From 467a44b0372d8268ce5bd90e58bde7db51c1d476 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: [PATCH 001/797] iio: adc: at91_adc: Repair broken platform_data support Trying to use the at91_adc driver while not using device tree is ending up in a kernel crash: Unable to handle kernel NULL pointer dereference at virtual address 00000004 [...] [] (at91_adc_probe) from [] (platform_drv_probe+0x18/0x48) [] (platform_drv_probe) from [] (driver_probe_device+0x100/0x218) [] (driver_probe_device) from [] (__driver_attach+0x8c/0x90) [] (__driver_attach) from [] (bus_for_each_dev+0x58/0x88) [] (bus_for_each_dev) from [] (bus_add_driver+0xd4/0x1d4) [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [] (driver_register) from [] (do_one_initcall+0xe8/0x14c) [] (do_one_initcall) from [] (kernel_init_freeable+0xec/0x1b4) [] (kernel_init_freeable) from [] (kernel_init+0x8/0xe4) [] (kernel_init) from [] (ret_from_fork+0x14/0x24) This is because the at91_adc_caps structure is mandatory but is not filled when using platform_data. Correct that by using an id_table. It ensues that the driver will not match "at91_adc" anymore but it was crashing anyway. Fixes: c46016665fff (iio: at91: ADC start-up time calculation changed since at91sam9x5) Cc: stable@vger.kernel.org # v3.13+ Signed-off-by: Alexandre Belloni Tested-by: Josh Wu Acked-by: Josh Wu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 5b1aa027c034..bbba014c9939 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -765,14 +765,17 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, if (!pdata) return -EINVAL; + st->caps = (struct at91_adc_caps *) + platform_get_device_id(pdev)->driver_data; + st->use_external = pdata->use_external_triggers; st->vref_mv = pdata->vref; st->channels_mask = pdata->channels_used; - st->num_channels = pdata->num_channels; + st->num_channels = st->caps->num_channels; st->startup_time = pdata->startup_time; st->trigger_number = pdata->trigger_number; st->trigger_list = pdata->trigger_list; - st->registers = pdata->registers; + st->registers = &st->caps->registers; return 0; } @@ -1101,7 +1104,6 @@ static int at91_adc_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_OF static struct at91_adc_caps at91sam9260_caps = { .calc_startup_ticks = calc_startup_ticks_9260, .num_channels = 4, @@ -1154,11 +1156,27 @@ static const struct of_device_id at91_adc_dt_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); -#endif + +static const struct platform_device_id at91_adc_ids[] = { + { + .name = "at91sam9260-adc", + .driver_data = (unsigned long)&at91sam9260_caps, + }, { + .name = "at91sam9g45-adc", + .driver_data = (unsigned long)&at91sam9g45_caps, + }, { + .name = "at91sam9x5-adc", + .driver_data = (unsigned long)&at91sam9x5_caps, + }, { + /* terminator */ + } +}; +MODULE_DEVICE_TABLE(platform, at91_adc_ids); static struct platform_driver at91_adc_driver = { .probe = at91_adc_probe, .remove = at91_adc_remove, + .id_table = at91_adc_ids, .driver = { .name = DRIVER_NAME, .of_match_table = of_match_ptr(at91_adc_dt_ids), -- GitLab From 41c897f8789d0d1039ed873ddcd0caabd5756e0f Mon Sep 17 00:00:00 2001 From: Beomho Seo Date: Wed, 3 Dec 2014 00:57:00 +0000 Subject: [PATCH 002/797] iio: cm32181: Fix read integration time function In read integration time function, assign 0 to val. Because, prevent return inaccurate value when call read integration time. Cc: Stable@vger.kernel.org Cc: Kevin Tsai Signed-off-by: Beomho Seo Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm32181.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index 47a6dbac2d0c..d976e6ce60db 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -221,6 +221,7 @@ static int cm32181_read_raw(struct iio_dev *indio_dev, *val = cm32181->calibscale; return IIO_VAL_INT; case IIO_CHAN_INFO_INT_TIME: + *val = 0; ret = cm32181_read_als_it(cm32181, val2); return ret; } -- GitLab From 142df13b7598d88de5b163464e74d2101912f479 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: [PATCH 003/797] ARM: at91: at91sam9g45: change at91_adc name We can't use "at91_adc" to refer to the at91_adc driver anymore as the name is used to match an id_table. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Jonathan Cameron --- arch/arm/mach-at91/at91sam9g45_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index cb36fa872d30..88554024eb2d 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -1203,7 +1203,7 @@ static struct resource adc_resources[] = { }; static struct platform_device at91_adc_device = { - .name = "at91_adc", + .name = "at91sam9g45-adc", .id = -1, .dev = { .platform_data = &adc_data, -- GitLab From 301841a634976c1cef4490cae577ffd0f26d0149 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Sat, 3 May 2014 16:57:00 +0100 Subject: [PATCH 004/797] ARM: at91: at91sam9260: change at91_adc name We can't use "at91_adc" to refer to the at91_adc driver anymore as the name is used to match an id_table. Signed-off-by: Alexandre Belloni Acked-by: Nicolas Ferre Signed-off-by: Jonathan Cameron --- arch/arm/mach-at91/at91sam9260_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index eda8d1679d40..0a0315920963 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -1292,7 +1292,7 @@ static struct resource adc_resources[] = { }; static struct platform_device at91_adc_device = { - .name = "at91_adc", + .name = "at91sam9260-adc", .id = -1, .dev = { .platform_data = &adc_data, -- GitLab From 8f32b6ba56ef8c8434635b9f08ff6a23510960a5 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 3 Mar 2014 18:07:00 +0000 Subject: [PATCH 005/797] iio: adc: at91_adc: correct default shtim value When sample_hold_time is zero (this is the case when DT is not used or if atmel,adc-sample-hold-time is omitted), then the calculated shtim is large. Make that 0, which is the default for that register and the ADC will then use a sane value of 2/ADCCLK or 1/ADCCLK depending on the version. Signed-off-by: Alexandre Belloni Acked-by: Josh Wu Signed-off-by: Jonathan Cameron --- drivers/iio/adc/at91_adc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index bbba014c9939..89777ed9abd8 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1007,8 +1007,11 @@ static int at91_adc_probe(struct platform_device *pdev) * the best converted final value between two channels selection * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock */ - shtim = round_up((st->sample_hold_time * adc_clk_khz / - 1000) - 1, 1); + if (st->sample_hold_time > 0) + shtim = round_up((st->sample_hold_time * adc_clk_khz / 1000) + - 1, 1); + else + shtim = 0; reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask; reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask; -- GitLab From 6b9da2e77249bd62bb0902319cfa22398f32c538 Mon Sep 17 00:00:00 2001 From: Jimmy Li Date: Sat, 22 Mar 2014 05:58:00 +0000 Subject: [PATCH 006/797] staging:iio:ad2s1200 fix a missing break Signed-off-by: Jimmy Li Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1200.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index 36eedd8a0ea9..e2b482045158 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c @@ -70,6 +70,7 @@ static int ad2s1200_read_raw(struct iio_dev *indio_dev, vel = (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); vel = (vel << 4) >> 4; *val = vel; + break; default: mutex_unlock(&st->lock); return -EINVAL; -- GitLab From 2076a20fc1a06f7b0333c62a2bb4eeeac7ed1bcb Mon Sep 17 00:00:00 2001 From: Alec Berg Date: Wed, 19 Mar 2014 18:50:00 +0000 Subject: [PATCH 007/797] iio: querying buffer scan_mask should return 0/1 Ensure that querying the IIO buffer scan_mask returns a value of 0 or 1. Currently querying the scan mask has the value returned by test_bit(), which returns either true or false. For some architectures test_bit() may return -1 for true, which will appear to return an error when returning from iio_scan_mask_query(). Additionally, it's important for the sysfs interface to consistently return the same thing when querying the scan_mask. Signed-off-by: Alec Berg Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index c67d83bdc8f0..fe25042f056a 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -165,7 +165,8 @@ static ssize_t iio_scan_el_show(struct device *dev, int ret; struct iio_dev *indio_dev = dev_to_iio_dev(dev); - ret = test_bit(to_iio_dev_attr(attr)->address, + /* Ensure ret is 0 or 1. */ + ret = !!test_bit(to_iio_dev_attr(attr)->address, indio_dev->buffer->scan_mask); return sprintf(buf, "%d\n", ret); @@ -866,7 +867,8 @@ int iio_scan_mask_query(struct iio_dev *indio_dev, if (!buffer->scan_mask) return 0; - return test_bit(bit, buffer->scan_mask); + /* Ensure return value is 0 or 1. */ + return !!test_bit(bit, buffer->scan_mask); }; EXPORT_SYMBOL_GPL(iio_scan_mask_query); -- GitLab From d0a588a57c2b0748df8307a0865a1bbbf1624c53 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 18 Mar 2014 08:13:00 +0000 Subject: [PATCH 008/797] iio: cm36651: Fix i2c client leak and possible NULL pointer dereference During probe the driver allocates dummy I2C devices (i2c_new_dummy()) but they aren't unregistered during driver remove or probe failure. Additionally driver does not check the return value of i2c_new_dummy(). In case of error (i2c_new_device(): memory allocation failure or I2C address cannot be used) this function returns NULL which is later dereferenced by i2c_smbus_{read,write}_data() functions. Fix issues by properly checking for i2c_new_dummy() return value and unregistering I2C devices on driver remove or probe failure. Signed-off-by: Krzysztof Kozlowski Acked-by: Beomho Seo Cc: stable@vger.kernel.org Signed-off-by: Jonathan Cameron --- drivers/iio/light/cm36651.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/iio/light/cm36651.c b/drivers/iio/light/cm36651.c index a45e07492db3..39fc67e82138 100644 --- a/drivers/iio/light/cm36651.c +++ b/drivers/iio/light/cm36651.c @@ -652,7 +652,19 @@ static int cm36651_probe(struct i2c_client *client, cm36651->client = client; cm36651->ps_client = i2c_new_dummy(client->adapter, CM36651_I2C_ADDR_PS); + if (!cm36651->ps_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_disable_reg; + } + cm36651->ara_client = i2c_new_dummy(client->adapter, CM36651_ARA); + if (!cm36651->ara_client) { + dev_err(&client->dev, "%s: new i2c device failed\n", __func__); + ret = -ENODEV; + goto error_i2c_unregister_ps; + } + mutex_init(&cm36651->lock); indio_dev->dev.parent = &client->dev; indio_dev->channels = cm36651_channels; @@ -664,7 +676,7 @@ static int cm36651_probe(struct i2c_client *client, ret = cm36651_setup_reg(cm36651); if (ret) { dev_err(&client->dev, "%s: register setup failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = request_threaded_irq(client->irq, NULL, cm36651_irq_handler, @@ -672,7 +684,7 @@ static int cm36651_probe(struct i2c_client *client, "cm36651", indio_dev); if (ret) { dev_err(&client->dev, "%s: request irq failed\n", __func__); - goto error_disable_reg; + goto error_i2c_unregister_ara; } ret = iio_device_register(indio_dev); @@ -685,6 +697,10 @@ static int cm36651_probe(struct i2c_client *client, error_free_irq: free_irq(client->irq, indio_dev); +error_i2c_unregister_ara: + i2c_unregister_device(cm36651->ara_client); +error_i2c_unregister_ps: + i2c_unregister_device(cm36651->ps_client); error_disable_reg: regulator_disable(cm36651->vled_reg); return ret; @@ -698,6 +714,8 @@ static int cm36651_remove(struct i2c_client *client) iio_device_unregister(indio_dev); regulator_disable(cm36651->vled_reg); free_irq(client->irq, indio_dev); + i2c_unregister_device(cm36651->ps_client); + i2c_unregister_device(cm36651->ara_client); return 0; } -- GitLab From e036f71e8ce310dc58b1351c3eb967b892f4641c Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 17 Mar 2014 16:43:00 +0000 Subject: [PATCH 009/797] iio: adc: mxs-lradc: fix warning when buidling on avr32 This fixes: drivers/staging/iio/adc/mxs-lradc.c: In function 'mxs_lradc_probe': drivers/staging/iio/adc/mxs-lradc.c:1558: warning: comparison of distinct pointer types lacks a cast drivers/staging/iio/adc/mxs-lradc.c:1558: warning: right shift count >= width of type drivers/staging/iio/adc/mxs-lradc.c:1558: warning: passing argument 1 of '__div64_32' from incompatible pointer type When building on avr32. Reported-by: Fengguang Wu Signed-off-by: Alexandre Belloni 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 514844efac75..53b3f963a7e3 100644 --- a/drivers/staging/iio/adc/mxs-lradc.c +++ b/drivers/staging/iio/adc/mxs-lradc.c @@ -1527,7 +1527,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) struct resource *iores; int ret = 0, touch_ret; int i, s; - unsigned int scale_uv; + uint64_t scale_uv; /* Allocate the IIO device. */ iio = devm_iio_device_alloc(dev, sizeof(*lradc)); -- GitLab From 95f75476b9a8841c7070301305fbcd437d07c40c Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 1 Apr 2014 09:29:15 -0400 Subject: [PATCH 010/797] tools/liblockdep: Ignore asmlinkage and visible Commit 63f9a7fde7 "asmlinkage: Make lockdep_sys_exit asmlinkage" has added asmlinkage annotation to lockdep_sys_exit, which broke build of liblockdep. Since we don't need asmlinkage in liblockep, just ignore it. Reported-by: Eunbong Song Reported-by: Robin Hack Signed-off-by: Sasha Levin --- tools/lib/lockdep/uinclude/linux/lockdep.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h index d0f5d6e50214..c1552c28507e 100644 --- a/tools/lib/lockdep/uinclude/linux/lockdep.h +++ b/tools/lib/lockdep/uinclude/linux/lockdep.h @@ -10,6 +10,9 @@ #define MAX_LOCK_DEPTH 2000UL +#define asmlinkage +#define __visible + #include "../../../include/linux/lockdep.h" struct task_struct { -- GitLab From be227b45fb228adff4371b8de9e3989904209ff4 Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Tue, 1 Apr 2014 11:42:18 -0400 Subject: [PATCH 011/797] tools/liblockdep: Add proper versioning to the shared obj Add proper versioning to the shared obj so that distros would be able to ship this lib without having to worry about versioning. Suggested-by: Josh Boyer Signed-off-by: Sasha Levin --- tools/lib/lockdep/Makefile | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile index 07b0b7542511..cb09d3ff8f58 100644 --- a/tools/lib/lockdep/Makefile +++ b/tools/lib/lockdep/Makefile @@ -1,13 +1,8 @@ -# liblockdep version -LL_VERSION = 0 -LL_PATCHLEVEL = 0 -LL_EXTRAVERSION = 1 - # file format version FILE_VERSION = 1 MAKEFLAGS += --no-print-directory - +LIBLOCKDEP_VERSION=$(shell make -sC ../../.. kernelversion) # Makefiles suck: This macro sets a default value of $(2) for the # variable named by $(1), unless the variable has been set by @@ -98,7 +93,7 @@ export prefix libdir bindir src obj libdir_SQ = $(subst ','\'',$(libdir)) bindir_SQ = $(subst ','\'',$(bindir)) -LIB_FILE = liblockdep.a liblockdep.so +LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION) BIN_FILE = lockdep CONFIG_INCLUDES = @@ -110,8 +105,6 @@ N = export Q VERBOSE -LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION) - INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include $(CONFIG_INCLUDES) # Set compile option CFLAGS if not set elsewhere @@ -146,7 +139,7 @@ do_app_build = \ do_compile_shared_library = \ ($(print_shared_lib_compile) \ - $(CC) --shared $^ -o $@ -lpthread -ldl) + $(CC) --shared $^ -o $@ -lpthread -ldl -Wl,-soname='"$@"';$(shell ln -s $@ liblockdep.so)) do_build_static_lib = \ ($(print_static_lib_build) \ @@ -177,7 +170,7 @@ all: all_cmd all_cmd: $(CMD_TARGETS) -liblockdep.so: $(PEVENT_LIB_OBJS) +liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS) $(Q)$(do_compile_shared_library) liblockdep.a: $(PEVENT_LIB_OBJS) -- GitLab From e69af4657e7764d03ad555f0b583d9c4217bcefa Mon Sep 17 00:00:00 2001 From: Vince Weaver Date: Wed, 2 Apr 2014 00:49:55 -0400 Subject: [PATCH 012/797] perf/x86: Enable DRAM RAPL support on Intel Haswell It turns out all Haswell processors (including the Desktop variant) support RAPL DRAM readings in addition to package, pp0, and pp1. I've confirmed RAPL DRAM readings on my model 60 Haswell desktop. See the 4th-gen-core-family-desktop-vol-2-datasheet.pdf available from the Intel website for confirmation. Signed-off-by: Vince Weaver Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Stephane Eranian Link: http://lkml.kernel.org/r/alpine.DEB.2.10.1404020045290.17889@vincent-weaver-1.um.maine.edu Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_rapl.c | 33 +++++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 5ad35ad94d0f..3cec947e3b98 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c @@ -59,7 +59,7 @@ #define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */ #define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */ #define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */ -#define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */ +#define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */ #define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */ /* Clients have PP0, PKG */ @@ -72,6 +72,12 @@ 1<config * any other bit is reserved @@ -425,6 +431,24 @@ static struct attribute *rapl_events_cln_attr[] = { NULL, }; +static struct attribute *rapl_events_hsw_attr[] = { + EVENT_PTR(rapl_cores), + EVENT_PTR(rapl_pkg), + EVENT_PTR(rapl_gpu), + EVENT_PTR(rapl_ram), + + EVENT_PTR(rapl_cores_unit), + EVENT_PTR(rapl_pkg_unit), + EVENT_PTR(rapl_gpu_unit), + EVENT_PTR(rapl_ram_unit), + + EVENT_PTR(rapl_cores_scale), + EVENT_PTR(rapl_pkg_scale), + EVENT_PTR(rapl_gpu_scale), + EVENT_PTR(rapl_ram_scale), + NULL, +}; + static struct attribute_group rapl_pmu_events_group = { .name = "events", .attrs = NULL, /* patched at runtime */ @@ -631,11 +655,14 @@ static int __init rapl_pmu_init(void) switch (boot_cpu_data.x86_model) { case 42: /* Sandy Bridge */ case 58: /* Ivy Bridge */ - case 60: /* Haswell */ - case 69: /* Haswell-Celeron */ rapl_cntr_mask = RAPL_IDX_CLN; rapl_pmu_events_group.attrs = rapl_events_cln_attr; break; + case 60: /* Haswell */ + case 69: /* Haswell-Celeron */ + rapl_cntr_mask = RAPL_IDX_HSW; + rapl_pmu_events_group.attrs = rapl_events_hsw_attr; + break; case 45: /* Sandy Bridge-EP */ case 62: /* IvyTown */ rapl_cntr_mask = RAPL_IDX_SRV; -- GitLab From 74c03eb63061c834893e7ebf8d298573bdccfd08 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Apr 2014 12:41:59 -0400 Subject: [PATCH 013/797] libata: make AHCI_XGENE depend on PHY_XGENE AHCI_XGENE is only applicable on ARM64 but it can also be enabled for compile testing; however, AHCI_XGENE selects PHY_XGENE which has other arch specific dependencies. This leads to the following warning when enabling it on other archs for compile testing. warning: (AHCI_XGENE) selects PHY_XGENE which has unmet direct dependencies (HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)) Selecting a config option which itself has dependencies can easily lead to broken configurations. For now, let's just make AHCI_XGENE depend on PHY_XGENE which has all the necessary dependencies already. Signed-off-by: Tejun Heo Reported-by: Linus Torvalds Cc: Loc Ho Cc: Bartlomiej Zolnierkiewicz Cc: Kishon Vijay Abraham I --- drivers/ata/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 20e03a7eb8b4..2e4da3bc47fc 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -134,8 +134,7 @@ config AHCI_SUNXI config AHCI_XGENE tristate "APM X-Gene 6.0Gbps AHCI SATA host controller support" - depends on ARM64 || COMPILE_TEST - select PHY_XGENE + depends on PHY_XGENE help This option enables support for APM X-Gene SoC SATA host controller. -- GitLab From d121f7d0cbb875abce249dbf7eb191f9bafe80b7 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Tue, 1 Apr 2014 20:42:37 -0400 Subject: [PATCH 014/797] libata: Update queued trim blacklist for M5x0 drives Crucial/Micron M500 drives properly support queued DSM TRIM starting with firmware MU05. Update the blacklist so we only disable queued trim for older firmware releases. Early M550 series drives suffer from the same issue as M500. A bugfix firmware is in the pipeline but not ready yet. Until then, blacklist queued trim for M550. Signed-off-by: Martin K. Petersen Cc: Chris Samuel Cc: Marc MERLIN Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org --- drivers/ata/libata-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 34406f7fdd7a..f2a6020366e1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4224,8 +4224,10 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { { "PIONEER DVD-RW DVR-216D", NULL, ATA_HORKAGE_NOSETXFER }, /* devices that don't properly handle queued TRIM commands */ - { "Micron_M500*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, - { "Crucial_CT???M500SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M500*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Crucial_CT???M500SSD*", "MU0[1-4]*", ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Micron_M550*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, + { "Crucial_CT???M550SSD*", NULL, ATA_HORKAGE_NO_NCQ_TRIM, }, /* * Some WD SATA-I drives spin up and down erratically when the link -- GitLab From 27aa64b9d1bd0d23fd692c91763a48309b694311 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 31 Mar 2014 19:51:14 +0200 Subject: [PATCH 015/797] pata_at91: fix ata_host_activate() failure handling Add missing clk_put() call to ata_host_activate() failure path. Sergei says, "Hm, I have once fixed that (see that *if* (!ret)) but looks like a later commit 477c87e90853d136b188c50c0e4a93d01cad872e (ARM: at91/pata: use gpio_is_valid to check the gpio) broke it again. :-( Would be good if the changelog did mention that..." Cc: Andrew Victor Cc: Nicolas Ferre Cc: Jean-Christophe Plagniol-Villard Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Tejun Heo Cc: stable@vger.kernel.org --- drivers/ata/pata_at91.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index e9c87274a781..8a66f23af4c4 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -407,12 +407,13 @@ static int pata_at91_probe(struct platform_device *pdev) host->private_data = info; - return ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, - gpio_is_valid(irq) ? ata_sff_interrupt : NULL, - irq_flags, &pata_at91_sht); + ret = ata_host_activate(host, gpio_is_valid(irq) ? gpio_to_irq(irq) : 0, + gpio_is_valid(irq) ? ata_sff_interrupt : NULL, + irq_flags, &pata_at91_sht); + if (ret) + goto err_put; - if (!ret) - return 0; + return 0; err_put: clk_put(info->mck); -- GitLab From 2cf8ee9044d744df57adf8485f205e8f2d4c6f02 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Wed, 2 Apr 2014 12:31:19 -0400 Subject: [PATCH 016/797] HID: sony: Fix cancel_work_sync mismerge Remove redundant cancel_work_sync() call caused by mismerge. Signed-off-by: Frank Praznik Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 69204afea7a4..908de2789219 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -1721,8 +1721,6 @@ static void sony_remove(struct hid_device *hdev) if (sc->quirks & SONY_LED_SUPPORT) sony_leds_remove(hdev); - if (sc->worker_initialized) - cancel_work_sync(&sc->state_worker); if (sc->quirks & SONY_BATTERY_SUPPORT) { hid_hw_close(hdev); sony_battery_remove(sc); -- GitLab From 496252f787560df18a65fdc74dc3180f7cd2c723 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 14 Feb 2014 14:18:56 -0600 Subject: [PATCH 017/797] parisc: Replace __get_cpu_var uses for address calculation Convert to the use of this_cpu_ptr(). Cc: "James E.J. Bottomley" Cc: Helge Deller Cc: linux-parisc@vger.kernel.org Signed-off-by: Christoph Lameter Signed-off-by: Helge Deller --- arch/parisc/lib/memcpy.c | 2 +- arch/parisc/mm/fault.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index 413dc1769299..b2b441b32341 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -470,7 +470,7 @@ static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len) return 0; /* if a load or store fault occured we can get the faulty addr */ - d = &__get_cpu_var(exception_data); + d = this_cpu_ptr(&exception_data); fault_addr = d->fault_addr; /* error in load or store? */ diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 9d08c71a967e..747550762f3c 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -151,7 +151,7 @@ int fixup_exception(struct pt_regs *regs) fix = search_exception_tables(regs->iaoq[0]); if (fix) { struct exception_data *d; - d = &__get_cpu_var(exception_data); + d = this_cpu_ptr(&exception_data); d->fault_ip = regs->iaoq[0]; d->fault_space = regs->isr; d->fault_addr = regs->ior; -- GitLab From 378ed3ccd2a0404d031e771b65aa3af221ea8aea Mon Sep 17 00:00:00 2001 From: Andy Lutomirski Date: Thu, 3 Apr 2014 10:53:43 -0700 Subject: [PATCH 018/797] x86, vdso: Make the vdso linker script compatible with Gold Gold can't parse the script due to: https://sourceware.org/bugzilla/show_bug.cgi?id=16804 With a workaround in place for that issue, Gold 2.23 crashes due to: https://sourceware.org/bugzilla/show_bug.cgi?id=15355 This works around the former bug and avoids the second by removing the unnecessary vvar and hpet sections and segments. The vdso and hpet symbols are still there, and nothing needed the sections or segments. Reported-by: Markus Trippelsdorf Signed-off-by: Andy Lutomirski Link: http://lkml.kernel.org/r/243fa205098d112ec759c9b1b26785c09f399833.1396547532.git.luto@amacapital.net Signed-off-by: H. Peter Anvin --- arch/x86/vdso/vdso-layout.lds.S | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/arch/x86/vdso/vdso-layout.lds.S b/arch/x86/vdso/vdso-layout.lds.S index 2e263f367b13..9df017ab2285 100644 --- a/arch/x86/vdso/vdso-layout.lds.S +++ b/arch/x86/vdso/vdso-layout.lds.S @@ -9,12 +9,9 @@ SECTIONS #ifdef BUILD_VDSO32 #include - .hpet_sect : { - hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE); - } :text :hpet_sect + hpet_page = . - VDSO_OFFSET(VDSO_HPET_PAGE); - .vvar_sect : { - vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE); + vvar = . - VDSO_OFFSET(VDSO_VVAR_PAGE); /* Place all vvars at the offsets in asm/vvar.h. */ #define EMIT_VVAR(name, offset) vvar_ ## name = vvar + offset; @@ -22,7 +19,6 @@ SECTIONS #include #undef __VVAR_KERNEL_LDS #undef EMIT_VVAR - } :text :vvar_sect #endif . = SIZEOF_HEADERS; @@ -61,7 +57,12 @@ SECTIONS */ . = ALIGN(0x100); - .text : { *(.text*) } :text =0x90909090 + .text : { *(.text*) } :text =0x90909090, + + /* + * The comma above works around a bug in gold: + * https://sourceware.org/bugzilla/show_bug.cgi?id=16804 + */ /DISCARD/ : { *(.discard) @@ -84,8 +85,4 @@ PHDRS dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ note PT_NOTE FLAGS(4); /* PF_R */ eh_frame_hdr PT_GNU_EH_FRAME; -#ifdef BUILD_VDSO32 - vvar_sect PT_NULL FLAGS(4); /* PF_R */ - hpet_sect PT_NULL FLAGS(4); /* PF_R */ -#endif } -- GitLab From 30f58877bfdaa562d329ec870f948b4d03e1ab03 Mon Sep 17 00:00:00 2001 From: Stephen Chandler Paul Date: Thu, 3 Apr 2014 16:27:55 -0400 Subject: [PATCH 019/797] HID: sensor-hub: add sensor hub quirk for ThinkPad Helix Just like some of the other laptops/tablets on the market with ultrabook sensors, the ThinkPad Helix's sensor hub requires a special quirk in order for it to power on properly. Without it the sensors are detected by the kernel and set up as usual, but they won't output any data. This will also fix the sensors on any other laptops with the same model of sensor hub. Signed-off-by: Stephen Chandler Paul Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 ++- drivers/hid/hid-sensor-hub.c | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index bd221263c739..3312f1b568ef 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -455,7 +455,8 @@ #define USB_VENDOR_ID_INTEL_0 0x8086 #define USB_VENDOR_ID_INTEL_1 0x8087 -#define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa +#define USB_DEVICE_ID_INTEL_HID_SENSOR_0 0x09fa +#define USB_DEVICE_ID_INTEL_HID_SENSOR_1 0x0a04 #define USB_VENDOR_ID_STM_0 0x0483 #define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1 diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 5182031f7b52..af8244b1c1f4 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -697,10 +697,13 @@ static void sensor_hub_remove(struct hid_device *hdev) static const struct hid_device_id sensor_hub_devices[] = { { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0, - USB_DEVICE_ID_INTEL_HID_SENSOR), + USB_DEVICE_ID_INTEL_HID_SENSOR_0), .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, - USB_DEVICE_ID_INTEL_HID_SENSOR), + USB_DEVICE_ID_INTEL_HID_SENSOR_0), + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1, + USB_DEVICE_ID_INTEL_HID_SENSOR_1), .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, USB_DEVICE_ID_STM_HID_SENSOR), -- GitLab From 5678de3f15010b9022ee45673f33bcfc71d47b60 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 28 Mar 2014 20:41:50 +0100 Subject: [PATCH 020/797] KVM: ioapic: fix assignment of ioapic->rtc_status.pending_eoi (CVE-2014-0155) QE reported that they got the BUG_ON in ioapic_service to trigger. I cannot reproduce it, but there are two reasons why this could happen. The less likely but also easiest one, is when kvm_irq_delivery_to_apic does not deliver to any APIC and returns -1. Because irqe.shorthand == 0, the kvm_for_each_vcpu loop in that function is never reached. However, you can target the similar loop in kvm_irq_delivery_to_apic_fast; just program a zero logical destination address into the IOAPIC, or an out-of-range physical destination address. Signed-off-by: Paolo Bonzini --- virt/kvm/ioapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index d4b601547f1f..d98d107efb05 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -356,7 +356,7 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) BUG_ON(ioapic->rtc_status.pending_eoi != 0); ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, ioapic->rtc_status.dest_map); - ioapic->rtc_status.pending_eoi = ret; + ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret); } else ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL); -- GitLab From 4009b2499eee26c7f413073300d124a37765dfca Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 28 Mar 2014 20:41:51 +0100 Subject: [PATCH 021/797] KVM: ioapic: try to recover if pending_eoi goes out of range The RTC tracking code tracks the cardinality of rtc_status.dest_map into rtc_status.pending_eoi. It has some WARN_ONs that trigger if pending_eoi ever becomes negative; however, these do not do anything to recover, and it bad things will happen soon after they trigger. When the next RTC interrupt is triggered, rtc_check_coalesced() will return false, but ioapic_service will find pending_eoi != 0 and do a BUG_ON. To avoid this, should pending_eoi ever be nonzero, call kvm_rtc_eoi_tracking_restore_all to recompute a correct dest_map and pending_eoi. Signed-off-by: Paolo Bonzini --- virt/kvm/ioapic.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index d98d107efb05..2458a1dc2ba9 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c @@ -97,6 +97,14 @@ static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) bitmap_zero(ioapic->rtc_status.dest_map, KVM_MAX_VCPUS); } +static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); + +static void rtc_status_pending_eoi_check_valid(struct kvm_ioapic *ioapic) +{ + if (WARN_ON(ioapic->rtc_status.pending_eoi < 0)) + kvm_rtc_eoi_tracking_restore_all(ioapic); +} + static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) { bool new_val, old_val; @@ -120,9 +128,8 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) } else { __clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map); ioapic->rtc_status.pending_eoi--; + rtc_status_pending_eoi_check_valid(ioapic); } - - WARN_ON(ioapic->rtc_status.pending_eoi < 0); } void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) @@ -149,10 +156,10 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic) static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu) { - if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) + if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) { --ioapic->rtc_status.pending_eoi; - - WARN_ON(ioapic->rtc_status.pending_eoi < 0); + rtc_status_pending_eoi_check_valid(ioapic); + } } static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic) @@ -353,6 +360,12 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) ioapic->irr &= ~(1 << irq); if (irq == RTC_GSI && line_status) { + /* + * pending_eoi cannot ever become negative (see + * rtc_status_pending_eoi_check_valid) and the caller + * ensures that it is only called if it is >= zero, namely + * if rtc_irq_check_coalesced returns false). + */ BUG_ON(ioapic->rtc_status.pending_eoi != 0); ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, ioapic->rtc_status.dest_map); -- GitLab From f3b0cbce01cd5c242b420d986b208d306bdc5083 Mon Sep 17 00:00:00 2001 From: Derya Date: Mon, 31 Mar 2014 13:27:09 -0400 Subject: [PATCH 022/797] Revert "HID: microsoft: Add ID's for Surface Type/Touch Cover 2" This reverts commit 117309c51dca42121f70cacec801511b76acf75c. The MS Surface Pro 2 has an USB composite device with 3 interfaces - interface 0 - sensor hub - interface 1 - wacom digitizer - interface 2 - the keyboard cover, if one is attached This USB composite device changes it product id dependent on if and which keyboard cover is attached. Adding the covers to hid_have_special_driver prevents loading the right hid drivers for the other two interfaces, all 3 get loaded with hid-microsoft. We don't even need hid-microsoft for the keyboards. We have to revert this to load the right hid modules for each interface. CC: stable@vger.kernel.org # kernel 3.14 only Signed-off-by: Derya Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 2 -- drivers/hid/hid-ids.h | 2 -- drivers/hid/hid-microsoft.c | 4 ---- 3 files changed, 8 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9e8064205bc7..3f488ff88e0c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1821,8 +1821,6 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2) }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3312f1b568ef..c8af7202c28d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -630,8 +630,6 @@ #define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 #define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730 #define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c -#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 -#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 #define USB_VENDOR_ID_MOJO 0x8282 #define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index 6fd58175a291..8ba17a946f2a 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -274,10 +274,6 @@ static const struct hid_device_id ms_devices[] = { .driver_data = MS_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500), .driver_data = MS_DUPLICATE_USAGES }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2), - .driver_data = 0 }, - { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2), - .driver_data = 0 }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), .driver_data = MS_PRESENTER }, -- GitLab From e24d0d399b2fce71b627043e900ef28283850482 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 31 Mar 2014 13:27:10 -0400 Subject: [PATCH 023/797] HID: core: do not scan constant input report The Microsoft Surface Type/Touch Cover 2 is a fancy device which advertised itself as a multitouch device but with constant input reports. This way, hid_scan_report() gives the group MULTITOUCH to it, but hid-multitouch can not handle it due to the constant collection ignored by hid-input. To prevent such crap in the future, and while we do not fix this particular device, make the scan_report coherent with hid-input.c, and ignore constant input reports. CC: stable@vger.kernel.org # 3.12+ Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 3f488ff88e0c..10a2c0866459 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -718,6 +718,9 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) case HID_MAIN_ITEM_TAG_END_COLLECTION: break; case HID_MAIN_ITEM_TAG_INPUT: + /* ignore constant inputs, they will be ignored by hid-input */ + if (data & HID_MAIN_ITEM_CONSTANT) + break; for (i = 0; i < parser->local.usage_index; i++) hid_scan_input_usage(parser, parser->local.usage[i]); break; -- GitLab From 666525dfbdca09bbd4848ac711e4a4dbd6921325 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Mon, 7 Apr 2014 10:18:56 -0400 Subject: [PATCH 024/797] ext4: fix 64-bit number truncation warning '0x7FDEADBEEF' will be truncated to 32-bit number under unicore32. Need append 'ULL' for it. The related warning (with allmodconfig under unicore32): CC [M] fs/ext4/extents_status.o fs/ext4/extents_status.c: In function "__es_remove_extent": fs/ext4/extents_status.c:813: warning: integer constant is too large for "long" type Signed-off-by: Chen Gang Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents_status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index 0a014a7194b2..0ebc21204b51 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c @@ -810,7 +810,7 @@ static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, newes.es_lblk = end + 1; newes.es_len = len2; - block = 0x7FDEADBEEF; + block = 0x7FDEADBEEFULL; if (ext4_es_is_written(&orig_es) || ext4_es_is_unwritten(&orig_es)) block = ext4_es_pblock(&orig_es) + -- GitLab From 4adb6ab3e0fa71363a5ef229544b2d17de6600d7 Mon Sep 17 00:00:00 2001 From: Kazuya Mio Date: Mon, 7 Apr 2014 10:53:28 -0400 Subject: [PATCH 025/797] ext4: FIBMAP ioctl causes BUG_ON due to handle EXT_MAX_BLOCKS When we try to get 2^32-1 block of the file which has the extent (ee_block=2^32-2, ee_len=1) with FIBMAP ioctl, it causes BUG_ON in ext4_ext_put_gap_in_cache(). To avoid the problem, ext4_map_blocks() needs to check the file logical block number. ext4_ext_put_gap_in_cache() called via ext4_map_blocks() cannot handle 2^32-1 because the maximum file logical block number is 2^32-2. Note that ext4_ind_map_blocks() returns -EIO when the block number is invalid. So ext4_map_blocks() should also return the same errno. Signed-off-by: Kazuya Mio Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5b0d2c7d5408..93f16c5e8a8e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -522,6 +522,10 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, if (unlikely(map->m_len > INT_MAX)) map->m_len = INT_MAX; + /* We can handle the block number less than EXT_MAX_BLOCKS */ + if (unlikely(map->m_lblk >= EXT_MAX_BLOCKS)) + return -EIO; + /* Lookup extent status tree firstly */ if (ext4_es_lookup_extent(inode, map->m_lblk, &es)) { ext4_es_lru_add(inode); -- GitLab From 007649375f6af242d5b1df2c15996949714303ba Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 7 Apr 2014 10:54:20 -0400 Subject: [PATCH 026/797] ext4: initialize multi-block allocator before checking block descriptors With EXT4FS_DEBUG ext4_count_free_clusters() will call ext4_read_block_bitmap() without s_group_info initialized, so we need to initialize multi-block allocator before. And dependencies that must be solved, to allow this: - multi-block allocator needs in group descriptors - need to install s_op before initializing multi-block allocator, because in ext4_mb_init_backend() new inode is created. - initialize number of group desc blocks (s_gdb_count) otherwise number of clusters returned by ext4_free_clusters_after_init() is not correct. (see ext4_bg_num_gdb_nometa()) Here is the stack backtrace: (gdb) bt #0 ext4_get_group_info (group=0, sb=0xffff880079a10000) at ext4.h:2430 #1 ext4_validate_block_bitmap (sb=sb@entry=0xffff880079a10000, desc=desc@entry=0xffff880056510000, block_group=block_group@entry=0, bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:358 #2 0xffffffff81232202 in ext4_wait_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0, bh=bh@entry=0xffff88007bf2b2d8) at balloc.c:476 #3 0xffffffff81232eaf in ext4_read_block_bitmap (sb=sb@entry=0xffff880079a10000, block_group=block_group@entry=0) at balloc.c:489 #4 0xffffffff81232fc0 in ext4_count_free_clusters (sb=sb@entry=0xffff880079a10000) at balloc.c:665 #5 0xffffffff81259ffa in ext4_check_descriptors (first_not_zeroed=, sb=0xffff880079a10000) at super.c:2143 #6 ext4_fill_super (sb=sb@entry=0xffff880079a10000, data=, data@entry=0x0 , silent=silent@entry=0) at super.c:3851 ... Signed-off-by: Azat Khuzhin Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index f3c667091618..6f9e6fadac04 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -3869,19 +3869,38 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) goto failed_mount2; } } + + /* + * set up enough so that it can read an inode, + * and create new inode for buddy allocator + */ + sbi->s_gdb_count = db_count; + if (!test_opt(sb, NOLOAD) && + EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) + sb->s_op = &ext4_sops; + else + sb->s_op = &ext4_nojournal_sops; + + ext4_ext_init(sb); + err = ext4_mb_init(sb); + if (err) { + ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", + err); + goto failed_mount2; + } + if (!ext4_check_descriptors(sb, &first_not_zeroed)) { ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); - goto failed_mount2; + goto failed_mount2a; } if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) if (!ext4_fill_flex_info(sb)) { ext4_msg(sb, KERN_ERR, "unable to initialize " "flex_bg meta info!"); - goto failed_mount2; + goto failed_mount2a; } - sbi->s_gdb_count = db_count; get_random_bytes(&sbi->s_next_generation, sizeof(u32)); spin_lock_init(&sbi->s_next_gen_lock); @@ -3916,14 +3935,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_stripe = ext4_get_stripe_size(sbi); sbi->s_extent_max_zeroout_kb = 32; - /* - * set up enough so that it can read an inode - */ - if (!test_opt(sb, NOLOAD) && - EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) - sb->s_op = &ext4_sops; - else - sb->s_op = &ext4_nojournal_sops; sb->s_export_op = &ext4_export_ops; sb->s_xattr = ext4_xattr_handlers; #ifdef CONFIG_QUOTA @@ -4113,21 +4124,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) if (err) { ext4_msg(sb, KERN_ERR, "failed to reserve %llu clusters for " "reserved pool", ext4_calculate_resv_clusters(sb)); - goto failed_mount4a; + goto failed_mount5; } err = ext4_setup_system_zone(sb); if (err) { ext4_msg(sb, KERN_ERR, "failed to initialize system " "zone (%d)", err); - goto failed_mount4a; - } - - ext4_ext_init(sb); - err = ext4_mb_init(sb); - if (err) { - ext4_msg(sb, KERN_ERR, "failed to initialize mballoc (%d)", - err); goto failed_mount5; } @@ -4204,11 +4207,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) failed_mount7: ext4_unregister_li_request(sb); failed_mount6: - ext4_mb_release(sb); -failed_mount5: - ext4_ext_release(sb); ext4_release_system_zone(sb); -failed_mount4a: +failed_mount5: dput(sb->s_root); sb->s_root = NULL; failed_mount4: @@ -4232,11 +4232,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) percpu_counter_destroy(&sbi->s_extent_cache_cnt); if (sbi->s_mmp_tsk) kthread_stop(sbi->s_mmp_tsk); +failed_mount2a: + ext4_mb_release(sb); failed_mount2: for (i = 0; i < db_count; i++) brelse(sbi->s_group_desc[i]); ext4_kvfree(sbi->s_group_desc); failed_mount: + ext4_ext_release(sb); if (sbi->s_chksum_driver) crypto_free_shash(sbi->s_chksum_driver); if (sbi->s_proc) { -- GitLab From 9503c67c93ed0b95ba62d12d1fd09da6245dbdd6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 7 Apr 2014 10:54:20 -0400 Subject: [PATCH 027/797] ext4: note the error in ext4_end_bio() ext4_end_bio() currently throws away the error that it receives. Chances are this is part of a spate of errors, one of which will end up getting the error returned to userspace somehow, but we shouldn't take that risk. Also print out the errno to aid in debug. Signed-off-by: Matthew Wilcox Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara Cc: stable@vger.kernel.org --- fs/ext4/page-io.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index ab95508e3d40..c18d95b50540 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -308,13 +308,14 @@ static void ext4_end_bio(struct bio *bio, int error) if (error) { struct inode *inode = io_end->inode; - ext4_warning(inode->i_sb, "I/O error writing to inode %lu " + ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu " "(offset %llu size %ld starting block %llu)", - inode->i_ino, + error, inode->i_ino, (unsigned long long) io_end->offset, (long) io_end->size, (unsigned long long) bi_sector >> (inode->i_blkbits - 9)); + mapping_set_error(inode->i_mapping, error); } if (io_end->flag & EXT4_IO_END_UNWRITTEN) { -- GitLab From ec4cb1aa2b7bae18dd8164f2e9c7c51abcf61280 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 7 Apr 2014 10:54:21 -0400 Subject: [PATCH 028/797] ext4: fix jbd2 warning under heavy xattr load When heavily exercising xattr code the assertion that jbd2_journal_dirty_metadata() shouldn't return error was triggered: WARNING: at /srv/autobuild-ceph/gitbuilder.git/build/fs/jbd2/transaction.c:1237 jbd2_journal_dirty_metadata+0x1ba/0x260() CPU: 0 PID: 8877 Comm: ceph-osd Tainted: G W 3.10.0-ceph-00049-g68d04c9 #1 Hardware name: Dell Inc. PowerEdge R410/01V648, BIOS 1.6.3 02/07/2011 ffffffff81a1d3c8 ffff880214469928 ffffffff816311b0 ffff880214469968 ffffffff8103fae0 ffff880214469958 ffff880170a9dc30 ffff8802240fbe80 0000000000000000 ffff88020b366000 ffff8802256e7510 ffff880214469978 Call Trace: [] dump_stack+0x19/0x1b [] warn_slowpath_common+0x70/0xa0 [] warn_slowpath_null+0x1a/0x20 [] jbd2_journal_dirty_metadata+0x1ba/0x260 [] __ext4_handle_dirty_metadata+0xa3/0x140 [] ext4_xattr_release_block+0x103/0x1f0 [] ext4_xattr_block_set+0x1e0/0x910 [] ext4_xattr_set_handle+0x38b/0x4a0 [] ? trace_hardirqs_on+0xd/0x10 [] ext4_xattr_set+0xc2/0x140 [] ext4_xattr_user_set+0x47/0x50 [] generic_setxattr+0x6e/0x90 [] __vfs_setxattr_noperm+0x7b/0x1c0 [] vfs_setxattr+0xc4/0xd0 [] setxattr+0x13e/0x1e0 [] ? __sb_start_write+0xe7/0x1b0 [] ? mnt_want_write_file+0x28/0x60 [] ? fget_light+0x3c/0x130 [] ? mnt_want_write_file+0x28/0x60 [] ? __mnt_want_write+0x58/0x70 [] SyS_fsetxattr+0xbe/0x100 [] system_call_fastpath+0x16/0x1b The reason for the warning is that buffer_head passed into jbd2_journal_dirty_metadata() didn't have journal_head attached. This is caused by the following race of two ext4_xattr_release_block() calls: CPU1 CPU2 ext4_xattr_release_block() ext4_xattr_release_block() lock_buffer(bh); /* False */ if (BHDR(bh)->h_refcount == cpu_to_le32(1)) } else { le32_add_cpu(&BHDR(bh)->h_refcount, -1); unlock_buffer(bh); lock_buffer(bh); /* True */ if (BHDR(bh)->h_refcount == cpu_to_le32(1)) get_bh(bh); ext4_free_blocks() ... jbd2_journal_forget() jbd2_journal_unfile_buffer() -> JH is gone error = ext4_handle_dirty_xattr_block(handle, inode, bh); -> triggers the warning We fix the problem by moving ext4_handle_dirty_xattr_block() under the buffer lock. Sadly this cannot be done in nojournal mode as that function can call sync_dirty_buffer() which would deadlock. Luckily in nojournal mode the race is harmless (we only dirty already freed buffer) and thus for nojournal mode we leave the dirtying outside of the buffer lock. Reported-by: Sage Weil Signed-off-by: Jan Kara Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/xattr.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 1f5cf5880718..4eec399ec807 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -520,8 +520,8 @@ static void ext4_xattr_update_super_block(handle_t *handle, } /* - * Release the xattr block BH: If the reference count is > 1, decrement - * it; otherwise free the block. + * Release the xattr block BH: If the reference count is > 1, decrement it; + * otherwise free the block. */ static void ext4_xattr_release_block(handle_t *handle, struct inode *inode, @@ -542,16 +542,31 @@ ext4_xattr_release_block(handle_t *handle, struct inode *inode, if (ce) mb_cache_entry_free(ce); get_bh(bh); + unlock_buffer(bh); ext4_free_blocks(handle, inode, bh, 0, 1, EXT4_FREE_BLOCKS_METADATA | EXT4_FREE_BLOCKS_FORGET); - unlock_buffer(bh); } else { le32_add_cpu(&BHDR(bh)->h_refcount, -1); if (ce) mb_cache_entry_release(ce); + /* + * Beware of this ugliness: Releasing of xattr block references + * from different inodes can race and so we have to protect + * from a race where someone else frees the block (and releases + * its journal_head) before we are done dirtying the buffer. In + * nojournal mode this race is harmless and we actually cannot + * call ext4_handle_dirty_xattr_block() with locked buffer as + * that function can call sync_dirty_buffer() so for that case + * we handle the dirtying after unlocking the buffer. + */ + if (ext4_handle_valid(handle)) + error = ext4_handle_dirty_xattr_block(handle, inode, + bh); unlock_buffer(bh); - error = ext4_handle_dirty_xattr_block(handle, inode, bh); + if (!ext4_handle_valid(handle)) + error = ext4_handle_dirty_xattr_block(handle, inode, + bh); if (IS_SYNC(inode)) ext4_handle_sync(handle); dquot_free_block(inode, EXT4_C2B(EXT4_SB(inode->i_sb), 1)); -- GitLab From 0d606c08f44a09e3ca86d4af1a40aec61a6e9dde Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:45:58 +0100 Subject: [PATCH 029/797] ARM: Kirkwood: Fix Atmel vendor prefix The documented vendor prefix for Atmel is 'atmel' not 'at' as used in these .dts[i] files. The i2c framework actually ignores the prefix, so making this change does not cause compatibility issues. Signed-off-by: Andrew Lunn Link: https://lkml.kernel.org/r/1395492360-1865-4-git-send-email-andrew@lunn.ch Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood-laplug.dts | 2 +- arch/arm/boot/dts/kirkwood-ns2-common.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-laplug.dts b/arch/arm/boot/dts/kirkwood-laplug.dts index c9e82eff9bf2..6761ffa2c4ab 100644 --- a/arch/arm/boot/dts/kirkwood-laplug.dts +++ b/arch/arm/boot/dts/kirkwood-laplug.dts @@ -48,7 +48,7 @@ status = "okay"; eeprom@50 { - compatible = "at,24c04"; + compatible = "atmel,24c04"; pagesize = <16>; reg = <0x50>; }; diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 743152f31a81..843eb478b3e4 100644 --- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -50,7 +50,7 @@ status = "okay"; eeprom@50 { - compatible = "at,24c04"; + compatible = "atmel,24c04"; pagesize = <16>; reg = <0x50>; }; -- GitLab From dcdf9cfc4868878957d5c372f82b233143ec4320 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:46:00 +0100 Subject: [PATCH 030/797] ARM: Kirkwood: DT: Add missing vendor prefix Add vendor prefixes to compatible strings where they are missing. Both the I2C and MTD framework ignore the prefix, so adding them has no effect on backwards compatibility. Signed-off-by: Andrew Lunn Link: https://lkml.kernel.org/r/1395492360-1865-6-git-send-email-andrew@lunn.ch Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood-b3.dts | 2 +- arch/arm/boot/dts/kirkwood-cloudbox.dts | 2 +- arch/arm/boot/dts/kirkwood-dreamplug.dts | 2 +- arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts | 2 +- arch/arm/boot/dts/kirkwood-ns2-common.dtsi | 2 +- arch/arm/boot/dts/kirkwood-nsa310.dts | 2 +- arch/arm/boot/dts/kirkwood-nsa310a.dts | 2 +- arch/arm/boot/dts/kirkwood-openblocks_a6.dts | 2 +- arch/arm/boot/dts/kirkwood-openblocks_a7.dts | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/kirkwood-b3.dts b/arch/arm/boot/dts/kirkwood-b3.dts index 40791053106b..6becedebaa4e 100644 --- a/arch/arm/boot/dts/kirkwood-b3.dts +++ b/arch/arm/boot/dts/kirkwood-b3.dts @@ -75,7 +75,7 @@ m25p16@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "m25p16"; + compatible = "st,m25p16"; reg = <0>; spi-max-frequency = <40000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-cloudbox.dts b/arch/arm/boot/dts/kirkwood-cloudbox.dts index 0e06fd3cee4d..3b62aeeaa3a2 100644 --- a/arch/arm/boot/dts/kirkwood-cloudbox.dts +++ b/arch/arm/boot/dts/kirkwood-cloudbox.dts @@ -46,7 +46,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l4005a"; + compatible = "mxicy,mx25l4005a"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index ef3463e0ae19..28b3ee369778 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts @@ -43,7 +43,7 @@ m25p40@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l1606e"; + compatible = "mxicy,mx25l1606e"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts index dc86429756d7..25cbaaae142e 100644 --- a/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts +++ b/arch/arm/boot/dts/kirkwood-mv88f6281gtw-ge.dts @@ -56,7 +56,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l12805d"; + compatible = "mxicy,mx25l12805d"; reg = <0>; spi-max-frequency = <50000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi index 843eb478b3e4..e6e5ec4fe6b9 100644 --- a/arch/arm/boot/dts/kirkwood-ns2-common.dtsi +++ b/arch/arm/boot/dts/kirkwood-ns2-common.dtsi @@ -32,7 +32,7 @@ flash@0 { #address-cells = <1>; #size-cells = <1>; - compatible = "mx25l4005a"; + compatible = "mxicy,mx25l4005a"; reg = <0>; spi-max-frequency = <20000000>; mode = <0>; diff --git a/arch/arm/boot/dts/kirkwood-nsa310.dts b/arch/arm/boot/dts/kirkwood-nsa310.dts index 03fa24cf3344..0a07af9d8e58 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310.dts @@ -104,7 +104,7 @@ status = "okay"; adt7476: adt7476a@2e { - compatible = "adt7476"; + compatible = "adi,adt7476"; reg = <0x2e>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-nsa310a.dts b/arch/arm/boot/dts/kirkwood-nsa310a.dts index a5e779452867..27ca6a79c48a 100644 --- a/arch/arm/boot/dts/kirkwood-nsa310a.dts +++ b/arch/arm/boot/dts/kirkwood-nsa310a.dts @@ -94,7 +94,7 @@ status = "okay"; lm85: lm85@2e { - compatible = "lm85"; + compatible = "national,lm85"; reg = <0x2e>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts index b88da9392c32..0650beafc1de 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a6.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a6.dts @@ -40,7 +40,7 @@ pinctrl-names = "default"; s35390a: s35390a@30 { - compatible = "s35390a"; + compatible = "sii,s35390a"; reg = <0x30>; }; }; diff --git a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts index b2f7cae06839..38520a287514 100644 --- a/arch/arm/boot/dts/kirkwood-openblocks_a7.dts +++ b/arch/arm/boot/dts/kirkwood-openblocks_a7.dts @@ -52,7 +52,7 @@ pinctrl-names = "default"; s24c02: s24c02@50 { - compatible = "24c02"; + compatible = "atmel,24c02"; reg = <0x50>; }; }; -- GitLab From a6e03dd451c724f785277d8ecca5d1a0b886d892 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 26 Mar 2014 00:33:58 +0100 Subject: [PATCH 031/797] ARM: mvebu: ensure the mdio node has a clock reference on Armada 370/XP The mvmdio driver accesses some register of the Ethernet unit. It therefore takes a reference and enables a clock. However, on Armada 370/XP, no clock specification was given in the Device Tree, which leads the mvmdio driver to fail when being used as a module and loaded before the mvneta driver: it tries to access a register from a hardware unit that isn't clocked. Cc: stable@vger.kernel.org Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1395790439-21332-2-git-send-email-thomas.petazzoni@free-electrons.com Acked-by: Andrew Lunn Acked-by: Gregory CLEMENT Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-xp.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/armada-370-xp.dtsi b/arch/arm/boot/dts/armada-370-xp.dtsi index bbb40f62037d..bb77970c0b12 100644 --- a/arch/arm/boot/dts/armada-370-xp.dtsi +++ b/arch/arm/boot/dts/armada-370-xp.dtsi @@ -230,6 +230,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x72004 0x4>; + clocks = <&gateclk 4>; }; eth1: ethernet@74000 { -- GitLab From 33faf20b8ebe2770f2d7b52796f5f35eeb87ab6f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 26 Mar 2014 00:33:59 +0100 Subject: [PATCH 032/797] ARM: mvebu: ensure the mdio node has a clock reference on Armada 38x The mvmdio driver accesses some register of the Ethernet unit. It therefore takes a reference and enables a clock. However, on Armada 38x, no clock specification was given in the Device Tree, which leads the mvmdio driver to fail when being used as a module and loaded before the mvneta driver: it tries to access a register from a hardware unit that isn't clocked. Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1395790439-21332-3-git-send-email-thomas.petazzoni@free-electrons.com Acked-by: Andrew Lunn Acked-by: Gregory CLEMENT Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-38x.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index a064f59da02d..ca8813bb99ba 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -336,6 +336,7 @@ #size-cells = <0>; compatible = "marvell,orion-mdio"; reg = <0x72004 0x4>; + clocks = <&gateclk 4>; }; coredivclk: clock@e4250 { -- GitLab From b08eed0c4d7d70eae2f4f1ff518cc33643722a07 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Mon, 7 Apr 2014 20:16:52 +0100 Subject: [PATCH 033/797] ARM: shmobile: lager: correct renesas,gpios to renesas,groups in sd[02] pfc Fix probable typo of renesas,groups in the lager dt. The kernel has no renesas,gpios but this should match renesas,groups. Signed-off-by: Rob Taylor [ben.dooks@codethink.co.uk: fixup description] Signed-off-by: Ben Dooks Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 6e99eb2df076..d01048ab3e77 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -141,12 +141,12 @@ }; sdhi0_pins: sd0 { - renesas,gpios = "sdhi0_data4", "sdhi0_ctrl"; + renesas,groups = "sdhi0_data4", "sdhi0_ctrl"; renesas,function = "sdhi0"; }; sdhi2_pins: sd2 { - renesas,gpios = "sdhi2_data4", "sdhi2_ctrl"; + renesas,groups = "sdhi2_data4", "sdhi2_ctrl"; renesas,function = "sdhi2"; }; -- GitLab From 8142b227ef43119e19acf6122a9eea1a82492645 Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Mon, 31 Mar 2014 18:14:18 +0400 Subject: [PATCH 034/797] netfilter: nf_conntrack: flush net_gre->keymap_list only from gre helper nf_ct_gre_keymap_flush() removes a nf_ct_gre_keymap object from net_gre->keymap_list and frees the object. But it doesn't clean a reference on this object from ct_pptp_info->keymap[dir]. Then nf_ct_gre_keymap_destroy() may release the same object again. So nf_ct_gre_keymap_flush() can be called only when we are sure that when nf_ct_gre_keymap_destroy will not be called. nf_ct_gre_keymap is created by nf_ct_gre_keymap_add() and the right way to destroy it is to call nf_ct_gre_keymap_destroy(). This patch marks nf_ct_gre_keymap_flush() as static, so this patch can break compilation of third party modules, which use nf_ct_gre_keymap_flush. I'm not sure this is the right way to deprecate this function. [ 226.540793] general protection fault: 0000 [#1] SMP [ 226.541750] Modules linked in: nf_nat_pptp nf_nat_proto_gre nf_conntrack_pptp nf_conntrack_proto_gre ip_gre ip_tunnel gre ppp_deflate bsd_comp ppp_async crc_ccitt ppp_generic slhc xt_nat iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack veth tun bridge stp llc ppdev microcode joydev pcspkr serio_raw virtio_console virtio_balloon floppy parport_pc parport pvpanic i2c_piix4 virtio_net drm_kms_helper ttm ata_generic virtio_pci virtio_ring virtio drm i2c_core pata_acpi [last unloaded: ip_tunnel] [ 226.541776] CPU: 0 PID: 49 Comm: kworker/u4:2 Not tainted 3.14.0-rc8+ #101 [ 226.541776] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 226.541776] Workqueue: netns cleanup_net [ 226.541776] task: ffff8800371e0000 ti: ffff88003730c000 task.ti: ffff88003730c000 [ 226.541776] RIP: 0010:[] [] __list_del_entry+0x29/0xd0 [ 226.541776] RSP: 0018:ffff88003730dbd0 EFLAGS: 00010a83 [ 226.541776] RAX: 6b6b6b6b6b6b6b6b RBX: ffff8800374e6c40 RCX: dead000000200200 [ 226.541776] RDX: 6b6b6b6b6b6b6b6b RSI: ffff8800371e07d0 RDI: ffff8800374e6c40 [ 226.541776] RBP: ffff88003730dbd0 R08: 0000000000000000 R09: 0000000000000000 [ 226.541776] R10: 0000000000000001 R11: ffff88003730d92e R12: 0000000000000002 [ 226.541776] R13: ffff88007a4c42d0 R14: ffff88007aef0000 R15: ffff880036cf0018 [ 226.541776] FS: 0000000000000000(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000 [ 226.541776] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 226.541776] CR2: 00007f07f643f7d0 CR3: 0000000036fd2000 CR4: 00000000000006f0 [ 226.541776] Stack: [ 226.541776] ffff88003730dbe8 ffffffff81389c5d ffff8800374ffbe4 ffff88003730dc28 [ 226.541776] ffffffffa0162a43 ffffffffa01627c5 ffff88007a4c42d0 ffff88007aef0000 [ 226.541776] ffffffffa01651c0 ffff88007a4c45e0 ffff88007aef0000 ffff88003730dc40 [ 226.541776] Call Trace: [ 226.541776] [] list_del+0xd/0x30 [ 226.541776] [] nf_ct_gre_keymap_destroy+0x283/0x2d0 [nf_conntrack_proto_gre] [ 226.541776] [] ? nf_ct_gre_keymap_destroy+0x5/0x2d0 [nf_conntrack_proto_gre] [ 226.541776] [] gre_destroy+0x27/0x70 [nf_conntrack_proto_gre] [ 226.541776] [] destroy_conntrack+0x83/0x200 [nf_conntrack] [ 226.541776] [] ? destroy_conntrack+0x27/0x200 [nf_conntrack] [ 226.541776] [] ? nf_conntrack_hash_check_insert+0x2e0/0x2e0 [nf_conntrack] [ 226.541776] [] nf_conntrack_destroy+0x72/0x180 [ 226.541776] [] ? nf_conntrack_destroy+0x5/0x180 [ 226.541776] [] ? kill_l3proto+0x20/0x20 [nf_conntrack] [ 226.541776] [] nf_ct_iterate_cleanup+0x14e/0x170 [nf_conntrack] [ 226.541776] [] nf_ct_l4proto_pernet_unregister+0x5b/0x90 [nf_conntrack] [ 226.541776] [] proto_gre_net_exit+0x19/0x30 [nf_conntrack_proto_gre] [ 226.541776] [] ops_exit_list.isra.1+0x39/0x60 [ 226.541776] [] cleanup_net+0x100/0x1d0 [ 226.541776] [] process_one_work+0x1ea/0x4f0 [ 226.541776] [] ? process_one_work+0x188/0x4f0 [ 226.541776] [] worker_thread+0x11b/0x3a0 [ 226.541776] [] ? process_one_work+0x4f0/0x4f0 [ 226.541776] [] kthread+0xed/0x110 [ 226.541776] [] ? _raw_spin_unlock_irq+0x2c/0x40 [ 226.541776] [] ? kthread_create_on_node+0x200/0x200 [ 226.541776] [] ret_from_fork+0x7c/0xb0 [ 226.541776] [] ? kthread_create_on_node+0x200/0x200 [ 226.541776] Code: 00 00 55 48 8b 17 48 b9 00 01 10 00 00 00 ad de 48 8b 47 08 48 89 e5 48 39 ca 74 29 48 b9 00 02 20 00 00 00 ad de 48 39 c8 74 7a <4c> 8b 00 4c 39 c7 75 53 4c 8b 42 08 4c 39 c7 75 2b 48 89 42 08 [ 226.541776] RIP [] __list_del_entry+0x29/0xd0 [ 226.541776] RSP [ 226.612193] ---[ end trace 985ae23ddfcc357c ]--- Cc: Pablo Neira Ayuso Cc: Patrick McHardy Cc: Jozsef Kadlecsik Cc: "David S. Miller" Signed-off-by: Andrey Vagin Signed-off-by: Pablo Neira Ayuso --- .../linux/netfilter/nf_conntrack_proto_gre.h | 1 - net/netfilter/nf_conntrack_pptp.c | 20 +------------------ net/netfilter/nf_conntrack_proto_gre.c | 3 +-- 3 files changed, 2 insertions(+), 22 deletions(-) diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h index ec2ffaf418c8..df78dc2b5524 100644 --- a/include/linux/netfilter/nf_conntrack_proto_gre.h +++ b/include/linux/netfilter/nf_conntrack_proto_gre.h @@ -87,7 +87,6 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, /* delete keymap entries */ void nf_ct_gre_keymap_destroy(struct nf_conn *ct); -void nf_ct_gre_keymap_flush(struct net *net); void nf_nat_need_gre(void); #endif /* __KERNEL__ */ diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c index 7bd03decd36c..825c3e3f8305 100644 --- a/net/netfilter/nf_conntrack_pptp.c +++ b/net/netfilter/nf_conntrack_pptp.c @@ -605,32 +605,14 @@ static struct nf_conntrack_helper pptp __read_mostly = { .expect_policy = &pptp_exp_policy, }; -static void nf_conntrack_pptp_net_exit(struct net *net) -{ - nf_ct_gre_keymap_flush(net); -} - -static struct pernet_operations nf_conntrack_pptp_net_ops = { - .exit = nf_conntrack_pptp_net_exit, -}; - static int __init nf_conntrack_pptp_init(void) { - int rv; - - rv = nf_conntrack_helper_register(&pptp); - if (rv < 0) - return rv; - rv = register_pernet_subsys(&nf_conntrack_pptp_net_ops); - if (rv < 0) - nf_conntrack_helper_unregister(&pptp); - return rv; + return nf_conntrack_helper_register(&pptp); } static void __exit nf_conntrack_pptp_fini(void) { nf_conntrack_helper_unregister(&pptp); - unregister_pernet_subsys(&nf_conntrack_pptp_net_ops); } module_init(nf_conntrack_pptp_init); diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index 9d9c0dade602..d5665739e3b1 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -66,7 +66,7 @@ static inline struct netns_proto_gre *gre_pernet(struct net *net) return net_generic(net, proto_gre_net_id); } -void nf_ct_gre_keymap_flush(struct net *net) +static void nf_ct_gre_keymap_flush(struct net *net) { struct netns_proto_gre *net_gre = gre_pernet(net); struct nf_ct_gre_keymap *km, *tmp; @@ -78,7 +78,6 @@ void nf_ct_gre_keymap_flush(struct net *net) } write_unlock_bh(&net_gre->keymap_lock); } -EXPORT_SYMBOL(nf_ct_gre_keymap_flush); static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km, const struct nf_conntrack_tuple *t) -- GitLab From f5f85ee065f2e243f4165d7dd7d1a4a95daa1801 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 8 Apr 2014 11:06:26 +0200 Subject: [PATCH 035/797] ata: fix i.MX AHCI driver dependencies The ahci_imx driver is only needed on Freescale i.MX platforms so don't let it be built on other platforms, except for build test purpose. Signed-off-by: Jean Delvare Cc: Tejun Heo Cc: Richard Zhu Signed-off-by: Tejun Heo --- drivers/ata/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 2e4da3bc47fc..c2706047337f 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -116,7 +116,7 @@ config AHCI_ST config AHCI_IMX tristate "Freescale i.MX AHCI SATA support" - depends on MFD_SYSCON + depends on MFD_SYSCON && (ARCH_MXC || COMPILE_TEST) help This option enables support for the Freescale i.MX SoC's onboard AHCI SATA. -- GitLab From 5e3283e2920a0bd8a806964d80274b8756e0dd7f Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 8 Apr 2014 11:08:41 +0100 Subject: [PATCH 036/797] dm thin: irqsave must always be used with the pool->lock spinlock Commit c140e1c4e23 ("dm thin: use per thin device deferred bio lists") incorrectly stopped disabling irqs when taking the pool's spinlock. Irqs must be disabled when taking the pool's spinlock otherwise a thread could spin_lock(), then get interrupted to service thin_endio() in interrupt context, which would then deadlock in spin_lock_irqsave(). Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-thin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 53728be84dee..ae5fd0b9c75c 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -3101,6 +3101,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) struct thin_c *tc; struct dm_dev *pool_dev, *origin_dev; struct mapped_device *pool_md; + unsigned long flags; mutex_lock(&dm_thin_pool_table.mutex); @@ -3191,9 +3192,9 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) mutex_unlock(&dm_thin_pool_table.mutex); - spin_lock(&tc->pool->lock); + spin_lock_irqsave(&tc->pool->lock, flags); list_add_tail_rcu(&tc->list, &tc->pool->active_thins); - spin_unlock(&tc->pool->lock); + spin_unlock_irqrestore(&tc->pool->lock, flags); /* * This synchronize_rcu() call is needed here otherwise we risk a * wake_worker() call finding no bios to process (because the newly -- GitLab From 1ca2030563534bc0b057df9fddd30fb6257826cb Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 7 Apr 2014 10:37:44 +0200 Subject: [PATCH 037/797] drm/tegra: dp: Support address-only I2C-over-AUX transactions Certain types of I2C-over-AUX transactions require that only the address is transferred. Detect this by looking at the AUX message's size and set the address-only bit appropriately. Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dpaux.c | 44 ++++++++++++++++++++++++----------- drivers/gpu/drm/tegra/dpaux.h | 1 + 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c index d536ed381fbd..005c19bd92df 100644 --- a/drivers/gpu/drm/tegra/dpaux.c +++ b/drivers/gpu/drm/tegra/dpaux.c @@ -99,55 +99,73 @@ static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer, static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { - unsigned long value = DPAUX_DP_AUXCTL_TRANSACTREQ; unsigned long timeout = msecs_to_jiffies(250); struct tegra_dpaux *dpaux = to_dpaux(aux); unsigned long status; ssize_t ret = 0; + u32 value; - if (msg->size < 1 || msg->size > 16) + /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */ + if (msg->size > 16) return -EINVAL; - tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR); + /* + * Allow zero-sized messages only for I2C, in which case they specify + * address-only transactions. + */ + if (msg->size < 1) { + switch (msg->request & ~DP_AUX_I2C_MOT) { + case DP_AUX_I2C_WRITE: + case DP_AUX_I2C_READ: + value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY; + break; + + default: + return -EINVAL; + } + } else { + /* For non-zero-sized messages, set the CMDLEN field. */ + value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1); + } switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_I2C_WRITE: if (msg->request & DP_AUX_I2C_MOT) - value = DPAUX_DP_AUXCTL_CMD_MOT_WR; + value |= DPAUX_DP_AUXCTL_CMD_MOT_WR; else - value = DPAUX_DP_AUXCTL_CMD_I2C_WR; + value |= DPAUX_DP_AUXCTL_CMD_I2C_WR; break; case DP_AUX_I2C_READ: if (msg->request & DP_AUX_I2C_MOT) - value = DPAUX_DP_AUXCTL_CMD_MOT_RD; + value |= DPAUX_DP_AUXCTL_CMD_MOT_RD; else - value = DPAUX_DP_AUXCTL_CMD_I2C_RD; + value |= DPAUX_DP_AUXCTL_CMD_I2C_RD; break; case DP_AUX_I2C_STATUS: if (msg->request & DP_AUX_I2C_MOT) - value = DPAUX_DP_AUXCTL_CMD_MOT_RQ; + value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ; else - value = DPAUX_DP_AUXCTL_CMD_I2C_RQ; + value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ; break; case DP_AUX_NATIVE_WRITE: - value = DPAUX_DP_AUXCTL_CMD_AUX_WR; + value |= DPAUX_DP_AUXCTL_CMD_AUX_WR; break; case DP_AUX_NATIVE_READ: - value = DPAUX_DP_AUXCTL_CMD_AUX_RD; + value |= DPAUX_DP_AUXCTL_CMD_AUX_RD; break; default: return -EINVAL; } - value |= DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1); + tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR); tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL); if ((msg->request & DP_AUX_I2C_READ) == 0) { @@ -198,7 +216,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux, break; } - if (msg->reply == DP_AUX_NATIVE_REPLY_ACK) { + if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) { if (msg->request & DP_AUX_I2C_READ) { size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK; diff --git a/drivers/gpu/drm/tegra/dpaux.h b/drivers/gpu/drm/tegra/dpaux.h index 4f5bf10fdff9..806e245ca787 100644 --- a/drivers/gpu/drm/tegra/dpaux.h +++ b/drivers/gpu/drm/tegra/dpaux.h @@ -32,6 +32,7 @@ #define DPAUX_DP_AUXCTL_CMD_I2C_RQ (2 << 12) #define DPAUX_DP_AUXCTL_CMD_I2C_RD (1 << 12) #define DPAUX_DP_AUXCTL_CMD_I2C_WR (0 << 12) +#define DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY (1 << 8) #define DPAUX_DP_AUXCTL_CMDLEN(x) ((x) & 0xff) #define DPAUX_DP_AUXSTAT 0x31 -- GitLab From a6c8aff022d4d06e4b41455ae9b2a5d3d503bf76 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Mon, 7 Apr 2014 12:37:25 +0300 Subject: [PATCH 038/797] drm/i915: support address only i2c-over-aux transactions To support bare address requests used by the drm dp helpers. Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a0dad1a2f819..d2a55884ad52 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -575,7 +575,8 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, return ret; } -#define HEADER_SIZE 4 +#define BARE_ADDRESS_SIZE 3 +#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1) static ssize_t intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { @@ -592,7 +593,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_WRITE: case DP_AUX_I2C_WRITE: - txsize = HEADER_SIZE + msg->size; + txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE; rxsize = 1; if (WARN_ON(txsize > 20)) @@ -611,7 +612,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) case DP_AUX_NATIVE_READ: case DP_AUX_I2C_READ: - txsize = HEADER_SIZE; + txsize = msg->size ? HEADER_SIZE : BARE_ADDRESS_SIZE; rxsize = msg->size + 1; if (WARN_ON(rxsize > 20)) -- GitLab From 25377b921b4078a509f384fdd328b50d46414d9c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 7 Apr 2014 10:33:43 -0400 Subject: [PATCH 039/797] drm/radeon/dp: handle zero sized i2c over aux transactions (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Needed for proper i2c over aux handling for certain monitors and configurations (e.g., dp bridges or adapters). v2: add comments clarifying tx_size setting. Signed-off-by: Alex Deucher Signed-off-by: Christian König --- drivers/gpu/drm/radeon/atombios_dp.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 8b0ab170cef9..e4483042aee0 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -142,7 +142,8 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan, return recv_bytes; } -#define HEADER_SIZE 4 +#define BARE_ADDRESS_SIZE 3 +#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1) static ssize_t radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) @@ -160,13 +161,19 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) tx_buf[0] = msg->address & 0xff; tx_buf[1] = msg->address >> 8; tx_buf[2] = msg->request << 4; - tx_buf[3] = msg->size - 1; + tx_buf[3] = msg->size ? (msg->size - 1) : 0; switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_WRITE: case DP_AUX_I2C_WRITE: + /* tx_size needs to be 4 even for bare address packets since the atom + * table needs the info in tx_buf[3]. + */ tx_size = HEADER_SIZE + msg->size; - tx_buf[3] |= tx_size << 4; + if (msg->size == 0) + tx_buf[3] |= BARE_ADDRESS_SIZE << 4; + else + tx_buf[3] |= tx_size << 4; memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size); ret = radeon_process_aux_ch(chan, tx_buf, tx_size, NULL, 0, delay, &ack); @@ -176,8 +183,14 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) break; case DP_AUX_NATIVE_READ: case DP_AUX_I2C_READ: + /* tx_size needs to be 4 even for bare address packets since the atom + * table needs the info in tx_buf[3]. + */ tx_size = HEADER_SIZE; - tx_buf[3] |= tx_size << 4; + if (msg->size == 0) + tx_buf[3] |= BARE_ADDRESS_SIZE << 4; + else + tx_buf[3] |= tx_size << 4; ret = radeon_process_aux_ch(chan, tx_buf, tx_size, msg->buffer, msg->size, delay, &ack); break; @@ -186,7 +199,7 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) break; } - if (ret > 0) + if (ret >= 0) msg->reply = ack >> 4; return ret; -- GitLab From ccdb516e1873d9c69377bfec1e3392f3ed660102 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 7 Apr 2014 10:33:44 -0400 Subject: [PATCH 040/797] drm/dp/i2c: send bare addresses to properly reset i2c connections (v4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need bare address packets at the start and end of each i2c over aux transaction to properly reset the connection between transactions. This mirrors what the existing dp i2c over aux algo currently does. This fixes EDID fetches on certain monitors especially with dp bridges. v2: update as per Ville's comments - Set buffer to NULL for zero sized packets - abort the entre transaction if one of the messages fails v3: drop leftover debugging code v4: integrate Thierry's comments - add comments about address only transactions - switch back to i and j Signed-off-by: Alex Deucher Cc: Ville Syrjälä Cc: Jani Nikula Cc: Thierry Reding Reviewed-by: Ville Syrjälä Signed-off-by: Christian König --- drivers/gpu/drm/drm_dp_helper.c | 51 +++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 27671489477d..bcfb0d07718e 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -665,11 +665,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, { struct drm_dp_aux *aux = adapter->algo_data; unsigned int i, j; + struct drm_dp_aux_msg msg; + int err = 0; - for (i = 0; i < num; i++) { - struct drm_dp_aux_msg msg; - int err; + memset(&msg, 0, sizeof(msg)); + for (i = 0; i < num; i++) { + msg.address = msgs[i].addr; + msg.request = (msgs[i].flags & I2C_M_RD) ? + DP_AUX_I2C_READ : + DP_AUX_I2C_WRITE; + msg.request |= DP_AUX_I2C_MOT; + /* Send a bare address packet to start the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.buffer = NULL; + msg.size = 0; + err = drm_dp_i2c_do_msg(aux, &msg); + if (err < 0) + break; /* * Many hardware implementations support FIFOs larger than a * single byte, but it has been empirically determined that @@ -678,30 +693,28 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, * transferred byte-by-byte. */ for (j = 0; j < msgs[i].len; j++) { - memset(&msg, 0, sizeof(msg)); - msg.address = msgs[i].addr; - - msg.request = (msgs[i].flags & I2C_M_RD) ? - DP_AUX_I2C_READ : - DP_AUX_I2C_WRITE; - - /* - * All messages except the last one are middle-of- - * transfer messages. - */ - if ((i < num - 1) || (j < msgs[i].len - 1)) - msg.request |= DP_AUX_I2C_MOT; - msg.buffer = msgs[i].buf + j; msg.size = 1; err = drm_dp_i2c_do_msg(aux, &msg); if (err < 0) - return err; + break; } + if (err < 0) + break; } + if (err >= 0) + err = num; + /* Send a bare address packet to close out the transaction. + * Zero sized messages specify an address only (bare + * address) transaction. + */ + msg.request &= ~DP_AUX_I2C_MOT; + msg.buffer = NULL; + msg.size = 0; + (void)drm_dp_i2c_do_msg(aux, &msg); - return num; + return err; } static const struct i2c_algorithm drm_dp_i2c_algo = { -- GitLab From 732d50b431dca2f3f78fc21ba9b7ed9d06bb01ce Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 7 Apr 2014 10:33:45 -0400 Subject: [PATCH 041/797] drm/dp/i2c: Update comments about common i2c over dp assumptions (v3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If you are using the common dp over i2c functionality, it is asumed that the aux transfer function does not modify the any of the msg structure other than the reply field. Doing so breaks the logic in the common code. v2: update struct drm_dp_aux comments about assumptions v3 (chk): rebased on upstream changes Signed-off-by: Alex Deucher Cc: Ville Syrjälä Cc: Jani Nikula Cc: Thierry Reding Reviewed-by: Ville Syrjälä Signed-off-by: Christian König --- drivers/gpu/drm/drm_dp_helper.c | 4 +++- include/drm/drm_dp_helper.h | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index bcfb0d07718e..4b6e6f3ba0a1 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c @@ -577,7 +577,9 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter) /* * Transfer a single I2C-over-AUX message and handle various error conditions, - * retrying the transaction as appropriate. + * retrying the transaction as appropriate. It is assumed that the + * aux->transfer function does not modify anything in the msg other than the + * reply field. */ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) { diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index b4f58914bf7d..cfcacec5b89d 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -456,6 +456,10 @@ struct drm_dp_aux_msg { * transactions. The drm_dp_aux_register_i2c_bus() function registers an * I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers * should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter. + * + * Note that the aux helper code assumes that the .transfer() function + * only modifies the reply field of the drm_dp_aux_msg structure. The + * retry logic and i2c helpers assume this is the case. */ struct drm_dp_aux { const char *name; -- GitLab From 379dfc25e257ffe10eb53b86d2375f7c0f4f33ef Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 7 Apr 2014 10:33:46 -0400 Subject: [PATCH 042/797] drm/radeon/dp: switch to the common i2c over aux code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provides a nice cleanup in radeon. Signed-off-by: Alex Deucher Signed-off-by: Christian König --- drivers/gpu/drm/radeon/atombios_dp.c | 117 +++------------------ drivers/gpu/drm/radeon/radeon_connectors.c | 44 ++------ drivers/gpu/drm/radeon/radeon_display.c | 11 +- drivers/gpu/drm/radeon/radeon_i2c.c | 60 +++-------- drivers/gpu/drm/radeon/radeon_mode.h | 12 +-- 5 files changed, 44 insertions(+), 200 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index e4483042aee0..15936524f226 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -207,98 +207,15 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) void radeon_dp_aux_init(struct radeon_connector *radeon_connector) { - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; - - dig_connector->dp_i2c_bus->aux.dev = radeon_connector->base.kdev; - dig_connector->dp_i2c_bus->aux.transfer = radeon_dp_aux_transfer; -} - -int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, - u8 write_byte, u8 *read_byte) -{ - struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; - struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter); - u16 address = algo_data->address; - u8 msg[5]; - u8 reply[2]; - unsigned retry; - int msg_bytes; - int reply_bytes = 1; int ret; - u8 ack; - - /* Set up the address */ - msg[0] = address; - msg[1] = address >> 8; - - /* Set up the command byte */ - if (mode & MODE_I2C_READ) { - msg[2] = DP_AUX_I2C_READ << 4; - msg_bytes = 4; - msg[3] = msg_bytes << 4; - } else { - msg[2] = DP_AUX_I2C_WRITE << 4; - msg_bytes = 5; - msg[3] = msg_bytes << 4; - msg[4] = write_byte; - } - /* special handling for start/stop */ - if (mode & (MODE_I2C_START | MODE_I2C_STOP)) - msg[3] = 3 << 4; - - /* Set MOT bit for all but stop */ - if ((mode & MODE_I2C_STOP) == 0) - msg[2] |= DP_AUX_I2C_MOT << 4; - - for (retry = 0; retry < 7; retry++) { - ret = radeon_process_aux_ch(auxch, - msg, msg_bytes, reply, reply_bytes, 0, &ack); - if (ret == -EBUSY) - continue; - else if (ret < 0) { - DRM_DEBUG_KMS("aux_ch failed %d\n", ret); - return ret; - } + radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; + radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer; + ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux); + if (!ret) + radeon_connector->ddc_bus->has_aux = true; - switch ((ack >> 4) & DP_AUX_NATIVE_REPLY_MASK) { - case DP_AUX_NATIVE_REPLY_ACK: - /* I2C-over-AUX Reply field is only valid - * when paired with AUX ACK. - */ - break; - case DP_AUX_NATIVE_REPLY_NACK: - DRM_DEBUG_KMS("aux_ch native nack\n"); - return -EREMOTEIO; - case DP_AUX_NATIVE_REPLY_DEFER: - DRM_DEBUG_KMS("aux_ch native defer\n"); - usleep_range(500, 600); - continue; - default: - DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack); - return -EREMOTEIO; - } - - switch ((ack >> 4) & DP_AUX_I2C_REPLY_MASK) { - case DP_AUX_I2C_REPLY_ACK: - if (mode == MODE_I2C_READ) - *read_byte = reply[0]; - return ret; - case DP_AUX_I2C_REPLY_NACK: - DRM_DEBUG_KMS("aux_i2c nack\n"); - return -EREMOTEIO; - case DP_AUX_I2C_REPLY_DEFER: - DRM_DEBUG_KMS("aux_i2c defer\n"); - usleep_range(400, 500); - break; - default: - DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack); - return -EREMOTEIO; - } - } - - DRM_DEBUG_KMS("aux i2c too many retries, giving up\n"); - return -EREMOTEIO; + WARN(ret, "drm_dp_aux_register_i2c_bus() failed with error %d\n", ret); } /***** general DP utility functions *****/ @@ -433,12 +350,11 @@ static u8 radeon_dp_encoder_service(struct radeon_device *rdev, u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector) { - struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; struct drm_device *dev = radeon_connector->base.dev; struct radeon_device *rdev = dev->dev_private; return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0, - dig_connector->dp_i2c_bus->rec.i2c_id, 0); + radeon_connector->ddc_bus->rec.i2c_id, 0); } static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) @@ -449,11 +365,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) return; - if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_SINK_OUI, buf, 3)) + if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3)) DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); - if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_BRANCH_OUI, buf, 3)) + if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3)) DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", buf[0], buf[1], buf[2]); } @@ -464,7 +380,7 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector) u8 msg[DP_DPCD_SIZE]; int ret, i; - ret = drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_DPCD_REV, msg, + ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_DPCD_REV, msg, DP_DPCD_SIZE); if (ret > 0) { memcpy(dig_connector->dpcd, msg, DP_DPCD_SIZE); @@ -502,7 +418,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, if (dp_bridge != ENCODER_OBJECT_ID_NONE) { /* DP bridge chips */ - drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, + drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_EDP_CONFIGURATION_CAP, &tmp); if (tmp & 1) panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; @@ -513,7 +429,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { /* eDP */ - drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, + drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_EDP_CONFIGURATION_CAP, &tmp); if (tmp & 1) panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; @@ -567,7 +483,8 @@ bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector) u8 link_status[DP_LINK_STATUS_SIZE]; struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - if (drm_dp_dpcd_read_link_status(&dig->dp_i2c_bus->aux, link_status) <= 0) + if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status) + <= 0) return false; if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count)) return false; @@ -587,7 +504,7 @@ void radeon_dp_set_rx_power_state(struct drm_connector *connector, /* power up/down the sink */ if (dig_connector->dpcd[0] >= 0x11) { - drm_dp_dpcd_writeb(&dig_connector->dp_i2c_bus->aux, + drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux, DP_SET_POWER, power_state); usleep_range(1000, 2000); } @@ -891,7 +808,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder, else dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; - drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, DP_MAX_LANE_COUNT, &tmp); + drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp); if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) dp_info.tp3_supported = true; else @@ -903,7 +820,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder, dp_info.connector = connector; dp_info.dp_lane_count = dig_connector->dp_lane_count; dp_info.dp_clock = dig_connector->dp_clock; - dp_info.aux = &dig_connector->dp_i2c_bus->aux; + dp_info.aux = &radeon_connector->ddc_bus->aux; if (radeon_dp_link_train_init(&dp_info)) goto done; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index c566b486ca08..ea50e0ae7bf7 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1261,21 +1261,6 @@ static const struct drm_connector_funcs radeon_dvi_connector_funcs = { .force = radeon_dvi_force, }; -static void radeon_dp_connector_destroy(struct drm_connector *connector) -{ - struct radeon_connector *radeon_connector = to_radeon_connector(connector); - struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; - - if (radeon_connector->edid) - kfree(radeon_connector->edid); - if (radeon_dig_connector->dp_i2c_bus) - radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus); - kfree(radeon_connector->con_priv); - drm_sysfs_connector_remove(connector); - drm_connector_cleanup(connector); - kfree(connector); -} - static int radeon_dp_get_modes(struct drm_connector *connector) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); @@ -1553,7 +1538,7 @@ static const struct drm_connector_funcs radeon_dp_connector_funcs = { .detect = radeon_dp_detect, .fill_modes = drm_helper_probe_single_connector_modes, .set_property = radeon_connector_set_property, - .destroy = radeon_dp_connector_destroy, + .destroy = radeon_connector_destroy, .force = radeon_dvi_force, }; @@ -1562,7 +1547,7 @@ static const struct drm_connector_funcs radeon_edp_connector_funcs = { .detect = radeon_dp_detect, .fill_modes = drm_helper_probe_single_connector_modes, .set_property = radeon_lvds_set_property, - .destroy = radeon_dp_connector_destroy, + .destroy = radeon_connector_destroy, .force = radeon_dvi_force, }; @@ -1571,7 +1556,7 @@ static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = { .detect = radeon_dp_detect, .fill_modes = drm_helper_probe_single_connector_modes, .set_property = radeon_lvds_set_property, - .destroy = radeon_dp_connector_destroy, + .destroy = radeon_connector_destroy, .force = radeon_dvi_force, }; @@ -1668,17 +1653,10 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_dig_connector->igp_lane_info = igp_lane_info; radeon_connector->con_priv = radeon_dig_connector; if (i2c_bus->valid) { - /* add DP i2c bus */ - if (connector_type == DRM_MODE_CONNECTOR_eDP) - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); - else - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); - if (radeon_dig_connector->dp_i2c_bus) + radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); + if (radeon_connector->ddc_bus) has_aux = true; else - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); } switch (connector_type) { @@ -1893,10 +1871,6 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); if (i2c_bus->valid) { - /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); - if (!radeon_dig_connector->dp_i2c_bus) - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); if (radeon_connector->ddc_bus) has_aux = true; @@ -1942,14 +1916,10 @@ radeon_add_atom_connector(struct drm_device *dev, drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type); drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs); if (i2c_bus->valid) { - /* add DP i2c bus */ - radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch"); - if (radeon_dig_connector->dp_i2c_bus) + radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); + if (radeon_connector->ddc_bus) has_aux = true; else - DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); - radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); - if (!radeon_connector->ddc_bus) DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); } drm_object_attach_property(&radeon_connector->base.base, diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 386cfa4c194d..776e03d6ac81 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -759,19 +759,18 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != ENCODER_OBJECT_ID_NONE) { - struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - - if (dig->dp_i2c_bus) + if (radeon_connector->ddc_bus->has_aux) radeon_connector->edid = drm_get_edid(&radeon_connector->base, - &dig->dp_i2c_bus->adapter); + &radeon_connector->ddc_bus->aux.ddc); } else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || - dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && dig->dp_i2c_bus) + dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) && + radeon_connector->ddc_bus->has_aux) radeon_connector->edid = drm_get_edid(&radeon_connector->base, - &dig->dp_i2c_bus->adapter); + &radeon_connector->ddc_bus->aux.ddc); else if (radeon_connector->ddc_bus && !radeon_connector->edid) radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index e24ca6ab96de..7b944142a9fd 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -64,8 +64,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux) radeon_router_select_ddc_port(radeon_connector); if (use_aux) { - struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; - ret = i2c_transfer(&dig->dp_i2c_bus->adapter, msgs, 2); + ret = i2c_transfer(&radeon_connector->ddc_bus->aux.ddc, msgs, 2); } else { ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); } @@ -950,16 +949,16 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, /* set the radeon bit adapter */ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "Radeon i2c bit bus %s", name); - i2c->adapter.algo_data = &i2c->algo.bit; - i2c->algo.bit.pre_xfer = pre_xfer; - i2c->algo.bit.post_xfer = post_xfer; - i2c->algo.bit.setsda = set_data; - i2c->algo.bit.setscl = set_clock; - i2c->algo.bit.getsda = get_data; - i2c->algo.bit.getscl = get_clock; - i2c->algo.bit.udelay = 10; - i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ - i2c->algo.bit.data = i2c; + i2c->adapter.algo_data = &i2c->bit; + i2c->bit.pre_xfer = pre_xfer; + i2c->bit.post_xfer = post_xfer; + i2c->bit.setsda = set_data; + i2c->bit.setscl = set_clock; + i2c->bit.getsda = get_data; + i2c->bit.getscl = get_clock; + i2c->bit.udelay = 10; + i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */ + i2c->bit.data = i2c; ret = i2c_bit_add_bus(&i2c->adapter); if (ret) { DRM_ERROR("Failed to register bit i2c %s\n", name); @@ -974,46 +973,13 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, } -struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name) -{ - struct radeon_i2c_chan *i2c; - int ret; - - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); - if (i2c == NULL) - return NULL; - - i2c->rec = *rec; - i2c->adapter.owner = THIS_MODULE; - i2c->adapter.class = I2C_CLASS_DDC; - i2c->adapter.dev.parent = &dev->pdev->dev; - i2c->dev = dev; - snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), - "Radeon aux bus %s", name); - i2c_set_adapdata(&i2c->adapter, i2c); - i2c->adapter.algo_data = &i2c->algo.dp; - i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; - i2c->algo.dp.address = 0; - ret = i2c_dp_aux_add_bus(&i2c->adapter); - if (ret) { - DRM_INFO("Failed to register i2c %s\n", name); - goto out_free; - } - - return i2c; -out_free: - kfree(i2c); - return NULL; - -} - void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) { if (!i2c) return; i2c_del_adapter(&i2c->adapter); + if (i2c->has_aux) + drm_dp_aux_unregister_i2c_bus(&i2c->aux); kfree(i2c); } diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 832d9fa1a4c4..6ddf31a2d34e 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -187,12 +187,10 @@ struct radeon_pll { struct radeon_i2c_chan { struct i2c_adapter adapter; struct drm_device *dev; - union { - struct i2c_algo_bit_data bit; - struct i2c_algo_dp_aux_data dp; - } algo; + struct i2c_algo_bit_data bit; struct radeon_i2c_bus_rec rec; struct drm_dp_aux aux; + bool has_aux; }; /* mostly for macs, but really any system without connector tables */ @@ -440,7 +438,6 @@ struct radeon_encoder { struct radeon_connector_atom_dig { uint32_t igp_lane_info; /* displayport */ - struct radeon_i2c_chan *dp_i2c_bus; u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 dp_sink_type; int dp_clock; @@ -702,8 +699,6 @@ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder, uint8_t lane_set); extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder); extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder); -extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, - u8 write_byte, u8 *read_byte); void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le); extern void radeon_i2c_init(struct radeon_device *rdev); @@ -715,9 +710,6 @@ extern void radeon_i2c_add(struct radeon_device *rdev, const char *name); extern struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev, struct radeon_i2c_bus_rec *i2c_bus); -extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, - struct radeon_i2c_bus_rec *rec, - const char *name); extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_bus_rec *rec, const char *name); -- GitLab From b10ebd34cccae1b431caf1be54919aede2be7cbe Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 8 Apr 2014 11:29:01 +0100 Subject: [PATCH 043/797] dm thin: fix rcu_read_lock being held in code that can sleep Commit c140e1c4e23 ("dm thin: use per thin device deferred bio lists") introduced the use of an rculist for all active thin devices. The use of rcu_read_lock() in process_deferred_bios() can result in a BUG if a dm_bio_prison_cell must be allocated as a side-effect of bio_detain(): BUG: sleeping function called from invalid context at mm/mempool.c:203 in_atomic(): 1, irqs_disabled(): 0, pid: 6, name: kworker/u8:0 3 locks held by kworker/u8:0/6: #0: ("dm-" "thin"){.+.+..}, at: [] process_one_work+0x192/0x550 #1: ((&pool->worker)){+.+...}, at: [] process_one_work+0x192/0x550 #2: (rcu_read_lock){.+.+..}, at: [] do_worker+0x5/0x4d0 We can't process deferred bios with the rcu lock held, since dm_bio_prison_cell allocation may block if the bio-prison's cell mempool is exhausted. To fix: - Introduce a refcount and completion field to each thin_c - Add thin_get/put methods for adjusting the refcount. If the refcount hits zero then the completion is triggered. - Initialise refcount to 1 when creating thin_c - When iterating the active_thins list we thin_get() whilst the rcu lock is held. - After the rcu lock is dropped we process the deferred bios for that thin. - When destroying a thin_c we thin_put() and then wait for the completion -- to avoid a race between the worker thread iterating from that thin_c and destroying the thin_c. Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-thin.c | 70 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ae5fd0b9c75c..28fc282b61b2 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -232,6 +232,13 @@ struct thin_c { struct bio_list deferred_bio_list; struct bio_list retry_on_resume_list; struct rb_root sort_bio_list; /* sorted list of deferred bios */ + + /* + * Ensures the thin is not destroyed until the worker has finished + * iterating the active_thins list. + */ + atomic_t refcount; + struct completion can_destroy; }; /*----------------------------------------------------------------*/ @@ -1486,6 +1493,45 @@ static void process_thin_deferred_bios(struct thin_c *tc) blk_finish_plug(&plug); } +static void thin_get(struct thin_c *tc); +static void thin_put(struct thin_c *tc); + +/* + * We can't hold rcu_read_lock() around code that can block. So we + * find a thin with the rcu lock held; bump a refcount; then drop + * the lock. + */ +static struct thin_c *get_first_thin(struct pool *pool) +{ + struct thin_c *tc = NULL; + + rcu_read_lock(); + if (!list_empty(&pool->active_thins)) { + tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); + thin_get(tc); + } + rcu_read_unlock(); + + return tc; +} + +static struct thin_c *get_next_thin(struct pool *pool, struct thin_c *tc) +{ + struct thin_c *old_tc = tc; + + rcu_read_lock(); + list_for_each_entry_continue_rcu(tc, &pool->active_thins, list) { + thin_get(tc); + thin_put(old_tc); + rcu_read_unlock(); + return tc; + } + thin_put(old_tc); + rcu_read_unlock(); + + return NULL; +} + static void process_deferred_bios(struct pool *pool) { unsigned long flags; @@ -1493,10 +1539,11 @@ static void process_deferred_bios(struct pool *pool) struct bio_list bios; struct thin_c *tc; - rcu_read_lock(); - list_for_each_entry_rcu(tc, &pool->active_thins, list) + tc = get_first_thin(pool); + while (tc) { process_thin_deferred_bios(tc); - rcu_read_unlock(); + tc = get_next_thin(pool, tc); + } /* * If there are any deferred flush bios, we must commit @@ -3061,11 +3108,25 @@ static struct target_type pool_target = { /*---------------------------------------------------------------- * Thin target methods *--------------------------------------------------------------*/ +static void thin_get(struct thin_c *tc) +{ + atomic_inc(&tc->refcount); +} + +static void thin_put(struct thin_c *tc) +{ + if (atomic_dec_and_test(&tc->refcount)) + complete(&tc->can_destroy); +} + static void thin_dtr(struct dm_target *ti) { struct thin_c *tc = ti->private; unsigned long flags; + thin_put(tc); + wait_for_completion(&tc->can_destroy); + spin_lock_irqsave(&tc->pool->lock, flags); list_del_rcu(&tc->list); spin_unlock_irqrestore(&tc->pool->lock, flags); @@ -3192,6 +3253,9 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv) mutex_unlock(&dm_thin_pool_table.mutex); + atomic_set(&tc->refcount, 1); + init_completion(&tc->can_destroy); + spin_lock_irqsave(&tc->pool->lock, flags); list_add_tail_rcu(&tc->list, &tc->pool->active_thins); spin_unlock_irqrestore(&tc->pool->lock, flags); -- GitLab From 87f7e41636ff201148443551d06bc74497160aac Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 8 Apr 2014 11:38:28 -0400 Subject: [PATCH 044/797] ext4: update PF_MEMALLOC handling in ext4_write_inode() The special handling of PF_MEMALLOC callers in ext4_write_inode() shouldn't be necessary as there shouldn't be any. Warn about it. Also update comment before the function as it seems somewhat outdated. (Changes modeled on an ext3 patch posted by Jan Kara to the linux-ext4 mailing list on Februaryt 28, 2014, which apparently never went into the ext3 tree.) Signed-off-by: "Theodore Ts'o" Cc: Jan Kara --- fs/ext4/inode.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 93f16c5e8a8e..7b93df9aa182 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4427,21 +4427,20 @@ static int ext4_do_update_inode(handle_t *handle, * * We are called from a few places: * - * - Within generic_file_write() for O_SYNC files. + * - Within generic_file_aio_write() -> generic_write_sync() for O_SYNC files. * Here, there will be no transaction running. We wait for any running * transaction to commit. * - * - Within sys_sync(), kupdate and such. - * We wait on commit, if tol to. + * - Within flush work (sys_sync(), kupdate and such). + * We wait on commit, if told to. * - * - Within prune_icache() (PF_MEMALLOC == true) - * Here we simply return. We can't afford to block kswapd on the - * journal commit. + * - Within iput_final() -> write_inode_now() + * We wait on commit, if told to. * * In all cases it is actually safe for us to return without doing anything, * because the inode has been copied into a raw inode buffer in - * ext4_mark_inode_dirty(). This is a correctness thing for O_SYNC and for - * knfsd. + * ext4_mark_inode_dirty(). This is a correctness thing for WB_SYNC_ALL + * writeback. * * Note that we are absolutely dependent upon all inode dirtiers doing the * right thing: they *must* call mark_inode_dirty() after dirtying info in @@ -4453,15 +4452,15 @@ static int ext4_do_update_inode(handle_t *handle, * stuff(); * inode->i_size = expr; * - * is in error because a kswapd-driven write_inode() could occur while - * `stuff()' is running, and the new i_size will be lost. Plus the inode - * will no longer be on the superblock's dirty inode list. + * is in error because write_inode() could occur while `stuff()' is running, + * and the new i_size will be lost. Plus the inode will no longer be on the + * superblock's dirty inode list. */ int ext4_write_inode(struct inode *inode, struct writeback_control *wbc) { int err; - if (current->flags & PF_MEMALLOC) + if (WARN_ON_ONCE(current->flags & PF_MEMALLOC)) return 0; if (EXT4_SB(inode->i_sb)->s_journal) { -- GitLab From be0949f5eb9c8133a05cf25f108f09e85e79cd32 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 8 Apr 2014 11:28:54 -0400 Subject: [PATCH 045/797] drm/radeon: fix audio pin counts for DCE6+ (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is actually quite a bit of variance based on the asic. v2: fix typo noticed by Jerome. Signed-off-by: Alex Deucher Signed-off-by: Christian König Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/dce6_afmt.c | 14 ++++++++++---- drivers/gpu/drm/radeon/radeon.h | 5 ++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c index 94e858751994..0a65dc7e93e7 100644 --- a/drivers/gpu/drm/radeon/dce6_afmt.c +++ b/drivers/gpu/drm/radeon/dce6_afmt.c @@ -309,11 +309,17 @@ int dce6_audio_init(struct radeon_device *rdev) rdev->audio.enabled = true; - if (ASIC_IS_DCE8(rdev)) + if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */ + rdev->audio.num_pins = 7; + else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */ + rdev->audio.num_pins = 3; + else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */ + rdev->audio.num_pins = 7; + else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */ rdev->audio.num_pins = 6; - else if (ASIC_IS_DCE61(rdev)) - rdev->audio.num_pins = 4; - else + else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */ + rdev->audio.num_pins = 2; + else /* SI: 6 streams, 6 endpoints */ rdev->audio.num_pins = 6; for (i = 0; i < rdev->audio.num_pins; i++) { diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f21db7a0b34d..05b08e16e1f5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -739,7 +739,7 @@ union radeon_irq_stat_regs { struct cik_irq_stat_regs cik; }; -#define RADEON_MAX_HPD_PINS 6 +#define RADEON_MAX_HPD_PINS 7 #define RADEON_MAX_CRTCS 6 #define RADEON_MAX_AFMT_BLOCKS 7 @@ -2631,6 +2631,9 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); #define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND)) #define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN)) #define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE)) +#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI)) +#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE)) +#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI)) #define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \ (rdev->ddev->pdev->device == 0x6850) || \ -- GitLab From 8902e6f2b832e00e10c6f9e9532f6f63feb4972f Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Tue, 8 Apr 2014 13:39:36 +0300 Subject: [PATCH 046/797] drm/radeon: Improve vramlimit module param documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lauri Kasanen Signed-off-by: Christian König Reviewed-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d0eba48dd74e..cf2721a91249 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -186,7 +186,7 @@ module_param_named(dynclks, radeon_dynclks, int, 0444); MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx"); module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444); -MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing"); +MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes"); module_param_named(vramlimit, radeon_vram_limit, int, 0600); MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); -- GitLab From a8a934e44f2bd0ed613e1aa0471e3478c6a9228a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Tue, 1 Apr 2014 13:45:33 +0200 Subject: [PATCH 047/797] s390: fix control register update The git commit c63badebfebacdba827ab1cc1d420fc81bd8d818 "s390: optimize control register update" broke the update for control register 0. After the update do the lctlg from the correct value. Cc: # 3.14 Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 4ac8fafec95f..1c82619eb4f7 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -64,7 +64,7 @@ void update_cr_regs(struct task_struct *task) if (task->thread.per_flags & PER_FLAG_NO_TE) cr_new &= ~(1UL << 55); if (cr_new != cr) - __ctl_load(cr, 0, 0); + __ctl_load(cr_new, 0, 0); /* Set or clear transaction execution TDC bits 62 and 63. */ __ctl_store(cr, 2, 2); cr_new = cr & ~3UL; -- GitLab From e7c46c66dbd1727f7de52f54c4acefb692b24f37 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 4 Apr 2014 11:23:03 +0200 Subject: [PATCH 048/797] s390/smp: fix smp_stop_cpu() for !CONFIG_SMP smp_stop_cpu() should stop the current cpu even for !CONFIG_SMP. Otherwise machine_halt() will return and and the machine generates a panic instread of simply stopping the current cpu: Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000 CPU: 0 PID: 1 Comm: systemd-shutdow Not tainted 3.14.0-01527-g2b6ef16a6bc5 #10 [...] Call Trace: ([<0000000000110db0>] show_trace+0xf8/0x158) [<0000000000110e7a>] show_stack+0x6a/0xe8 [<000000000074dba8>] panic+0xe4/0x268 [<0000000000140570>] do_exit+0xa88/0xb2c [<000000000016e12c>] SyS_reboot+0x1f0/0x234 [<000000000075da70>] sysc_nr_ok+0x22/0x28 [<000000007d5a09b4>] 0x7d5a09b4 Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/sigp.h | 19 +++++++++++++++++++ arch/s390/include/asm/smp.h | 13 ++++++++++++- arch/s390/kernel/smp.c | 15 --------------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index d091aa1aaf11..bf9c823d4020 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h @@ -31,4 +31,23 @@ #define SIGP_STATUS_INCORRECT_STATE 0x00000200UL #define SIGP_STATUS_NOT_RUNNING 0x00000400UL +#ifndef __ASSEMBLY__ + +static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status) +{ + register unsigned int reg1 asm ("1") = parm; + int cc; + + asm volatile( + " sigp %1,%2,0(%3)\n" + " ipm %0\n" + " srl %0,28\n" + : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc"); + if (status && cc == 1) + *status = reg1; + return cc; +} + +#endif /* __ASSEMBLY__ */ + #endif /* __S390_ASM_SIGP_H */ diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 160779394096..21703f85b48d 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h @@ -7,6 +7,8 @@ #ifndef __ASM_SMP_H #define __ASM_SMP_H +#include + #ifdef CONFIG_SMP #include @@ -50,9 +52,18 @@ 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_yield(void) { } -static inline void smp_stop_cpu(void) { } static inline void smp_fill_possible_mask(void) { } +static inline void smp_stop_cpu(void) +{ + u16 pcpu = stap(); + + for (;;) { + __pcpu_sigp(pcpu, SIGP_STOP, 0, NULL); + cpu_relax(); + } +} + #endif /* CONFIG_SMP */ #ifdef CONFIG_HOTPLUG_CPU diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 512ce1cde2a4..86e65ec3422b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -82,21 +82,6 @@ DEFINE_MUTEX(smp_cpu_state_mutex); /* * Signal processor helper functions. */ -static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status) -{ - register unsigned int reg1 asm ("1") = parm; - int cc; - - asm volatile( - " sigp %1,%2,0(%3)\n" - " ipm %0\n" - " srl %0,28\n" - : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc"); - if (status && cc == 1) - *status = reg1; - return cc; -} - static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status) { int cc; -- GitLab From 3b7df3421f8813ce3b0eedf3d1d9c247c38e3c39 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 7 Apr 2014 10:20:40 +0200 Subject: [PATCH 049/797] s390/mm: print control registers and page table walk on crash Print extra debugging information to the console if the kernel or a user space process crashed (with user space debugging enabled): - contents of control register 7 and 13 - failing address and translation exception identification - page table walk for the failing address Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/mm/fault.c | 140 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 135 insertions(+), 5 deletions(-) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 19f623f1f21c..2f51a998a67e 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -126,6 +126,133 @@ static inline int user_space_fault(struct pt_regs *regs) return 0; } +static int bad_address(void *p) +{ + unsigned long dummy; + + return probe_kernel_address((unsigned long *)p, dummy); +} + +#ifdef CONFIG_64BIT +static void dump_pagetable(unsigned long asce, unsigned long address) +{ + unsigned long *table = __va(asce & PAGE_MASK); + + pr_alert("AS:%016lx ", asce); + switch (asce & _ASCE_TYPE_MASK) { + case _ASCE_TYPE_REGION1: + table = table + ((address >> 53) & 0x7ff); + if (bad_address(table)) + goto bad; + pr_cont("R1:%016lx ", *table); + if (*table & _REGION_ENTRY_INVALID) + goto out; + table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); + /* fallthrough */ + case _ASCE_TYPE_REGION2: + table = table + ((address >> 42) & 0x7ff); + if (bad_address(table)) + goto bad; + pr_cont("R2:%016lx ", *table); + if (*table & _REGION_ENTRY_INVALID) + goto out; + table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); + /* fallthrough */ + case _ASCE_TYPE_REGION3: + table = table + ((address >> 31) & 0x7ff); + if (bad_address(table)) + goto bad; + pr_cont("R3:%016lx ", *table); + if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE)) + goto out; + table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); + /* fallthrough */ + case _ASCE_TYPE_SEGMENT: + table = table + ((address >> 20) & 0x7ff); + if (bad_address(table)) + goto bad; + pr_cont(KERN_CONT "S:%016lx ", *table); + if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE)) + goto out; + table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); + } + table = table + ((address >> 12) & 0xff); + if (bad_address(table)) + goto bad; + pr_cont("P:%016lx ", *table); +out: + pr_cont("\n"); + return; +bad: + pr_cont("BAD\n"); +} + +#else /* CONFIG_64BIT */ + +static void dump_pagetable(unsigned long asce, unsigned long address) +{ + unsigned long *table = __va(asce & PAGE_MASK); + + pr_alert("AS:%08lx ", asce); + table = table + ((address >> 20) & 0x7ff); + if (bad_address(table)) + goto bad; + pr_cont("S:%08lx ", *table); + if (*table & _SEGMENT_ENTRY_INVALID) + goto out; + table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN); + table = table + ((address >> 12) & 0xff); + if (bad_address(table)) + goto bad; + pr_cont("P:%08lx ", *table); +out: + pr_cont("\n"); + return; +bad: + pr_cont("BAD\n"); +} + +#endif /* CONFIG_64BIT */ + +static void dump_fault_info(struct pt_regs *regs) +{ + unsigned long asce; + + pr_alert("Fault in "); + switch (regs->int_parm_long & 3) { + case 3: + pr_cont("home space "); + break; + case 2: + pr_cont("secondary space "); + break; + case 1: + pr_cont("access register "); + break; + case 0: + pr_cont("primary space "); + break; + } + pr_cont("mode while using "); + if (!user_space_fault(regs)) { + asce = S390_lowcore.kernel_asce; + pr_cont("kernel "); + } +#ifdef CONFIG_PGSTE + else if ((current->flags & PF_VCPU) && S390_lowcore.gmap) { + struct gmap *gmap = (struct gmap *)S390_lowcore.gmap; + asce = gmap->asce; + pr_cont("gmap "); + } +#endif + else { + asce = S390_lowcore.user_asce; + pr_cont("user "); + } + pr_cont("ASCE.\n"); + dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK); +} + static inline void report_user_fault(struct pt_regs *regs, long signr) { if ((task_pid_nr(current) > 1) && !show_unhandled_signals) @@ -138,8 +265,9 @@ static inline void report_user_fault(struct pt_regs *regs, long signr) regs->int_code); print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN); printk(KERN_CONT "\n"); - printk(KERN_ALERT "failing address: %lX\n", - regs->int_parm_long & __FAIL_ADDR_MASK); + printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", + regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long); + dump_fault_info(regs); show_regs(regs); } @@ -177,11 +305,13 @@ static noinline void do_no_context(struct pt_regs *regs) address = regs->int_parm_long & __FAIL_ADDR_MASK; if (!user_space_fault(regs)) printk(KERN_ALERT "Unable to handle kernel pointer dereference" - " at virtual kernel address %p\n", (void *)address); + " in virtual kernel address space\n"); else printk(KERN_ALERT "Unable to handle kernel paging request" - " at virtual user address %p\n", (void *)address); - + " in virtual user address space\n"); + printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n", + regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long); + dump_fault_info(regs); die(regs, "Oops"); do_exit(SIGKILL); } -- GitLab From 115b943a6ea12656088fa1ff6634c0d30815e55b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 27 Mar 2014 15:39:20 +0100 Subject: [PATCH 050/797] mac80211: fix software remain-on-channel implementation Jouni reported that when doing off-channel transmissions mixed with on-channel transmissions, the on-channel ones ended up on the off-channel in some cases. The reason for that is that during the refactoring of the off- channel code, I lost the part that stopped all activity and as a consequence the on-channel frames (including data frames) were no longer queued but would be transmitted on the temporary channel. Fix this by simply restoring the lost activity stop call. Cc: stable@vger.kernel.org Fixes: 2eb278e083549 ("mac80211: unify SW/offload remain-on-channel") Reported-by: Jouni Malinen Signed-off-by: Johannes Berg --- net/mac80211/offchannel.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 0c2a29484c07..6fb38558a5e6 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -355,6 +355,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) struct ieee80211_roc_work *dep; /* start this ROC */ + ieee80211_offchannel_stop_vifs(local); /* switch channel etc */ ieee80211_recalc_idle(local); -- GitLab From 7b8a9cdd1f959c7166611fcc58ac91e8409c10ab Mon Sep 17 00:00:00 2001 From: Ido Yariv Date: Mon, 24 Mar 2014 09:55:45 +0200 Subject: [PATCH 051/797] mac80211: Disable SMPS for the monitor interface All antennas should be operational when monitoring to maximize reception. Signed-off-by: Ido Yariv Signed-off-by: Johannes Berg --- net/mac80211/chan.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index bd1fd8ea5105..68bee813dfad 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -492,6 +492,13 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, rx_chains_static = max(rx_chains_static, needed_static); rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); } + + /* Disable SMPS for the monitor interface */ + sdata = rcu_dereference(local->monitor_sdata); + if (sdata && + rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf) + rx_chains_dynamic = rx_chains_static = local->rx_chains; + rcu_read_unlock(); if (!local->use_chanctx) { -- GitLab From 9b4816f543ee8d48bb49151718edac480d2080b1 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 4 Apr 2014 13:02:43 +0200 Subject: [PATCH 052/797] mac80211: fix radar_enabled propagation If chandef had non-HT width it was possible for radar_enabled update to not be propagated properly through drv_config(). This happened because ieee80211_hw_conf_chan() would never see different local->hw.conf.chandef and local->_oper_chandef. This wasn't a problem with HT chandefs because _oper_chandef width is reset to non-HT in ieee80211_free_chanctx() making ieee80211_hw_conf_chan() to kick in. This problem led (at least) ath10k to not start CAC if prior CAC was cancelled and both CACs were requested for identical non-HT chandefs. Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/mac80211/chan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 68bee813dfad..75b5dd2c9267 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -249,7 +249,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, if (!local->use_chanctx) { local->_oper_chandef = *chandef; - ieee80211_hw_config(local, 0); + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); } else { err = drv_add_chanctx(local, ctx); if (err) { @@ -286,7 +286,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, check_single_channel = true; local->hw.conf.radar_enabled = false; - ieee80211_hw_config(local, 0); + ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); } else { drv_remove_chanctx(local, ctx); } -- GitLab From 00a9a6d1e2f18c193d28409bfafc890d78adef68 Mon Sep 17 00:00:00 2001 From: Chun-Yeow Yeoh Date: Wed, 2 Apr 2014 12:05:09 +0800 Subject: [PATCH 053/797] mac80211: update last_tx_rate only for data frame Rate controller in firmware may also return the Tx Rate used for management frame that is usually sent as lowest Tx Rate (1Mbps in 2.4GHz). So update the last_tx_rate only if it is data frame. This patch is tested with ath9k_htc. Signed-off-by: Chun-Yeow Yeoh Signed-off-by: Johannes Berg --- net/mac80211/status.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/mac80211/status.c b/net/mac80211/status.c index e6e574a307c8..00ba90b02ab2 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -618,6 +618,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) sta, true, acked); if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && + (ieee80211_is_data(hdr->frame_control)) && (rates_idx != -1)) sta->last_tx_rate = info->status.rates[rates_idx]; -- GitLab From 004f388559a89ac17fa4c81fb8559a6599050a4e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 7 Apr 2014 23:25:20 +0200 Subject: [PATCH 054/797] drm/mm: Don't WARN if drm_mm_reserve_node Jesse's BIOS fb reconstruction code actually relies on the -ENOSPC return value to detect overlapping framebuffers (which the bios uses always when lighting up more than one screen). All this fanciness happens in intel_alloc_plane_obj in intel_display.c. Since no one else uses this we can safely remove the WARN without repercussions. Reported-by: Ben Widawsky Tested-by: Ben Widawsky Cc: Jesse Barnes Cc: Dave Airlie Signed-off-by: Daniel Vetter Acked-by: Dave Airlie Signed-off-by: Jani Nikula --- drivers/gpu/drm/drm_mm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 71e2d3fcd6ee..04a209e2b66d 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -207,8 +207,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) return 0; } - WARN(1, "no hole found for node 0x%lx + 0x%lx\n", - node->start, node->size); return -ENOSPC; } EXPORT_SYMBOL(drm_mm_reserve_node); -- GitLab From 2ab1bc9df01dbc19b55b2271100db7407fa6bfdc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 7 Apr 2014 08:54:21 +0200 Subject: [PATCH 055/797] drm/i915: Disable self-refresh for untiled fbs on i915gm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently it doesn't work. X-tiled self-refresh works flawlessly otoh. Apparently X still works correctly with linear framebuffers, so might just be an issue with the initial modeset. It's unclear whether this just borked wm setup from our side or a hw restriction, but just disabling gets things going. Note that this regression was only brought to light with commit 3f2dc5ac05714711fc14f2bf0ee5e42d5c08c581 Author: Ville Syrjälä Date: Fri Jan 10 14:06:47 2014 +0200 drm/i915: Fix 915GM self-refresh enable/disable before that self-refresh for i915GM didn't work at all. Kudos to Ville for spotting a little bug in the original patch I've attached to the bug. Cc: Ville Syrjälä Cc: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76103 Tested-by: Krzysztof Mazur Cc: Krzysztof Mazur Cc: stable@vger.kernel.org Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter [Jani: rebase on top of drm-next with primary plane support.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_pm.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 5874716774a7..19e94c3edc19 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1545,6 +1545,16 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc) DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm); + if (IS_I915GM(dev) && enabled) { + struct intel_framebuffer *fb; + + fb = to_intel_framebuffer(enabled->primary->fb); + + /* self-refresh seems busted with untiled */ + if (fb->obj->tiling_mode == I915_TILING_NONE) + enabled = NULL; + } + /* * Overlay gets an aggressive default since video jitter is bad. */ -- GitLab From 390403fd79821bbd0c3a0d83307df2be87047b36 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Thu, 10 Apr 2014 11:01:09 -0700 Subject: [PATCH 056/797] ARM: OMAP3: PM: remove access to PRM_VOLTCTRL register There is a solitary write to this register every wakeup from off-mode, which isn't doing anything, so remove it. Also note that modifying this register trashes any attempted voltage scaling configuration and the change probably should never have gotten merged in the first place. Cc: Nishanth Menon Cc: Kevin Hilman Cc: Paul Walmsley Signed-off-by: Tero Kristo [tony@atomide.com: updated comments to describe regression] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/pm34xx.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 1f3770a8a728..87099bb6de69 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -330,10 +330,6 @@ void omap_sram_idle(void) omap3_sram_restore_context(); omap2_sms_restore_context(); } - if (core_next_state == PWRDM_POWER_OFF) - omap2_prm_clear_mod_reg_bits(OMAP3430_AUTO_OFF_MASK, - OMAP3430_GR_MOD, - OMAP3_PRM_VOLTCTRL_OFFSET); } omap3_intc_resume_idle(); -- GitLab From bf3f043e7bc2581475040348580f4acc786842e7 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 18 Feb 2014 16:09:02 +0100 Subject: [PATCH 057/797] IB/qib: Use pci_enable_msix_range() instead of pci_enable_msix() As result of the deprecation of the MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block(), all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() and pci_enable_msix_range() interfaces. Signed-off-by: Alexander Gordeev Acked-by: Mike Marciniszyn Signed-off-by: Roland Dreier --- drivers/infiniband/hw/qib/qib_pcie.c | 55 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c index c8d9c4ab142b..61a0046efb76 100644 --- a/drivers/infiniband/hw/qib/qib_pcie.c +++ b/drivers/infiniband/hw/qib/qib_pcie.c @@ -197,46 +197,47 @@ static void qib_msix_setup(struct qib_devdata *dd, int pos, u32 *msixcnt, struct qib_msix_entry *qib_msix_entry) { int ret; - u32 tabsize = 0; - u16 msix_flags; + int nvec = *msixcnt; struct msix_entry *msix_entry; int i; + ret = pci_msix_vec_count(dd->pcidev); + if (ret < 0) + goto do_intx; + + nvec = min(nvec, ret); + /* We can't pass qib_msix_entry array to qib_msix_setup * so use a dummy msix_entry array and copy the allocated * irq back to the qib_msix_entry array. */ - msix_entry = kmalloc(*msixcnt * sizeof(*msix_entry), GFP_KERNEL); - if (!msix_entry) { - ret = -ENOMEM; + msix_entry = kmalloc(nvec * sizeof(*msix_entry), GFP_KERNEL); + if (!msix_entry) goto do_intx; - } - for (i = 0; i < *msixcnt; i++) + + for (i = 0; i < nvec; i++) msix_entry[i] = qib_msix_entry[i].msix; - pci_read_config_word(dd->pcidev, pos + PCI_MSIX_FLAGS, &msix_flags); - tabsize = 1 + (msix_flags & PCI_MSIX_FLAGS_QSIZE); - if (tabsize > *msixcnt) - tabsize = *msixcnt; - ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize); - if (ret > 0) { - tabsize = ret; - ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize); - } -do_intx: - if (ret) { - qib_dev_err(dd, - "pci_enable_msix %d vectors failed: %d, falling back to INTx\n", - tabsize, ret); - tabsize = 0; - } - for (i = 0; i < tabsize; i++) + ret = pci_enable_msix_range(dd->pcidev, msix_entry, 1, nvec); + if (ret < 0) + goto free_msix_entry; + else + nvec = ret; + + for (i = 0; i < nvec; i++) qib_msix_entry[i].msix = msix_entry[i]; + kfree(msix_entry); - *msixcnt = tabsize; + *msixcnt = nvec; + return; - if (ret) - qib_enable_intx(dd->pcidev); +free_msix_entry: + kfree(msix_entry); +do_intx: + qib_dev_err(dd, "pci_enable_msix_range %d vectors failed: %d, " + "falling back to INTx\n", nvec, ret); + *msixcnt = 0; + qib_enable_intx(dd->pcidev); } /** -- GitLab From 9684c2ea6d1f5aab44119533530e4059b4c3e1ff Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Sun, 23 Feb 2014 07:57:05 +0100 Subject: [PATCH 058/797] IB/mthca: Use pci_enable_msix_exact() instead of pci_enable_msix() As result of the deprecation of the MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block(), all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces. Signed-off-by: Alexander Gordeev Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mthca/mthca_main.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 87897b95666d..ded76c101dde 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c @@ -858,13 +858,9 @@ static int mthca_enable_msi_x(struct mthca_dev *mdev) entries[1].entry = 1; entries[2].entry = 2; - err = pci_enable_msix(mdev->pdev, entries, ARRAY_SIZE(entries)); - if (err) { - if (err > 0) - mthca_info(mdev, "Only %d MSI-X vectors available, " - "not using MSI-X\n", err); + err = pci_enable_msix_exact(mdev->pdev, entries, ARRAY_SIZE(entries)); + if (err) return err; - } mdev->eq_table.eq[MTHCA_EQ_COMP ].msi_x_vector = entries[0].vector; mdev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector = entries[1].vector; -- GitLab From f360d88a2efddf2d2a2d01a8ac76fded34d624b4 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Wed, 2 Apr 2014 00:10:16 +0300 Subject: [PATCH 059/797] IB/mlx5: Add block multicast loopback support Add support for the block multicast loopback QP creation flag along the proper firmware API for that. Signed-off-by: Eli Cohen Signed-off-by: Or Gerlitz Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx5/main.c | 2 ++ drivers/infiniband/hw/mlx5/qp.c | 12 ++++++++++++ include/linux/mlx5/device.h | 1 + include/linux/mlx5/qp.h | 1 + 4 files changed, 16 insertions(+) diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index fa6dc870adae..364d4b6937f5 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -282,6 +282,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev, props->sig_guard_cap = IB_GUARD_T10DIF_CRC | IB_GUARD_T10DIF_CSUM; } + if (flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST) + props->device_cap_flags |= IB_DEVICE_BLOCK_MULTICAST_LOOPBACK; props->vendor_id = be32_to_cpup((__be32 *)(out_mad->data + 36)) & 0xffffff; diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index ae788d27b93f..dc930ed21eca 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -807,6 +807,15 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, spin_lock_init(&qp->sq.lock); spin_lock_init(&qp->rq.lock); + if (init_attr->create_flags & IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK) { + if (!(dev->mdev.caps.flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)) { + mlx5_ib_dbg(dev, "block multicast loopback isn't supported\n"); + return -EINVAL; + } else { + qp->flags |= MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK; + } + } + if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR) qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE; @@ -878,6 +887,9 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd, if (qp->wq_sig) in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_ENABLE_SIG); + if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK) + in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_BLOCK_MCAST); + if (qp->scat_cqe && is_connected(init_attr->qp_type)) { int rcqe_sz; int scqe_sz; diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h index 407bdb67fd4f..3406cfb1267a 100644 --- a/include/linux/mlx5/device.h +++ b/include/linux/mlx5/device.h @@ -179,6 +179,7 @@ enum { MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1LL << 9, MLX5_DEV_CAP_FLAG_APM = 1LL << 17, MLX5_DEV_CAP_FLAG_ATOMIC = 1LL << 18, + MLX5_DEV_CAP_FLAG_BLOCK_MCAST = 1LL << 23, MLX5_DEV_CAP_FLAG_ON_DMND_PG = 1LL << 24, MLX5_DEV_CAP_FLAG_CQ_MODER = 1LL << 29, MLX5_DEV_CAP_FLAG_RESIZE_CQ = 1LL << 30, diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h index f829ad80ff28..9709b30e2d69 100644 --- a/include/linux/mlx5/qp.h +++ b/include/linux/mlx5/qp.h @@ -146,6 +146,7 @@ enum { enum { MLX5_QP_LAT_SENSITIVE = 1 << 28, + MLX5_QP_BLOCK_MCAST = 1 << 30, MLX5_QP_ENABLE_SIG = 1 << 31, }; -- GitLab From 1ce01c4a199c50b023802be25261c0c02b2f0214 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Thu, 10 Apr 2014 22:58:20 -0400 Subject: [PATCH 060/797] ext4: fix COLLAPSE_RANGE test failure in data journalling mode When mounting ext4 with data=journal option, xfstest shared/002 and shared/004 are currently failing as checksum computed for testfile does not match with the checksum computed in other journal modes. In case of data=journal mode, a call to filemap_write_and_wait_range will not flush anything to disk as buffers are not marked dirty in write_end. In collapse range this call is followed by a call to truncate_pagecache_range. Due to this, when checksum is computed, a portion of file is re-read from disk which replace valid data with NULL bytes and hence the reason for the difference in checksum. Calling ext4_force_commit before filemap_write_and_wait_range solves the issue as it will mark the buffers dirty during commit transaction which can be later synced by a call to filemap_write_and_wait_range. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 82df3ce9874a..be1e56cbbf32 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5383,6 +5383,13 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) punch_start = offset >> EXT4_BLOCK_SIZE_BITS(sb); punch_stop = (offset + len) >> EXT4_BLOCK_SIZE_BITS(sb); + /* Call ext4_force_commit to flush all data in case of data=journal. */ + if (ext4_should_journal_data(inode)) { + ret = ext4_force_commit(inode->i_sb); + if (ret) + return ret; + } + /* Write out all dirty pages */ ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1); if (ret) -- GitLab From c57ab39b9658315a742b6e61fdc86bb4d20cf566 Mon Sep 17 00:00:00 2001 From: Younger Liu Date: Thu, 10 Apr 2014 23:03:43 -0400 Subject: [PATCH 061/797] ext4: return ENOMEM rather than EIO when find_###_page() fails Return ENOMEM rather than EIO when find_get_page() fails in ext4_mb_get_buddy_page_lock() and find_or_create_page() fails in ext4_mb_load_buddy(). Signed-off-by: Younger Liu Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index a888cac76e9c..73ccbb3b973b 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -989,7 +989,7 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb, poff = block % blocks_per_page; page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); if (!page) - return -EIO; + return -ENOMEM; BUG_ON(page->mapping != inode->i_mapping); e4b->bd_bitmap_page = page; e4b->bd_bitmap = page_address(page) + (poff * sb->s_blocksize); @@ -1003,7 +1003,7 @@ static int ext4_mb_get_buddy_page_lock(struct super_block *sb, pnum = block / blocks_per_page; page = find_or_create_page(inode->i_mapping, pnum, GFP_NOFS); if (!page) - return -EIO; + return -ENOMEM; BUG_ON(page->mapping != inode->i_mapping); e4b->bd_buddy_page = page; return 0; @@ -1168,7 +1168,11 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, unlock_page(page); } } - if (page == NULL || !PageUptodate(page)) { + if (page == NULL) { + ret = -ENOMEM; + goto err; + } + if (!PageUptodate(page)) { ret = -EIO; goto err; } @@ -1197,7 +1201,11 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group, unlock_page(page); } } - if (page == NULL || !PageUptodate(page)) { + if (page == NULL) { + ret = -ENOMEM; + goto err; + } + if (!PageUptodate(page)) { ret = -EIO; goto err; } -- GitLab From eb4a5346e777784f1b5ae9fd0c29b96344bdc3ae Mon Sep 17 00:00:00 2001 From: Matt Porter Date: Thu, 10 Apr 2014 15:22:10 -0400 Subject: [PATCH 062/797] hwrng: bcm2835 - fix oops when rng h/w is accessed during registration Commit "d9e7972 hwrng: add randomness to system from rng sources" exposed a bug in the bcm2835-rng driver resulting in boot failure on Raspberry Pi due to the following oops: [ 28.261523] BUG: soft lockup - CPU#0 stuck for 23s! [swapper:1] [ 28.271058] [ 28.275958] CPU: 0 PID: 1 Comm: swapper Not tainted 3.14.0+ #11 [ 28.285374] task: db480000 ti: db484000 task.ti: db484000 [ 28.294279] PC is at bcm2835_rng_read+0x28/0x48 [ 28.302276] LR is at hwrng_register+0x1a8/0x238 . . . The RNG h/w is not completely initialized and enabled before hwrng_register() is called and so the bcm2835_rng_read() fails. Fix this by making the warmup/enable writes before registering the RNG source with the hwrng core. Signed-off-by: Matt Porter Signed-off-by: Herbert Xu --- drivers/char/hw_random/bcm2835-rng.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/char/hw_random/bcm2835-rng.c b/drivers/char/hw_random/bcm2835-rng.c index 8c3b255e629a..e900961cdd2e 100644 --- a/drivers/char/hw_random/bcm2835-rng.c +++ b/drivers/char/hw_random/bcm2835-rng.c @@ -61,18 +61,18 @@ static int bcm2835_rng_probe(struct platform_device *pdev) } bcm2835_rng_ops.priv = (unsigned long)rng_base; + /* set warm-up count & enable */ + __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS); + __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL); + /* register driver */ err = hwrng_register(&bcm2835_rng_ops); if (err) { dev_err(dev, "hwrng registration failed\n"); iounmap(rng_base); - } else { + } else dev_info(dev, "hwrng registered\n"); - /* set warm-up count & enable */ - __raw_writel(RNG_WARMUP_COUNT, rng_base + RNG_STATUS); - __raw_writel(RNG_RBGEN, rng_base + RNG_CTRL); - } return err; } -- GitLab From 990baec022ccb97b6bb4185624f4fe7cd6150333 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 9 Apr 2014 00:08:01 +0200 Subject: [PATCH 063/797] mac80211: suppress BSS info change notifications for AP_VLAN Fixes warnings on tx power changes Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index b055f6a55c68..4172d4253197 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -199,7 +199,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; - if (!changed) + if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN) return; drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); -- GitLab From 764152ff66f4a8be1f9d7981e542ffdaa5bd7aff Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 10 Apr 2014 15:06:48 +0200 Subject: [PATCH 064/797] mac80211: exclude AP_VLAN interfaces from tx power calculation Their power value is initialized to zero. This patch fixes an issue where the configured power drops to the minimum value when AP_VLAN interfaces are created/removed. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Signed-off-by: Johannes Berg --- net/mac80211/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 4172d4253197..4c1bf61bc778 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -148,6 +148,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!rcu_access_pointer(sdata->vif.chanctx_conf)) continue; + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + continue; power = min(power, sdata->vif.bss_conf.txpower); } rcu_read_unlock(); -- GitLab From 60e69eed85bb7b5198ef70643b5895c26ad76ef7 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Mon, 7 Apr 2014 10:55:15 +0200 Subject: [PATCH 065/797] sched/numa: Fix task_numa_free() lockdep splat Sasha reported that lockdep claims that the following commit: made numa_group.lock interrupt unsafe: 156654f491dd ("sched/numa: Move task_numa_free() to __put_task_struct()") While I don't see how that could be, given the commit in question moved task_numa_free() from one irq enabled region to another, the below does make both gripes and lockups upon gripe with numa=fake=4 go away. Reported-by: Sasha Levin Fixes: 156654f491dd ("sched/numa: Move task_numa_free() to __put_task_struct()") Signed-off-by: Mike Galbraith Signed-off-by: Peter Zijlstra Cc: torvalds@linux-foundation.org Cc: mgorman@suse.com Cc: akpm@linux-foundation.org Cc: Dave Jones Link: http://lkml.kernel.org/r/1396860915.5170.5.camel@marge.simpson.net Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 13 +++++++------ kernel/sched/sched.h | 9 +++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 7e9bd0b1fa9e..4f14a656a720 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1497,7 +1497,7 @@ static void task_numa_placement(struct task_struct *p) /* If the task is part of a group prevent parallel updates to group stats */ if (p->numa_group) { group_lock = &p->numa_group->lock; - spin_lock(group_lock); + spin_lock_irq(group_lock); } /* Find the node with the highest number of faults */ @@ -1572,7 +1572,7 @@ static void task_numa_placement(struct task_struct *p) } } - spin_unlock(group_lock); + spin_unlock_irq(group_lock); } /* Preferred node as the node with the most faults */ @@ -1677,7 +1677,8 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags, if (!join) return; - double_lock(&my_grp->lock, &grp->lock); + BUG_ON(irqs_disabled()); + double_lock_irq(&my_grp->lock, &grp->lock); for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) { my_grp->faults[i] -= p->numa_faults_memory[i]; @@ -1691,7 +1692,7 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags, grp->nr_tasks++; spin_unlock(&my_grp->lock); - spin_unlock(&grp->lock); + spin_unlock_irq(&grp->lock); rcu_assign_pointer(p->numa_group, grp); @@ -1710,14 +1711,14 @@ void task_numa_free(struct task_struct *p) void *numa_faults = p->numa_faults_memory; if (grp) { - spin_lock(&grp->lock); + spin_lock_irq(&grp->lock); for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) grp->faults[i] -= p->numa_faults_memory[i]; grp->total_faults -= p->total_numa_faults; list_del(&p->numa_entry); grp->nr_tasks--; - spin_unlock(&grp->lock); + spin_unlock_irq(&grp->lock); rcu_assign_pointer(p->numa_group, NULL); put_numa_group(grp); } diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index c9007f28d3a2..456e492a3dca 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1385,6 +1385,15 @@ static inline void double_lock(spinlock_t *l1, spinlock_t *l2) spin_lock_nested(l2, SINGLE_DEPTH_NESTING); } +static inline void double_lock_irq(spinlock_t *l1, spinlock_t *l2) +{ + if (l1 > l2) + swap(l1, l2); + + spin_lock_irq(l1); + spin_lock_nested(l2, SINGLE_DEPTH_NESTING); +} + static inline void double_raw_lock(raw_spinlock_t *l1, raw_spinlock_t *l2) { if (l1 > l2) -- GitLab From a227960fe0cafcc229a8d6bb8b454a3a0b33719d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 10 Apr 2014 16:15:59 +0200 Subject: [PATCH 066/797] locking/mutex: Fix debug_mutexes debug_mutex_unlock() would bail when !debug_locks and forgets to actually unlock. Reported-by: "Michael L. Semon" Reported-by: "Kirill A. Shutemov" Reported-by: Valdis Kletnieks Fixes: 6f008e72cd11 ("locking/mutex: Fix debug checks") Tested-by: Dave Jones Cc: Jason Low Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140410141559.GE13658@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- kernel/locking/mutex-debug.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c index e1191c996c59..5cf6731b98e9 100644 --- a/kernel/locking/mutex-debug.c +++ b/kernel/locking/mutex-debug.c @@ -71,18 +71,17 @@ void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, void debug_mutex_unlock(struct mutex *lock) { - if (unlikely(!debug_locks)) - return; + if (likely(debug_locks)) { + DEBUG_LOCKS_WARN_ON(lock->magic != lock); - DEBUG_LOCKS_WARN_ON(lock->magic != lock); + if (!lock->owner) + DEBUG_LOCKS_WARN_ON(!lock->owner); + else + DEBUG_LOCKS_WARN_ON(lock->owner != current); - if (!lock->owner) - DEBUG_LOCKS_WARN_ON(!lock->owner); - else - DEBUG_LOCKS_WARN_ON(lock->owner != current); - - DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); - mutex_clear_owner(lock); + DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); + mutex_clear_owner(lock); + } /* * __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug -- GitLab From 39fbc9c8f6765959b55e0b127dd5c57df5a47d67 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 9 Apr 2014 11:22:06 +0300 Subject: [PATCH 067/797] drm/i915: check VBT for supported backlight type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The only supported types are none and PWM. Other values are obsolete or reserved, don't add them. Tested-by: Kamal Mostafa Tested-by: Martin Tested-by: jrg.otte@gmail.com Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_bios.c | 10 ++++++++++ drivers/gpu/drm/i915/intel_bios.h | 3 +++ 3 files changed, 14 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0905cd915589..d24eba70ca9f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1308,6 +1308,7 @@ struct intel_vbt_data { struct { u16 pwm_freq_hz; + bool present; bool active_low_pwm; } backlight; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4867f4cc0938..fa486c5fbb02 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -287,6 +287,9 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) const struct bdb_lfp_backlight_data *backlight_data; const struct bdb_lfp_backlight_data_entry *entry; + /* Err to enabling backlight if no backlight block. */ + dev_priv->vbt.backlight.present = true; + backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT); if (!backlight_data) return; @@ -299,6 +302,13 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb) entry = &backlight_data->data[panel_type]; + dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM; + if (!dev_priv->vbt.backlight.present) { + DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n", + entry->type); + return; + } + dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm; DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, " diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index 83b7629e4367..f27f7b282465 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -374,6 +374,9 @@ struct bdb_lvds_lfp_data { struct bdb_lvds_lfp_data_entry data[16]; } __packed; +#define BDB_BACKLIGHT_TYPE_NONE 0 +#define BDB_BACKLIGHT_TYPE_PWM 2 + struct bdb_lfp_backlight_data_entry { u8 type:2; u8 active_low_pwm:1; -- GitLab From c675949ec58ca50d5a3ae3c757892f1560f6e896 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 9 Apr 2014 11:31:37 +0300 Subject: [PATCH 068/797] drm/i915: do not setup backlight if not available according to VBT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some machines use an external EC for controlling the backlight. Info about this is present in the VBT. Do not setup native backlight control if no PWM backlight is available or supported according to VBT. The acpi_backlight interface appears to work for the EC control. In most cases there has been no harm done, but it looks like there are machines out there that have both an EC and our PWM line connected to the same wire. This, obviously, does not end well. This should fix the regression caused by commit bc0bb9fd1c7810407ab810d204bbaecb255fddde Author: Jani Nikula Date: Thu Nov 14 12:14:29 2013 +0200 drm/i915: remove QUIRK_NO_PCH_PWM_ENABLE AFAICT the quirk removed by the above commit effectively resulted in i915 not driving the backlight PWM output, thus not messing things up. Additionally this should fix the regression caused by commit fbc9fe1b4f222a7c575e3bd8e9defe59c6190a04 Author: Aaron Lu Date: Fri Oct 11 21:27:45 2013 +0800 ACPI / video: Do not register backlight if win8 and native interface exists which left some machines without a functioning backlight interface. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76276 Reference: https://bugzilla.kernel.org/show_bug.cgi?id=47941 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=62281 CC: Aaron Lu CC: Eric Griffith CC: Kent Baxley Tested-by: Kamal Mostafa Tested-by: Martin Tested-by: jrg.otte@gmail.com Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_panel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index cb058408c70e..0eead16aeda7 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -1065,6 +1065,11 @@ int intel_panel_setup_backlight(struct drm_connector *connector) unsigned long flags; int ret; + if (!dev_priv->vbt.backlight.present) { + DRM_DEBUG_KMS("native backlight control not available per VBT\n"); + return 0; + } + /* set level and max in panel struct */ spin_lock_irqsave(&dev_priv->backlight_lock, flags); ret = dev_priv->display.setup_backlight(intel_connector); -- GitLab From 691e6415c891b8b2b082a120b896b443531c4d45 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 9 Apr 2014 09:07:36 +0100 Subject: [PATCH 069/797] drm/i915: Always use kref tracking for all contexts. If we always initialize kref for the context, even if we are using fake contexts for hangstats when there is no hw support, we can forgo the dance to dereference the ctx->obj and inspect whether we are permitted to use kref inside i915_gem_context_reference() and _unreference(). My ulterior motive here is to improve the debugging of a use-after-free of ctx->obj. This patch avoids the dereference here and instead forces the assertion checks associated with kref. v2: Refactor the fake contexts to being even more like the real contexts, so that there is much less duplicated and special case code. v3: Tweaks. v4: Tweaks, minor. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76671 Signed-off-by: Chris Wilson Tested-by: lu hua Cc: Ben Widawsky Cc: Mika Kuoppala Reviewed-by: Ben Widawsky [Jani: tiny change to backport to drm-intel-fixes.] Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_drv.h | 8 +- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_gem_context.c | 218 +++++++++------------ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- 4 files changed, 93 insertions(+), 137 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d24eba70ca9f..ec82f6bff122 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2432,20 +2432,18 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file); int i915_gem_context_enable(struct drm_i915_private *dev_priv); void i915_gem_context_close(struct drm_device *dev, struct drm_file *file); int i915_switch_context(struct intel_ring_buffer *ring, - struct drm_file *file, struct i915_hw_context *to); + struct i915_hw_context *to); struct i915_hw_context * i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); void i915_gem_context_free(struct kref *ctx_ref); static inline void i915_gem_context_reference(struct i915_hw_context *ctx) { - if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev)) - kref_get(&ctx->ref); + kref_get(&ctx->ref); } static inline void i915_gem_context_unreference(struct i915_hw_context *ctx) { - if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev)) - kref_put(&ctx->ref, i915_gem_context_free); + kref_put(&ctx->ref, i915_gem_context_free); } static inline bool i915_gem_context_is_default(const struct i915_hw_context *c) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6370a761d137..2871ce75f438 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2790,7 +2790,7 @@ int i915_gpu_idle(struct drm_device *dev) /* Flush everything onto the inactive list. */ for_each_ring(ring, dev_priv, i) { - ret = i915_switch_context(ring, NULL, ring->default_context); + ret = i915_switch_context(ring, ring->default_context); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 6043062ffce7..d72db15afa02 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -96,9 +96,6 @@ #define GEN6_CONTEXT_ALIGN (64<<10) #define GEN7_CONTEXT_ALIGN 4096 -static int do_switch(struct intel_ring_buffer *ring, - struct i915_hw_context *to); - static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) { struct drm_device *dev = ppgtt->base.dev; @@ -185,13 +182,15 @@ void i915_gem_context_free(struct kref *ctx_ref) typeof(*ctx), ref); struct i915_hw_ppgtt *ppgtt = NULL; - /* We refcount even the aliasing PPGTT to keep the code symmetric */ - if (USES_PPGTT(ctx->obj->base.dev)) - ppgtt = ctx_to_ppgtt(ctx); + if (ctx->obj) { + /* We refcount even the aliasing PPGTT to keep the code symmetric */ + if (USES_PPGTT(ctx->obj->base.dev)) + ppgtt = ctx_to_ppgtt(ctx); - /* XXX: Free up the object before tearing down the address space, in - * case we're bound in the PPGTT */ - drm_gem_object_unreference(&ctx->obj->base); + /* XXX: Free up the object before tearing down the address space, in + * case we're bound in the PPGTT */ + drm_gem_object_unreference(&ctx->obj->base); + } if (ppgtt) kref_put(&ppgtt->ref, ppgtt_release); @@ -232,32 +231,32 @@ __create_hw_context(struct drm_device *dev, return ERR_PTR(-ENOMEM); kref_init(&ctx->ref); - ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); - INIT_LIST_HEAD(&ctx->link); - if (ctx->obj == NULL) { - kfree(ctx); - DRM_DEBUG_DRIVER("Context object allocated failed\n"); - return ERR_PTR(-ENOMEM); - } + list_add_tail(&ctx->link, &dev_priv->context_list); - if (INTEL_INFO(dev)->gen >= 7) { - ret = i915_gem_object_set_cache_level(ctx->obj, - I915_CACHE_L3_LLC); - /* Failure shouldn't ever happen this early */ - if (WARN_ON(ret)) + if (dev_priv->hw_context_size) { + ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); + if (ctx->obj == NULL) { + ret = -ENOMEM; goto err_out; - } + } - list_add_tail(&ctx->link, &dev_priv->context_list); + if (INTEL_INFO(dev)->gen >= 7) { + ret = i915_gem_object_set_cache_level(ctx->obj, + I915_CACHE_L3_LLC); + /* Failure shouldn't ever happen this early */ + if (WARN_ON(ret)) + goto err_out; + } + } /* Default context will never have a file_priv */ - if (file_priv == NULL) - return ctx; - - ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0, - GFP_KERNEL); - if (ret < 0) - goto err_out; + if (file_priv != NULL) { + ret = idr_alloc(&file_priv->context_idr, ctx, + DEFAULT_CONTEXT_ID, 0, GFP_KERNEL); + if (ret < 0) + goto err_out; + } else + ret = DEFAULT_CONTEXT_ID; ctx->file_priv = file_priv; ctx->id = ret; @@ -294,7 +293,7 @@ i915_gem_create_context(struct drm_device *dev, if (IS_ERR(ctx)) return ctx; - if (is_global_default_ctx) { + if (is_global_default_ctx && ctx->obj) { /* We may need to do things with the shrinker which * require us to immediately switch back to the default * context. This can cause a problem as pinning the @@ -342,7 +341,7 @@ i915_gem_create_context(struct drm_device *dev, return ctx; err_unpin: - if (is_global_default_ctx) + if (is_global_default_ctx && ctx->obj) i915_gem_object_ggtt_unpin(ctx->obj); err_destroy: i915_gem_context_unreference(ctx); @@ -352,32 +351,22 @@ i915_gem_create_context(struct drm_device *dev, void i915_gem_context_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; int i; - if (!HAS_HW_CONTEXTS(dev)) - return; - /* Prevent the hardware from restoring the last context (which hung) on * the next switch */ for (i = 0; i < I915_NUM_RINGS; i++) { - struct i915_hw_context *dctx; - if (!(INTEL_INFO(dev)->ring_mask & (1<ring[i]; + struct i915_hw_context *dctx = ring->default_context; /* Do a fake switch to the default context */ - ring = &dev_priv->ring[i]; - dctx = ring->default_context; - if (WARN_ON(!dctx)) + if (ring->last_context == dctx) continue; if (!ring->last_context) continue; - if (ring->last_context == dctx) - continue; - - if (i == RCS) { + if (dctx->obj && i == RCS) { WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj, get_context_alignment(dev), 0)); /* Fake a finish/inactive */ @@ -394,44 +383,35 @@ void i915_gem_context_reset(struct drm_device *dev) int i915_gem_context_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_ring_buffer *ring; + struct i915_hw_context *ctx; int i; - if (!HAS_HW_CONTEXTS(dev)) - return 0; - /* Init should only be called once per module load. Eventually the * restriction on the context_disabled check can be loosened. */ if (WARN_ON(dev_priv->ring[RCS].default_context)) return 0; - dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); - - if (dev_priv->hw_context_size > (1<<20)) { - DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n"); - return -E2BIG; + if (HAS_HW_CONTEXTS(dev)) { + dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); + if (dev_priv->hw_context_size > (1<<20)) { + DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n", + dev_priv->hw_context_size); + dev_priv->hw_context_size = 0; + } } - dev_priv->ring[RCS].default_context = - i915_gem_create_context(dev, NULL, USES_PPGTT(dev)); - - if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) { - DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n", - PTR_ERR(dev_priv->ring[RCS].default_context)); - return PTR_ERR(dev_priv->ring[RCS].default_context); + ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev)); + if (IS_ERR(ctx)) { + DRM_ERROR("Failed to create default global context (error %ld)\n", + PTR_ERR(ctx)); + return PTR_ERR(ctx); } - for (i = RCS + 1; i < I915_NUM_RINGS; i++) { - if (!(INTEL_INFO(dev)->ring_mask & (1<ring[i]; + /* NB: RCS will hold a ref for all rings */ + for (i = 0; i < I915_NUM_RINGS; i++) + dev_priv->ring[i].default_context = ctx; - /* NB: RCS will hold a ref for all rings */ - ring->default_context = dev_priv->ring[RCS].default_context; - } - - DRM_DEBUG_DRIVER("HW context support initialized\n"); + DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake"); return 0; } @@ -441,33 +421,30 @@ void i915_gem_context_fini(struct drm_device *dev) struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context; int i; - if (!HAS_HW_CONTEXTS(dev)) - return; - - /* The only known way to stop the gpu from accessing the hw context is - * to reset it. Do this as the very last operation to avoid confusing - * other code, leading to spurious errors. */ - intel_gpu_reset(dev); - - /* When default context is created and switched to, base object refcount - * will be 2 (+1 from object creation and +1 from do_switch()). - * i915_gem_context_fini() will be called after gpu_idle() has switched - * to default context. So we need to unreference the base object once - * to offset the do_switch part, so that i915_gem_context_unreference() - * can then free the base object correctly. */ - WARN_ON(!dev_priv->ring[RCS].last_context); - if (dev_priv->ring[RCS].last_context == dctx) { - /* Fake switch to NULL context */ - WARN_ON(dctx->obj->active); - i915_gem_object_ggtt_unpin(dctx->obj); - i915_gem_context_unreference(dctx); - dev_priv->ring[RCS].last_context = NULL; + if (dctx->obj) { + /* The only known way to stop the gpu from accessing the hw context is + * to reset it. Do this as the very last operation to avoid confusing + * other code, leading to spurious errors. */ + intel_gpu_reset(dev); + + /* When default context is created and switched to, base object refcount + * will be 2 (+1 from object creation and +1 from do_switch()). + * i915_gem_context_fini() will be called after gpu_idle() has switched + * to default context. So we need to unreference the base object once + * to offset the do_switch part, so that i915_gem_context_unreference() + * can then free the base object correctly. */ + WARN_ON(!dev_priv->ring[RCS].last_context); + if (dev_priv->ring[RCS].last_context == dctx) { + /* Fake switch to NULL context */ + WARN_ON(dctx->obj->active); + i915_gem_object_ggtt_unpin(dctx->obj); + i915_gem_context_unreference(dctx); + dev_priv->ring[RCS].last_context = NULL; + } } for (i = 0; i < I915_NUM_RINGS; i++) { struct intel_ring_buffer *ring = &dev_priv->ring[i]; - if (!(INTEL_INFO(dev)->ring_mask & (1<last_context) i915_gem_context_unreference(ring->last_context); @@ -478,7 +455,6 @@ void i915_gem_context_fini(struct drm_device *dev) i915_gem_object_ggtt_unpin(dctx->obj); i915_gem_context_unreference(dctx); - dev_priv->mm.aliasing_ppgtt = NULL; } int i915_gem_context_enable(struct drm_i915_private *dev_priv) @@ -486,9 +462,6 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) struct intel_ring_buffer *ring; int ret, i; - if (!HAS_HW_CONTEXTS(dev_priv->dev)) - return 0; - /* This is the only place the aliasing PPGTT gets enabled, which means * it has to happen before we bail on reset */ if (dev_priv->mm.aliasing_ppgtt) { @@ -503,7 +476,7 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) BUG_ON(!dev_priv->ring[RCS].default_context); for_each_ring(ring, dev_priv, i) { - ret = do_switch(ring, ring->default_context); + ret = i915_switch_context(ring, ring->default_context); if (ret) return ret; } @@ -526,19 +499,6 @@ static int context_idr_cleanup(int id, void *p, void *data) int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; - struct drm_i915_private *dev_priv = dev->dev_private; - - if (!HAS_HW_CONTEXTS(dev)) { - /* Cheat for hang stats */ - file_priv->private_default_ctx = - kzalloc(sizeof(struct i915_hw_context), GFP_KERNEL); - - if (file_priv->private_default_ctx == NULL) - return -ENOMEM; - - file_priv->private_default_ctx->vm = &dev_priv->gtt.base; - return 0; - } idr_init(&file_priv->context_idr); @@ -559,14 +519,10 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file) { struct drm_i915_file_private *file_priv = file->driver_priv; - if (!HAS_HW_CONTEXTS(dev)) { - kfree(file_priv->private_default_ctx); - return; - } - idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); - i915_gem_context_unreference(file_priv->private_default_ctx); idr_destroy(&file_priv->context_idr); + + i915_gem_context_unreference(file_priv->private_default_ctx); } struct i915_hw_context * @@ -574,9 +530,6 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id) { struct i915_hw_context *ctx; - if (!HAS_HW_CONTEXTS(file_priv->dev_priv->dev)) - return file_priv->private_default_ctx; - ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id); if (!ctx) return ERR_PTR(-ENOENT); @@ -758,7 +711,6 @@ static int do_switch(struct intel_ring_buffer *ring, /** * i915_switch_context() - perform a GPU context switch. * @ring: ring for which we'll execute the context switch - * @file_priv: file_priv associated with the context, may be NULL * @to: the context to switch to * * The context life cycle is simple. The context refcount is incremented and @@ -767,24 +719,30 @@ static int do_switch(struct intel_ring_buffer *ring, * object while letting the normal object tracking destroy the backing BO. */ int i915_switch_context(struct intel_ring_buffer *ring, - struct drm_file *file, struct i915_hw_context *to) { struct drm_i915_private *dev_priv = ring->dev->dev_private; WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex)); - BUG_ON(file && to == NULL); - - /* We have the fake context */ - if (!HAS_HW_CONTEXTS(ring->dev)) { - ring->last_context = to; + if (to->obj == NULL) { /* We have the fake context */ + if (to != ring->last_context) { + i915_gem_context_reference(to); + if (ring->last_context) + i915_gem_context_unreference(ring->last_context); + ring->last_context = to; + } return 0; } return do_switch(ring, to); } +static bool hw_context_enabled(struct drm_device *dev) +{ + return to_i915(dev)->hw_context_size; +} + int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { @@ -793,7 +751,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct i915_hw_context *ctx; int ret; - if (!HAS_HW_CONTEXTS(dev)) + if (!hw_context_enabled(dev)) return -ENODEV; ret = i915_mutex_lock_interruptible(dev); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 7447160155a3..2c9d9cbaf653 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1221,7 +1221,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret) goto err; - ret = i915_switch_context(ring, file, ctx); + ret = i915_switch_context(ring, ctx); if (ret) goto err; -- GitLab From 79861bbb759053a9b91026becc0915d0f1f8d37d Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 10 Apr 2014 18:16:33 -0700 Subject: [PATCH 070/797] ASoC: rsnd: fix clock prepare/unprepare As with the previous commit, before a clock can be used it must be prepared for use. Change from clk_enable() and clk_disable() to the versions of the calls which also prepare and un-prepare the clocks. Will fix warnings from the clock code when this is used. Signed-off-by: Ben Dooks Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/sh/rcar/src.c | 4 ++-- sound/soc/sh/rcar/ssi.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 6232b7d307aa..4d0720ed5a90 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@ -258,7 +258,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, { struct rsnd_src *src = rsnd_mod_to_src(mod); - clk_enable(src->clk); + clk_prepare_enable(src->clk); return 0; } @@ -269,7 +269,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod, { struct rsnd_src *src = rsnd_mod_to_src(mod); - clk_disable(src->clk); + clk_disable_unprepare(src->clk); return 0; } diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 4b7e20603dd7..1d8387c25bd8 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -171,7 +171,7 @@ static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, u32 cr; if (0 == ssi->usrcnt) { - clk_enable(ssi->clk); + clk_prepare_enable(ssi->clk); if (rsnd_dai_is_clk_master(rdai)) { if (rsnd_ssi_clk_from_parent(ssi)) @@ -230,7 +230,7 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, rsnd_ssi_master_clk_stop(ssi); } - clk_disable(ssi->clk); + clk_disable_unprepare(ssi->clk); } dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); -- GitLab From 9ea806621d97f728e6401dbfaa6f84f9af1b832f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 7 Apr 2014 16:26:37 +0200 Subject: [PATCH 071/797] s390: show_registers() should not map user space addresses to kernel symbols It doesn't make sense to map user space addresses to kernel symbols when show_registers() prints a user space psw. So just skip the translation part if a user space psw is handled. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/dumpstack.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index e6af9406987c..acb412442e5e 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -144,10 +144,10 @@ void show_registers(struct pt_regs *regs) char *mode; mode = user_mode(regs) ? "User" : "Krnl"; - printk("%s PSW : %p %p (%pSR)\n", - mode, (void *) regs->psw.mask, - (void *) regs->psw.addr, - (void *) regs->psw.addr); + printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr); + if (!user_mode(regs)) + printk(" (%pSR)", (void *)regs->psw.addr); + printk("\n"); printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), -- GitLab From a1977d128ab7c6c1be296a8fa39219e330abdb07 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 8 Apr 2014 13:13:38 +0200 Subject: [PATCH 072/797] s390: wire up sys_renameat2 Actually this also enable sys_setattr and sys_getattr, since I forgot to increase NR_syscalls when adding those syscalls. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/uapi/asm/unistd.h | 3 ++- arch/s390/kernel/compat_wrapper.c | 1 + arch/s390/kernel/syscalls.S | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 5eb5c9ddb120..3802d2d3a18d 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h @@ -282,7 +282,8 @@ #define __NR_finit_module 344 #define __NR_sched_setattr 345 #define __NR_sched_getattr 346 -#define NR_syscalls 345 +#define __NR_renameat2 347 +#define NR_syscalls 348 /* * There are some system calls that are not present on 64 bit, some diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index 824c39dfddfc..030051840ccd 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -213,3 +213,4 @@ COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, i COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); +COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags); diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 542ef488bac1..fe5cdf29a001 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S @@ -355,3 +355,4 @@ SYSCALL(sys_kcmp,sys_kcmp,compat_sys_kcmp) SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module) SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */ SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr) +SYSCALL(sys_renameat2,sys_renameat2,compat_sys_renameat2) -- GitLab From a960062e5826b88e75c3999db6e5997092da519b Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 8 Apr 2014 15:23:52 +0200 Subject: [PATCH 073/797] s390: add 31 bit warning message Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index f70f2489fa5f..88d1ca81e2dd 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -1027,3 +1027,35 @@ void __init setup_arch(char **cmdline_p) /* Setup zfcpdump support */ setup_zfcpdump(); } + +#ifdef CONFIG_32BIT +static int no_removal_warning __initdata; + +static int __init parse_no_removal_warning(char *str) +{ + no_removal_warning = 1; + return 0; +} +__setup("no_removal_warning", parse_no_removal_warning); + +static int __init removal_warning(void) +{ + if (no_removal_warning) + return 0; + printk(KERN_ALERT "\n\n"); + printk(KERN_CONT "Warning - you are using a 31 bit kernel!\n\n"); + printk(KERN_CONT "We plan to remove 31 bit kernel support from the kernel sources in March 2015.\n"); + printk(KERN_CONT "Currently we assume that nobody is using the 31 bit kernel on old 31 bit\n"); + printk(KERN_CONT "hardware anymore. If you think that the code should not be removed and also\n"); + printk(KERN_CONT "future versions of the Linux kernel should be able to run in 31 bit mode\n"); + printk(KERN_CONT "please let us know. Please write to:\n"); + printk(KERN_CONT "linux390@de.ibm.com (mail address) and/or\n"); + printk(KERN_CONT "linux-s390@vger.kernel.org (mailing list).\n\n"); + printk(KERN_CONT "Thank you!\n\n"); + printk(KERN_CONT "If this kernel runs on a 64 bit machine you may consider using a 64 bit kernel.\n"); + printk(KERN_CONT "This message can be disabled with the \"no_removal_warning\" kernel parameter.\n"); + schedule_timeout_uninterruptible(300 * HZ); + return 0; +} +early_initcall(removal_warning); +#endif -- GitLab From fa255f51c95fd91b4d7bb50a0fdcca18dd47db21 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 9 Apr 2014 09:42:58 +0200 Subject: [PATCH 074/797] s390/uaccess: fix possible register corruption in strnlen_user_srst() The whole point of the out-of-line strnlen_user_srst() function was to avoid corruption of register 0 due to register asm assignment. However 'somebody' :) forgot to remove the update_primary_asce() function call, which may clobber register 0 contents. So let's remove that call and also move the size check to the calling function. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index 23f866b4c7f1..7416efe8eae4 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -338,9 +338,6 @@ static inline unsigned long strnlen_user_srst(const char __user *src, register unsigned long reg0 asm("0") = 0; unsigned long tmp1, tmp2; - if (unlikely(!size)) - return 0; - update_primary_asce(current); asm volatile( " la %2,0(%1)\n" " la %3,0(%0,%1)\n" @@ -359,6 +356,8 @@ static inline unsigned long strnlen_user_srst(const char __user *src, unsigned long __strnlen_user(const char __user *src, unsigned long size) { + if (unlikely(!size)) + return 0; update_primary_asce(current); return strnlen_user_srst(src, size); } -- GitLab From 572c3eb7f841c019f756efc68debbc3187c2a62c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 9 Apr 2014 10:42:37 +0200 Subject: [PATCH 075/797] s390/compat: fix typo Reported-by: Michael Holzheu Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/compat_wrapper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c index 030051840ccd..45cdb37aa6f8 100644 --- a/arch/s390/kernel/compat_wrapper.c +++ b/arch/s390/kernel/compat_wrapper.c @@ -1,5 +1,5 @@ /* - * Compat sytem call wrappers. + * Compat system call wrappers. * * Copyright IBM Corp. 2014 */ -- GitLab From e106e4ea44699cc940a919924f2834b91f426d9f Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Wed, 9 Apr 2014 13:10:05 +0200 Subject: [PATCH 076/797] s390/sclp_vt220: Fix kernel panic due to early terminal input A kernel panic might occur when there is terminal input available via the SCLP VT220 interface at an early time during the boot process. The processing of terminal input requires prior initialization which is done via an early_initcall function (init_workqueues) while the SCLP VT220 driver registers for terminal input during a console_initcall function (sclp_vt220_con_init). When there is terminal input available via the SCLP interface between console_initcall and early_initcall, a null pointer dereference occurs (system_wq is null). Fix this problem by moving the registration for terminal input to a device_initcall function (sclp_vt220_tty_init). Reported-by: Christian Borntraeger Tested-by: Christian Borntraeger Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_vt220.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 4eed38cd0af6..cd9c91909596 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -97,13 +97,16 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg, static int __sclp_vt220_emit(struct sclp_vt220_request *request); static void sclp_vt220_emit_current(void); -/* Registration structure for our interest in SCLP event buffers */ +/* Registration structure for SCLP output event buffers */ static struct sclp_register sclp_vt220_register = { .send_mask = EVTYP_VT220MSG_MASK, + .pm_event_fn = sclp_vt220_pm_event_fn, +}; + +/* Registration structure for SCLP input event buffers */ +static struct sclp_register sclp_vt220_register_input = { .receive_mask = EVTYP_VT220MSG_MASK, - .state_change_fn = NULL, .receiver_fn = sclp_vt220_receiver_fn, - .pm_event_fn = sclp_vt220_pm_event_fn, }; @@ -715,9 +718,14 @@ static int __init sclp_vt220_tty_init(void) rc = tty_register_driver(driver); if (rc) goto out_init; + rc = sclp_register(&sclp_vt220_register_input); + if (rc) + goto out_reg; sclp_vt220_driver = driver; return 0; +out_reg: + tty_unregister_driver(driver); out_init: __sclp_vt220_cleanup(); out_driver: -- GitLab From 83d8e2527641b0710834bceeae5a681ffa759e1e Mon Sep 17 00:00:00 2001 From: Duan Jiong Date: Fri, 11 Apr 2014 13:39:06 +0200 Subject: [PATCH 077/797] s390/sclp: replace PTR_RET with PTR_ERR_OR_ZERO PTR_RET is deprecated. Do not recommend its usage anymore. Use PTR_ERR_OR_ZERO instead. Signed-off-by: Duan Jiong Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 1990285296c6..c316051d9bda 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -1252,7 +1252,7 @@ static __init int sclp_initcall(void) return rc; sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0); - rc = PTR_RET(sclp_pdev); + rc = PTR_ERR_OR_ZERO(sclp_pdev); if (rc) goto fail_platform_driver_unregister; -- GitLab From 5896f8fe491891f551bdc6574bbc4a07c054c30b Mon Sep 17 00:00:00 2001 From: Duan Jiong Date: Fri, 11 Apr 2014 13:41:54 +0200 Subject: [PATCH 078/797] s390/sclp_cmd: replace PTR_RET with PTR_ERR_OR_ZERO PTR_RET is deprecated. Do not recommend its usage anymore. Use PTR_ERR_OR_ZERO instead. Signed-off-by: Duan Jiong Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_cmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 6e8f90f84e49..6e14999f9e8f 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -515,7 +515,7 @@ static int __init sclp_detect_standby_memory(void) if (rc) goto out; sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0); - rc = PTR_RET(sclp_pdev); + rc = PTR_ERR_OR_ZERO(sclp_pdev); if (rc) goto out_driver; sclp_add_standby_memory(); -- GitLab From 622cad1325e404598fe3b148c3fa640dbaabc235 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 11 Apr 2014 10:35:17 -0400 Subject: [PATCH 079/797] ext4: move ext4_update_i_disksize() into mpage_map_and_submit_extent() The function ext4_update_i_disksize() is used in only one place, in the function mpage_map_and_submit_extent(). Move its code to simplify the code paths, and also move the call to ext4_mark_inode_dirty() into the i_data_sem's critical region, to be consistent with all of the other places where we update i_disksize. That way, we also keep the raw_inode's i_disksize protected, to avoid the following race: CPU #1 CPU #2 down_write(&i_data_sem) Modify i_disk_size up_write(&i_data_sem) down_write(&i_data_sem) Modify i_disk_size Copy i_disk_size to on-disk inode up_write(&i_data_sem) Copy i_disk_size to on-disk inode Signed-off-by: "Theodore Ts'o" Reviewed-by: Jan Kara Cc: stable@vger.kernel.org --- fs/ext4/ext4.h | 17 ----------------- fs/ext4/inode.c | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index f1c65dc7cc0a..66946aa62127 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2466,23 +2466,6 @@ static inline void ext4_update_i_disksize(struct inode *inode, loff_t newsize) up_write(&EXT4_I(inode)->i_data_sem); } -/* - * Update i_disksize after writeback has been started. Races with truncate - * are avoided by checking i_size under i_data_sem. - */ -static inline void ext4_wb_update_i_disksize(struct inode *inode, loff_t newsize) -{ - loff_t i_size; - - down_write(&EXT4_I(inode)->i_data_sem); - i_size = i_size_read(inode); - if (newsize > i_size) - newsize = i_size; - if (newsize > EXT4_I(inode)->i_disksize) - EXT4_I(inode)->i_disksize = newsize; - up_write(&EXT4_I(inode)->i_data_sem); -} - struct ext4_group_info { unsigned long bb_state; struct rb_root bb_free_root; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 7b93df9aa182..f023f0cb46fc 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2247,13 +2247,23 @@ static int mpage_map_and_submit_extent(handle_t *handle, return err; } while (map->m_len); - /* Update on-disk size after IO is submitted */ + /* + * Update on-disk size after IO is submitted. Races with + * truncate are avoided by checking i_size under i_data_sem. + */ disksize = ((loff_t)mpd->first_page) << PAGE_CACHE_SHIFT; if (disksize > EXT4_I(inode)->i_disksize) { int err2; - - ext4_wb_update_i_disksize(inode, disksize); + loff_t i_size; + + down_write(&EXT4_I(inode)->i_data_sem); + i_size = i_size_read(inode); + if (disksize > i_size) + disksize = i_size; + if (disksize > EXT4_I(inode)->i_disksize) + EXT4_I(inode)->i_disksize = disksize; err2 = ext4_mark_inode_dirty(handle, inode); + up_write(&EXT4_I(inode)->i_data_sem); if (err2) ext4_error(inode->i_sb, "Failed to mark inode %lu dirty", -- GitLab From c6c56697ae4bf1226263c19e8353343d7083f40e Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Thu, 10 Apr 2014 10:18:17 +0300 Subject: [PATCH 080/797] ARM: OMAP3: hwmod data: Correct clock domains for USB modules OMAP3 doesn't contain "l3_init_clkdm" clock domain. Use the proper clock domains for USB Host and USB TLL modules. Gets rid of the following warnings during boot omap_hwmod: usb_host_hs: could not associate to clkdm l3_init_clkdm omap_hwmod: usb_tll_hs: could not associate to clkdm l3_init_clkdm Reported-by: Nishanth Menon Cc: Paul Walmsley Signed-off-by: Roger Quadros Fixes: de231388cb80a8ef3e779bbfa0564ba0157b7377 ("ARM: OMAP: USB: EHCI and OHCI hwmod structures for OMAP3") Cc: Keshava Munegowda Cc: Partha Basak Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index a123ff0070bd..71ac7d5f3385 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -1964,7 +1964,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_host_hs_irqs[] = { static struct omap_hwmod omap3xxx_usb_host_hs_hwmod = { .name = "usb_host_hs", .class = &omap3xxx_usb_host_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", + .clkdm_name = "usbhost_clkdm", .mpu_irqs = omap3xxx_usb_host_hs_irqs, .main_clk = "usbhost_48m_fck", .prcm = { @@ -2047,7 +2047,7 @@ static struct omap_hwmod_irq_info omap3xxx_usb_tll_hs_irqs[] = { static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = { .name = "usb_tll_hs", .class = &omap3xxx_usb_tll_hs_hwmod_class, - .clkdm_name = "l3_init_clkdm", + .clkdm_name = "core_l4_clkdm", .mpu_irqs = omap3xxx_usb_tll_hs_irqs, .main_clk = "usbtll_fck", .prcm = { -- GitLab From 8e4cb9aac2ada7f8a986606703c34e2d573bb876 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 24 Mar 2014 16:31:52 +0530 Subject: [PATCH 081/797] ARM: AM43xx: fix dpll init in bypass mode On AM43xx, if a PLL is in bypass at kernel init, the code in omap2_get_dpll_rate() will not realize this and will try to calculate the clock rate using the multiplier and the divider, resulting in errors. omap2_init_dpll_parent() has similar issue. Add the missing soc_is_am43xx() check to make the code work on AM43xx. Signed-off-by: Tomi Valkeinen Signed-off-by: Sathya Prakash M R Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/clkt_dpll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c index 2649ce445845..332af927f4d3 100644 --- a/arch/arm/mach-omap2/clkt_dpll.c +++ b/arch/arm/mach-omap2/clkt_dpll.c @@ -209,7 +209,7 @@ u8 omap2_init_dpll_parent(struct clk_hw *hw) if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) return 1; - } else if (soc_is_am33xx() || cpu_is_omap44xx()) { + } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) @@ -255,7 +255,7 @@ unsigned long omap2_get_dpll_rate(struct clk_hw_omap *clk) if (v == OMAP3XXX_EN_DPLL_LPBYPASS || v == OMAP3XXX_EN_DPLL_FRBYPASS) return __clk_get_rate(dd->clk_bypass); - } else if (soc_is_am33xx() || cpu_is_omap44xx()) { + } else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx()) { if (v == OMAP4XXX_EN_DPLL_LPBYPASS || v == OMAP4XXX_EN_DPLL_FRBYPASS || v == OMAP4XXX_EN_DPLL_MNBYPASS) -- GitLab From 3d36ad7e7a9be0d130c862727a052ed279046437 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 14 Mar 2014 14:45:17 +0530 Subject: [PATCH 082/797] ARM: OMAP2+: hwmod: fix missing braces in _init() Bug was introduced by commit 'f92d959: ARM: OMAP2+: hwmod: Extract no-idle and no-reset info from DT' There were 2 versions of the patch posted which resulted in the above commit. While v1 [1] had the bug, v2 [2] had it fixed. However v1 apparently seemed to have been pulled in by mistake introducing the bug. Given of_find_property() does return NULL when the node passed is NULL, it did not introduce any functional issues as such, just the fact that the second if check was executed unnecessarily. [1] https://www.mail-archive.com/linux-omap@vger.kernel.org/msg94220.html [2] http://www.spinics.net/lists/linux-omap/msg98490.html Cc: Nishanth Menon Signed-off-by: Rajendra Nayak Signed-off-by: Suman Anna Signed-off-by: Lokesh Vutla Fixes: f92d9597f781f6a5a39c73dc71604bd8a21c5299 ("ARM: OMAP2+: hwmod: Extract no-idle and no-reset info from DT") Signed-off-by: Paul Walmsley --- arch/arm/mach-omap2/omap_hwmod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 1f33f5db10d5..66c60fe1104c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2546,11 +2546,12 @@ static int __init _init(struct omap_hwmod *oh, void *data) return -EINVAL; } - if (np) + if (np) { if (of_find_property(np, "ti,no-reset-on-init", NULL)) oh->flags |= HWMOD_INIT_NO_RESET; if (of_find_property(np, "ti,no-idle-on-init", NULL)) oh->flags |= HWMOD_INIT_NO_IDLE; + } oh->_state = _HWMOD_STATE_INITIALIZED; -- GitLab From fa658a98a2d08352c514758b3394caf91360aa44 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:25 -0500 Subject: [PATCH 083/797] RDMA/cxgb4: Use the BAR2/WC path for kernel QPs and T5 devices Signed-off-by: Steve Wise [ Fix cast from u64* to integer. - Roland ] Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/device.c | 41 ++++++++++++++---- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 2 + drivers/infiniband/hw/cxgb4/qp.c | 57 +++++++++++++++--------- drivers/infiniband/hw/cxgb4/t4.h | 60 ++++++++++++++++++++++++-- 4 files changed, 127 insertions(+), 33 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index 9489a388376c..f4fa50a609e2 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -682,7 +682,10 @@ static void c4iw_dealloc(struct uld_ctx *ctx) idr_destroy(&ctx->dev->hwtid_idr); idr_destroy(&ctx->dev->stid_idr); idr_destroy(&ctx->dev->atid_idr); - iounmap(ctx->dev->rdev.oc_mw_kva); + if (ctx->dev->rdev.bar2_kva) + iounmap(ctx->dev->rdev.bar2_kva); + if (ctx->dev->rdev.oc_mw_kva) + iounmap(ctx->dev->rdev.oc_mw_kva); ib_dealloc_device(&ctx->dev->ibdev); ctx->dev = NULL; } @@ -722,11 +725,31 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop) } devp->rdev.lldi = *infop; - devp->rdev.oc_mw_pa = pci_resource_start(devp->rdev.lldi.pdev, 2) + - (pci_resource_len(devp->rdev.lldi.pdev, 2) - - roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size)); - devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa, - devp->rdev.lldi.vr->ocq.size); + /* + * For T5 devices, we map all of BAR2 with WC. + * For T4 devices with onchip qp mem, we map only that part + * of BAR2 with WC. + */ + devp->rdev.bar2_pa = pci_resource_start(devp->rdev.lldi.pdev, 2); + if (is_t5(devp->rdev.lldi.adapter_type)) { + devp->rdev.bar2_kva = ioremap_wc(devp->rdev.bar2_pa, + pci_resource_len(devp->rdev.lldi.pdev, 2)); + if (!devp->rdev.bar2_kva) { + pr_err(MOD "Unable to ioremap BAR2\n"); + return ERR_PTR(-EINVAL); + } + } else if (ocqp_supported(infop)) { + devp->rdev.oc_mw_pa = + pci_resource_start(devp->rdev.lldi.pdev, 2) + + pci_resource_len(devp->rdev.lldi.pdev, 2) - + roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size); + devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa, + devp->rdev.lldi.vr->ocq.size); + if (!devp->rdev.oc_mw_kva) { + pr_err(MOD "Unable to ioremap onchip mem\n"); + return ERR_PTR(-EINVAL); + } + } PDBG(KERN_INFO MOD "ocq memory: " "hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n", @@ -1003,9 +1026,11 @@ static int enable_qp_db(int id, void *p, void *data) static void resume_rc_qp(struct c4iw_qp *qp) { spin_lock(&qp->lock); - t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc); + t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc, + is_t5(qp->rhp->rdev.lldi.adapter_type), NULL); qp->wq.sq.wq_pidx_inc = 0; - t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc); + t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc, + is_t5(qp->rhp->rdev.lldi.adapter_type), NULL); qp->wq.rq.wq_pidx_inc = 0; spin_unlock(&qp->lock); } diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index e872203c5424..7b8c5806a09d 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -149,6 +149,8 @@ struct c4iw_rdev { struct gen_pool *ocqp_pool; u32 flags; struct cxgb4_lld_info lldi; + unsigned long bar2_pa; + void __iomem *bar2_kva; unsigned long oc_mw_pa; void __iomem *oc_mw_kva; struct c4iw_stats stats; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index cb76eb5eee1f..e2fcbf4814f2 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -212,13 +212,23 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, wq->db = rdev->lldi.db_reg; wq->gts = rdev->lldi.gts_reg; - if (user) { - wq->sq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) + - (wq->sq.qid << rdev->qpshift); - wq->sq.udb &= PAGE_MASK; - wq->rq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) + - (wq->rq.qid << rdev->qpshift); - wq->rq.udb &= PAGE_MASK; + if (user || is_t5(rdev->lldi.adapter_type)) { + u32 off; + + off = (wq->sq.qid << rdev->qpshift) & PAGE_MASK; + if (user) { + wq->sq.udb = (u64 __iomem *)(rdev->bar2_pa + off); + } else { + off += 128 * (wq->sq.qid & rdev->qpmask) + 8; + wq->sq.udb = (u64 __iomem *)(rdev->bar2_kva + off); + } + off = (wq->rq.qid << rdev->qpshift) & PAGE_MASK; + if (user) { + wq->rq.udb = (u64 __iomem *)(rdev->bar2_pa + off); + } else { + off += 128 * (wq->rq.qid & rdev->qpmask) + 8; + wq->rq.udb = (u64 __iomem *)(rdev->bar2_kva + off); + } } wq->rdev = rdev; wq->rq.msn = 1; @@ -299,9 +309,10 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, if (ret) goto free_dma; - PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%llx rqudb 0x%llx\n", + PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%lx rqudb 0x%lx\n", __func__, wq->sq.qid, wq->rq.qid, wq->db, - (unsigned long long)wq->sq.udb, (unsigned long long)wq->rq.udb); + (__force unsigned long) wq->sq.udb, + (__force unsigned long) wq->rq.udb); return 0; free_dma: @@ -650,9 +661,10 @@ static int ring_kernel_sq_db(struct c4iw_qp *qhp, u16 inc) spin_lock_irqsave(&qhp->rhp->lock, flags); spin_lock(&qhp->lock); - if (qhp->rhp->db_state == NORMAL) { - t4_ring_sq_db(&qhp->wq, inc); - } else { + if (qhp->rhp->db_state == NORMAL) + t4_ring_sq_db(&qhp->wq, inc, + is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL); + else { add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry); qhp->wq.sq.wq_pidx_inc += inc; } @@ -667,9 +679,10 @@ static int ring_kernel_rq_db(struct c4iw_qp *qhp, u16 inc) spin_lock_irqsave(&qhp->rhp->lock, flags); spin_lock(&qhp->lock); - if (qhp->rhp->db_state == NORMAL) { - t4_ring_rq_db(&qhp->wq, inc); - } else { + if (qhp->rhp->db_state == NORMAL) + t4_ring_rq_db(&qhp->wq, inc, + is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL); + else { add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry); qhp->wq.rq.wq_pidx_inc += inc; } @@ -686,7 +699,7 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, enum fw_wr_opcodes fw_opcode = 0; enum fw_ri_wr_flags fw_flags; struct c4iw_qp *qhp; - union t4_wr *wqe; + union t4_wr *wqe = NULL; u32 num_wrs; struct t4_swsqe *swsqe; unsigned long flag; @@ -792,7 +805,8 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE); } if (!qhp->rhp->rdev.status_page->db_off) { - t4_ring_sq_db(&qhp->wq, idx); + t4_ring_sq_db(&qhp->wq, idx, + is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe); spin_unlock_irqrestore(&qhp->lock, flag); } else { spin_unlock_irqrestore(&qhp->lock, flag); @@ -806,7 +820,7 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, { int err = 0; struct c4iw_qp *qhp; - union t4_recv_wr *wqe; + union t4_recv_wr *wqe = NULL; u32 num_wrs; u8 len16 = 0; unsigned long flag; @@ -858,7 +872,8 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, num_wrs--; } if (!qhp->rhp->rdev.status_page->db_off) { - t4_ring_rq_db(&qhp->wq, idx); + t4_ring_rq_db(&qhp->wq, idx, + is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe); spin_unlock_irqrestore(&qhp->lock, flag); } else { spin_unlock_irqrestore(&qhp->lock, flag); @@ -1677,11 +1692,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs, mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize); insert_mmap(ucontext, mm2); mm3->key = uresp.sq_db_gts_key; - mm3->addr = qhp->wq.sq.udb; + mm3->addr = (__force unsigned long) qhp->wq.sq.udb; mm3->len = PAGE_SIZE; insert_mmap(ucontext, mm3); mm4->key = uresp.rq_db_gts_key; - mm4->addr = qhp->wq.rq.udb; + mm4->addr = (__force unsigned long) qhp->wq.rq.udb; mm4->len = PAGE_SIZE; insert_mmap(ucontext, mm4); if (mm5) { diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index eeca8b1e6376..931bfd105c49 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -292,7 +292,7 @@ struct t4_sq { unsigned long phys_addr; struct t4_swsqe *sw_sq; struct t4_swsqe *oldest_read; - u64 udb; + u64 __iomem *udb; size_t memsize; u32 qid; u16 in_use; @@ -314,7 +314,7 @@ struct t4_rq { dma_addr_t dma_addr; DEFINE_DMA_UNMAP_ADDR(mapping); struct t4_swrqe *sw_rq; - u64 udb; + u64 __iomem *udb; size_t memsize; u32 qid; u32 msn; @@ -435,15 +435,67 @@ static inline u16 t4_sq_wq_size(struct t4_wq *wq) return wq->sq.size * T4_SQ_NUM_SLOTS; } -static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc) +/* This function copies 64 byte coalesced work request to memory + * mapped BAR2 space. For coalesced WRs, the SGE fetches data + * from the FIFO instead of from Host. + */ +static inline void pio_copy(u64 __iomem *dst, u64 *src) +{ + int count = 8; + + while (count) { + writeq(*src, dst); + src++; + dst++; + count--; + } +} + +static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc, u8 t5, + union t4_wr *wqe) { + + /* Flush host queue memory writes. */ wmb(); + if (t5) { + if (inc == 1 && wqe) { + PDBG("%s: WC wq->sq.pidx = %d\n", + __func__, wq->sq.pidx); + pio_copy(wq->sq.udb + 7, (void *)wqe); + } else { + PDBG("%s: DB wq->sq.pidx = %d\n", + __func__, wq->sq.pidx); + writel(PIDX_T5(inc), wq->sq.udb); + } + + /* Flush user doorbell area writes. */ + wmb(); + return; + } writel(QID(wq->sq.qid) | PIDX(inc), wq->db); } -static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc) +static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc, u8 t5, + union t4_recv_wr *wqe) { + + /* Flush host queue memory writes. */ wmb(); + if (t5) { + if (inc == 1 && wqe) { + PDBG("%s: WC wq->rq.pidx = %d\n", + __func__, wq->rq.pidx); + pio_copy(wq->rq.udb + 7, (void *)wqe); + } else { + PDBG("%s: DB wq->rq.pidx = %d\n", + __func__, wq->rq.pidx); + writel(PIDX_T5(inc), wq->rq.udb); + } + + /* Flush user doorbell area writes. */ + wmb(); + return; + } writel(QID(wq->rq.qid) | PIDX(inc), wq->db); } -- GitLab From b33bd0cbfa102b8f87702338aa72742fe3c7f220 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:25 -0500 Subject: [PATCH 084/797] RDMA/cxgb4: Endpoint timeout fixes 1) timedout endpoint processing can be starved. If there are continual CPL messages flowing into the driver, the endpoint timeout processing can be starved. This condition exposed the other bugs below. Solution: In process_work(), call process_timedout_eps() after each CPL is processed. 2) Connection events can be processed even though the endpoint is on the timeout list. If the endpoint is scheduled for timeout processing, then we must ignore MPA Start Requests and Replies. Solution: Change stop_ep_timer() to return 1 if the ep has already been queued for timeout processing. All the callers of stop_ep_timer() need to check this and act accordingly. There are just a few cases where the caller needs to do something different if stop_ep_timer() returns 1: 1) in process_mpa_reply(), ignore the reply and process_timeout() will abort the connection. 2) in process_mpa_request, ignore the request and process_timeout() will abort the connection. It is ok for callers of stop_ep_timer() to abort the connection since that will leave the state in ABORTING or DEAD, and process_timeout() now ignores timeouts when the ep is in these states. 3) Double insertion on the timeout list. Since the endpoint timers are used for connection setup and teardown, we need to guard against the possibility that an endpoint is already on the timeout list. This is a rare condition and only seen under heavy load and in the presense of the above 2 bugs. Solution: In ep_timeout(), don't queue the endpoint if it is already on the queue. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cm.c | 89 ++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 33 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 02436d5d0dab..185452abf32c 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -173,12 +173,15 @@ static void start_ep_timer(struct c4iw_ep *ep) add_timer(&ep->timer); } -static void stop_ep_timer(struct c4iw_ep *ep) +static int stop_ep_timer(struct c4iw_ep *ep) { PDBG("%s ep %p stopping\n", __func__, ep); del_timer_sync(&ep->timer); - if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) + if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) { c4iw_put_ep(&ep->com); + return 0; + } + return 1; } static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb, @@ -1165,12 +1168,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); /* - * Stop mpa timer. If it expired, then the state has - * changed and we bail since ep_timeout already aborted - * the connection. + * Stop mpa timer. If it expired, then + * we ignore the MPA reply. process_timeout() + * will abort the connection. */ - stop_ep_timer(ep); - if (ep->com.state != MPA_REQ_SENT) + if (stop_ep_timer(ep)) return; /* @@ -1375,15 +1377,12 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); - if (ep->com.state != MPA_REQ_WAIT) - return; - /* * If we get more than the supported amount of private data * then we must fail this connection. */ if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) { - stop_ep_timer(ep); + (void)stop_ep_timer(ep); abort_connection(ep, skb, GFP_KERNEL); return; } @@ -1413,13 +1412,13 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) if (mpa->revision > mpa_rev) { printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d," " Received = %d\n", __func__, mpa_rev, mpa->revision); - stop_ep_timer(ep); + (void)stop_ep_timer(ep); abort_connection(ep, skb, GFP_KERNEL); return; } if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) { - stop_ep_timer(ep); + (void)stop_ep_timer(ep); abort_connection(ep, skb, GFP_KERNEL); return; } @@ -1430,7 +1429,7 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) * Fail if there's too much private data. */ if (plen > MPA_MAX_PRIVATE_DATA) { - stop_ep_timer(ep); + (void)stop_ep_timer(ep); abort_connection(ep, skb, GFP_KERNEL); return; } @@ -1439,7 +1438,7 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) * If plen does not account for pkt size */ if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) { - stop_ep_timer(ep); + (void)stop_ep_timer(ep); abort_connection(ep, skb, GFP_KERNEL); return; } @@ -1496,18 +1495,24 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version, ep->mpa_attr.p2p_type); - __state_set(&ep->com, MPA_REQ_RCVD); - stop_ep_timer(ep); - - /* drive upcall */ - mutex_lock(&ep->parent_ep->com.mutex); - if (ep->parent_ep->com.state != DEAD) { - if (connect_request_upcall(ep)) + /* + * If the endpoint timer already expired, then we ignore + * the start request. process_timeout() will abort + * the connection. + */ + if (!stop_ep_timer(ep)) { + __state_set(&ep->com, MPA_REQ_RCVD); + + /* drive upcall */ + mutex_lock(&ep->parent_ep->com.mutex); + if (ep->parent_ep->com.state != DEAD) { + if (connect_request_upcall(ep)) + abort_connection(ep, skb, GFP_KERNEL); + } else { abort_connection(ep, skb, GFP_KERNEL); - } else { - abort_connection(ep, skb, GFP_KERNEL); + } + mutex_unlock(&ep->parent_ep->com.mutex); } - mutex_unlock(&ep->parent_ep->com.mutex); return; } @@ -2265,7 +2270,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb) disconnect = 0; break; case MORIBUND: - stop_ep_timer(ep); + (void)stop_ep_timer(ep); if (ep->com.cm_id && ep->com.qp) { attrs.next_state = C4IW_QP_STATE_IDLE; c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, @@ -2325,10 +2330,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb) case CONNECTING: break; case MPA_REQ_WAIT: - stop_ep_timer(ep); + (void)stop_ep_timer(ep); break; case MPA_REQ_SENT: - stop_ep_timer(ep); + (void)stop_ep_timer(ep); if (mpa_rev == 1 || (mpa_rev == 2 && ep->tried_with_mpa_v1)) connect_reply_upcall(ep, -ECONNRESET); else { @@ -2433,7 +2438,7 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb) __state_set(&ep->com, MORIBUND); break; case MORIBUND: - stop_ep_timer(ep); + (void)stop_ep_timer(ep); if ((ep->com.cm_id) && (ep->com.qp)) { attrs.next_state = C4IW_QP_STATE_IDLE; c4iw_modify_qp(ep->com.qp->rhp, @@ -3028,7 +3033,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp) if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) { close = 1; if (abrupt) { - stop_ep_timer(ep); + (void)stop_ep_timer(ep); ep->com.state = ABORTING; } else ep->com.state = MORIBUND; @@ -3462,6 +3467,16 @@ static void process_timeout(struct c4iw_ep *ep) __state_set(&ep->com, ABORTING); close_complete_upcall(ep, -ETIMEDOUT); break; + case ABORTING: + case DEAD: + + /* + * These states are expected if the ep timed out at the same + * time as another thread was calling stop_ep_timer(). + * So we silently do nothing for these states. + */ + abort = 0; + break; default: WARN(1, "%s unexpected state ep %p tid %u state %u\n", __func__, ep, ep->hwtid, ep->com.state); @@ -3483,6 +3498,8 @@ static void process_timedout_eps(void) tmp = timeout_list.next; list_del(tmp); + tmp->next = NULL; + tmp->prev = NULL; spin_unlock_irq(&timeout_lock); ep = list_entry(tmp, struct c4iw_ep, entry); process_timeout(ep); @@ -3499,6 +3516,7 @@ static void process_work(struct work_struct *work) unsigned int opcode; int ret; + process_timedout_eps(); while ((skb = skb_dequeue(&rxq))) { rpl = cplhdr(skb); dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *))); @@ -3508,8 +3526,8 @@ static void process_work(struct work_struct *work) ret = work_handlers[opcode](dev, skb); if (!ret) kfree_skb(skb); + process_timedout_eps(); } - process_timedout_eps(); } static DECLARE_WORK(skb_work, process_work); @@ -3521,8 +3539,13 @@ static void ep_timeout(unsigned long arg) spin_lock(&timeout_lock); if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) { - list_add_tail(&ep->entry, &timeout_list); - kickit = 1; + /* + * Only insert if it is not already on the list. + */ + if (!ep->entry.next) { + list_add_tail(&ep->entry, &timeout_list); + kickit = 1; + } } spin_unlock(&timeout_lock); if (kickit) -- GitLab From def4771f4bf428d39c7fe6006a9e1a20ee380d1e Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:26 -0500 Subject: [PATCH 085/797] RDMA/cxgb4: rmb() after reading valid gen bit Some HW platforms can reorder read operations, so we must rmb() after we see a valid gen bit in a CQE but before we read any other fields from the CQE. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/t4.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 931bfd105c49..1f329fac9801 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -620,6 +620,9 @@ static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe) printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid); BUG_ON(1); } else if (t4_valid_cqe(cq, &cq->queue[cq->cidx])) { + + /* Ensure CQE is flushed to memory */ + rmb(); *cqe = &cq->queue[cq->cidx]; ret = 0; } else -- GitLab From b4e2901c52cc79f287e2b25804e029880e5e4b07 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:26 -0500 Subject: [PATCH 086/797] RDMA/cxgb4: SQ flush fix There is a race when moving a QP from RTS->CLOSING where a SQ work request could be posted after the FW receives the RDMA_RI/FINI WR. The SQ work request will never get processed, and should be completed with FLUSHED status. Function c4iw_flush_sq(), however was dropping the oldest SQ work request when in CLOSING or IDLE states, instead of completing the pending work request. If that oldest pending work request was actually complete and has a CQE in the CQ, then when that CQE is proceessed in poll_cq, we'll BUG_ON() due to the inconsistent SQ/CQ state. This is a very small timing hole and has only been hit once so far. The fix is two-fold: 1) c4iw_flush_sq() MUST always flush all non-completed WRs with FLUSHED status regardless of the QP state. 2) In c4iw_modify_rc_qp(), always set the "in error" bit on the queue before moving the state out of RTS. This ensures that the state transition will not happen while another thread is in post_rc_send(), because set_state() and post_rc_send() both aquire the qp spinlock. Also, once we transition the state out of RTS, subsequent calls to post_rc_send() will fail because the "in error" bit is set. I don't think this fully closes the race where the FW can get a FINI followed a SQ work request being posted (because they are posted to differente EQs), but the #1 fix will handle the issue by flushing the SQ work request. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cq.c | 22 ++++++++-------------- drivers/infiniband/hw/cxgb4/qp.c | 6 +++--- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index ce468e542428..e17b155b3758 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -235,27 +235,21 @@ int c4iw_flush_sq(struct c4iw_qp *qhp) struct t4_cq *cq = &chp->cq; int idx; struct t4_swsqe *swsqe; - int error = (qhp->attr.state != C4IW_QP_STATE_CLOSING && - qhp->attr.state != C4IW_QP_STATE_IDLE); if (wq->sq.flush_cidx == -1) wq->sq.flush_cidx = wq->sq.cidx; idx = wq->sq.flush_cidx; BUG_ON(idx >= wq->sq.size); while (idx != wq->sq.pidx) { - if (error) { - swsqe = &wq->sq.sw_sq[idx]; - BUG_ON(swsqe->flushed); - swsqe->flushed = 1; - insert_sq_cqe(wq, cq, swsqe); - if (wq->sq.oldest_read == swsqe) { - BUG_ON(swsqe->opcode != FW_RI_READ_REQ); - advance_oldest_read(wq); - } - flushed++; - } else { - t4_sq_consume(wq); + swsqe = &wq->sq.sw_sq[idx]; + BUG_ON(swsqe->flushed); + swsqe->flushed = 1; + insert_sq_cqe(wq, cq, swsqe); + if (wq->sq.oldest_read == swsqe) { + BUG_ON(swsqe->opcode != FW_RI_READ_REQ); + advance_oldest_read(wq); } + flushed++; if (++idx == wq->sq.size) idx = 0; } diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index e2fcbf4814f2..9b4a8b88908e 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1367,6 +1367,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, switch (attrs->next_state) { case C4IW_QP_STATE_CLOSING: BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2); + t4_set_wq_in_error(&qhp->wq); set_state(qhp, C4IW_QP_STATE_CLOSING); ep = qhp->ep; if (!internal) { @@ -1374,16 +1375,15 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, disconnect = 1; c4iw_get_ep(&qhp->ep->com); } - t4_set_wq_in_error(&qhp->wq); ret = rdma_fini(rhp, qhp, ep); if (ret) goto err; break; case C4IW_QP_STATE_TERMINATE: + t4_set_wq_in_error(&qhp->wq); set_state(qhp, C4IW_QP_STATE_TERMINATE); qhp->attr.layer_etype = attrs->layer_etype; qhp->attr.ecode = attrs->ecode; - t4_set_wq_in_error(&qhp->wq); ep = qhp->ep; disconnect = 1; if (!internal) @@ -1396,8 +1396,8 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, c4iw_get_ep(&qhp->ep->com); break; case C4IW_QP_STATE_ERROR: - set_state(qhp, C4IW_QP_STATE_ERROR); t4_set_wq_in_error(&qhp->wq); + set_state(qhp, C4IW_QP_STATE_ERROR); if (!internal) { abort = 1; disconnect = 1; -- GitLab From a03d9f94cc54199bf681729b16ba649d7206369e Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:27 -0500 Subject: [PATCH 087/797] RDMA/cxgb4: Max fastreg depth depends on DSGL support The max depth of a fastreg mr depends on whether the device supports DSGL or not. So compute it dynamically based on the device support and the module use_dsgl option. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/provider.c | 2 +- drivers/infiniband/hw/cxgb4/qp.c | 3 ++- drivers/infiniband/hw/cxgb4/t4.h | 9 ++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index 79429256023a..a94a3e12c349 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -328,7 +328,7 @@ static int c4iw_query_device(struct ib_device *ibdev, props->max_mr = c4iw_num_stags(&dev->rdev); props->max_pd = T4_MAX_NUM_PD; props->local_ca_ack_delay = 0; - props->max_fast_reg_page_list_len = T4_MAX_FR_DEPTH; + props->max_fast_reg_page_list_len = t4_max_fr_depth(use_dsgl); return 0; } diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 9b4a8b88908e..2c037e1746d3 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -566,7 +566,8 @@ static int build_fastreg(struct t4_sq *sq, union t4_wr *wqe, int pbllen = roundup(wr->wr.fast_reg.page_list_len * sizeof(u64), 32); int rem; - if (wr->wr.fast_reg.page_list_len > T4_MAX_FR_DEPTH) + if (wr->wr.fast_reg.page_list_len > + t4_max_fr_depth(use_dsgl)) return -EINVAL; wqe->fr.qpbinde_to_dcacpu = 0; diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h index 1f329fac9801..2178f3198410 100644 --- a/drivers/infiniband/hw/cxgb4/t4.h +++ b/drivers/infiniband/hw/cxgb4/t4.h @@ -84,7 +84,14 @@ struct t4_status_page { sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge)) #define T4_MAX_FR_IMMD ((T4_SQ_NUM_BYTES - sizeof(struct fw_ri_fr_nsmr_wr) - \ sizeof(struct fw_ri_immd)) & ~31UL) -#define T4_MAX_FR_DEPTH (1024 / sizeof(u64)) +#define T4_MAX_FR_IMMD_DEPTH (T4_MAX_FR_IMMD / sizeof(u64)) +#define T4_MAX_FR_DSGL 1024 +#define T4_MAX_FR_DSGL_DEPTH (T4_MAX_FR_DSGL / sizeof(u64)) + +static inline int t4_max_fr_depth(int use_dsgl) +{ + return use_dsgl ? T4_MAX_FR_DSGL_DEPTH : T4_MAX_FR_IMMD_DEPTH; +} #define T4_RQ_NUM_SLOTS 2 #define T4_RQ_NUM_BYTES (T4_EQ_ENTRY_SIZE * T4_RQ_NUM_SLOTS) -- GitLab From aec844df104f1e45cafd10628481f256908554c4 Mon Sep 17 00:00:00 2001 From: Hariprasad Shenai Date: Wed, 9 Apr 2014 09:38:27 -0500 Subject: [PATCH 088/797] RDMA/cxgb4: Use pr_warn_ratelimited Signed-off-by: Hariprasad Shenai Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/resource.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c index cdef4d7fb6d8..94b5fd9b9379 100644 --- a/drivers/infiniband/hw/cxgb4/resource.c +++ b/drivers/infiniband/hw/cxgb4/resource.c @@ -322,8 +322,8 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size) unsigned long addr = gen_pool_alloc(rdev->rqt_pool, size << 6); PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size << 6); if (!addr) - printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n", - pci_name(rdev->lldi.pdev)); + pr_warn_ratelimited(MOD "%s: Out of RQT memory\n", + pci_name(rdev->lldi.pdev)); mutex_lock(&rdev->stats.lock); if (addr) { rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT); -- GitLab From c3f98fa29176753a759ade424f18b11f440b19f4 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:27 -0500 Subject: [PATCH 089/797] RDMA/cxgb4: Initialize reserved fields in a FW work request Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 2c037e1746d3..5a7d368aa47a 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -436,6 +436,8 @@ static int build_rdma_send(struct t4_sq *sq, union t4_wr *wqe, default: return -EINVAL; } + wqe->send.r3 = 0; + wqe->send.r4 = 0; plen = 0; if (wr->num_sge) { -- GitLab From 98a3e879907644c0b7e2f16436eb5cf24b9cd61f Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:28 -0500 Subject: [PATCH 090/797] RDMA/cxgb4: Add missing debug stats Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/mem.c | 6 +++++- drivers/infiniband/hw/cxgb4/resource.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index f9ca072a99ed..ec7a2988a703 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -259,8 +259,12 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) { stag_idx = c4iw_get_resource(&rdev->resource.tpt_table); - if (!stag_idx) + if (!stag_idx) { + mutex_lock(&rdev->stats.lock); + rdev->stats.stag.fail++; + mutex_unlock(&rdev->stats.lock); return -ENOMEM; + } mutex_lock(&rdev->stats.lock); rdev->stats.stag.cur += 32; if (rdev->stats.stag.cur > rdev->stats.stag.max) diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c index 94b5fd9b9379..67df71a7012e 100644 --- a/drivers/infiniband/hw/cxgb4/resource.c +++ b/drivers/infiniband/hw/cxgb4/resource.c @@ -179,8 +179,12 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) kfree(entry); } else { qid = c4iw_get_resource(&rdev->resource.qid_table); - if (!qid) + if (!qid) { + mutex_lock(&rdev->stats.lock); + rdev->stats.qid.fail++; + mutex_unlock(&rdev->stats.lock); goto out; + } mutex_lock(&rdev->stats.lock); rdev->stats.qid.cur += rdev->qpmask + 1; mutex_unlock(&rdev->stats.lock); -- GitLab From 97df1c6736f660b58b408a60d0f7f65a64fb9d56 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:38:28 -0500 Subject: [PATCH 091/797] RDMA/cxgb4: Use uninitialized_var() Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index e17b155b3758..cfaa56ada189 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -672,7 +672,7 @@ static int poll_cq(struct t4_wq *wq, struct t4_cq *cq, struct t4_cqe *cqe, static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc) { struct c4iw_qp *qhp = NULL; - struct t4_cqe cqe = {0, 0}, *rd_cqe; + struct t4_cqe uninitialized_var(cqe), *rd_cqe; struct t4_wq *wq; u32 credit = 0; u8 cqe_flushed; -- GitLab From 1d1ca9b4fdde07325d263f7a75379527b1281f52 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Wed, 9 Apr 2014 09:40:37 -0500 Subject: [PATCH 092/797] RDMA/cxgb4: Fix over-dereference when terminating Need to get the endpoint reference before calling rdma_fini(), which might fail causing us to not get the reference. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 5a7d368aa47a..7b5114cb486f 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1389,6 +1389,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, qhp->attr.ecode = attrs->ecode; ep = qhp->ep; disconnect = 1; + c4iw_get_ep(&qhp->ep->com); if (!internal) terminate = 1; else { @@ -1396,7 +1397,6 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, if (ret) goto err; } - c4iw_get_ep(&qhp->ep->com); break; case C4IW_QP_STATE_ERROR: t4_set_wq_in_error(&qhp->wq); -- GitLab From ab0a9358ecf87bb801ce124473e7db713457bec4 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 11 Apr 2014 12:25:37 +0200 Subject: [PATCH 093/797] i386: Wire up the renameat2() syscall The renameat2() system call was only wired up for x86-64. Signed-off-by: Miklos Szeredi Link: http://lkml.kernel.org/r/1397211951-20549-2-git-send-email-miklos@szeredi.hu Cc: H. Peter Anvin Signed-off-by: H. Peter Anvin --- arch/x86/syscalls/syscall_32.tbl | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl index 96bc506ac6de..d6b867921612 100644 --- a/arch/x86/syscalls/syscall_32.tbl +++ b/arch/x86/syscalls/syscall_32.tbl @@ -359,3 +359,4 @@ 350 i386 finit_module sys_finit_module 351 i386 sched_setattr sys_sched_setattr 352 i386 sched_getattr sys_sched_getattr +353 i386 renameat2 sys_renameat2 -- GitLab From 9ef06cec7c96f6bf59f1dd8b64b9645820099051 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 09:47:00 -0400 Subject: [PATCH 094/797] ext4: remove unnecessary check for APPEND and IMMUTABLE All the checks IS_APPEND and IS_IMMUTABLE for the fallocate operation on the inode are done in vfs. No need to do this again in ext4. Remove it. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 6 ------ fs/ext4/inode.c | 6 +----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index be1e56cbbf32..ed4ec48239b6 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5398,12 +5398,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) /* Take mutex lock */ mutex_lock(&inode->i_mutex); - /* It's not possible punch hole on append only file */ - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { - ret = -EPERM; - goto out_mutex; - } - if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; goto out_mutex; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index f023f0cb46fc..e2bba76f0d7b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3541,11 +3541,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) } mutex_lock(&inode->i_mutex); - /* It's not possible punch hole on append only file */ - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) { - ret = -EPERM; - goto out_mutex; - } + if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; goto out_mutex; -- GitLab From 8fc61d92630d1c96057a94c61e1643475045b25b Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 09:51:34 -0400 Subject: [PATCH 095/797] fs: prevent doing FALLOC_FL_ZERO_RANGE on append only file Currently punch hole and collapse range fallocate operation are not allowed on append only file. This should be case for zero range as well. Fix it by allowing only pure fallocate (possibly with keep size set). Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/open.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/open.c b/fs/open.c index 631aea815def..3a83253d3373 100644 --- a/fs/open.c +++ b/fs/open.c @@ -254,11 +254,9 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) return -EBADF; /* - * It's not possible to punch hole or perform collapse range - * on append only file + * We can only allow pure fallocate on append only files */ - if (mode & (FALLOC_FL_PUNCH_HOLE | FALLOC_FL_COLLAPSE_RANGE) - && IS_APPEND(inode)) + if ((mode & ~FALLOC_FL_KEEP_SIZE) && IS_APPEND(inode)) return -EPERM; if (IS_IMMUTABLE(inode)) -- GitLab From 23fffa925ea2c9a2bcb1a4453e2c542635aa3545 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 09:56:41 -0400 Subject: [PATCH 096/797] fs: move falloc collapse range check into the filesystem methods Currently in do_fallocate in collapse range case we're checking whether offset + len is not bigger than i_size. However there is nothing which would prevent i_size from changing so the check is pointless. It should be done in the file system itself and the file system needs to make sure that i_size is not going to change. The i_size check for the other fallocate modes are also done in the filesystems. As it is now we can easily crash the kernel by having two processes doing truncate and fallocate collapse range at the same time. This can be reproduced on ext4 and it is theoretically possible on xfs even though I was not able to trigger it with this simple test. This commit removes the check from do_fallocate and adds it to the file system. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" Acked-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/ext4/extents.c | 11 +++++++++-- fs/open.c | 8 -------- fs/xfs/xfs_file.c | 10 +++++++++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ed4ec48239b6..ac5460d0d133 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5368,8 +5368,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) loff_t new_size; int ret; - BUG_ON(offset + len > i_size_read(inode)); - /* Collapse range works only on fs block size aligned offsets. */ if (offset & (EXT4_BLOCK_SIZE(sb) - 1) || len & (EXT4_BLOCK_SIZE(sb) - 1)) @@ -5398,6 +5396,15 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) /* Take mutex lock */ mutex_lock(&inode->i_mutex); + /* + * There is no need to overlap collapse range with EOF, in which case + * it is effectively a truncate operation + */ + if (offset + len >= i_size_read(inode)) { + ret = -EINVAL; + goto out_mutex; + } + if (IS_SWAPFILE(inode)) { ret = -ETXTBSY; goto out_mutex; diff --git a/fs/open.c b/fs/open.c index 3a83253d3373..adf34202213a 100644 --- a/fs/open.c +++ b/fs/open.c @@ -284,14 +284,6 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (((offset + len) > inode->i_sb->s_maxbytes) || ((offset + len) < 0)) return -EFBIG; - /* - * There is no need to overlap collapse range with EOF, in which case - * it is effectively a truncate operation - */ - if ((mode & FALLOC_FL_COLLAPSE_RANGE) && - (offset + len >= i_size_read(inode))) - return -EINVAL; - if (!file->f_op->fallocate) return -EOPNOTSUPP; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f7abff8c16ca..3cb528c4f27c 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -840,7 +840,15 @@ xfs_file_fallocate( goto out_unlock; } - ASSERT(offset + len < i_size_read(inode)); + /* + * There is no need to overlap collapse range with EOF, + * in which case it is effectively a truncate operation + */ + if (offset + len >= i_size_read(inode)) { + error = -EINVAL; + goto out_unlock; + } + new_size = i_size_read(inode) - len; error = xfs_collapse_file_space(ip, offset, len); -- GitLab From 0790b31b69374ddadefebb156251b319e5b43345 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Sat, 12 Apr 2014 10:05:37 -0400 Subject: [PATCH 097/797] fs: disallow all fallocate operation on active swapfile Currently some file system have IS_SWAPFILE check in their fallocate implementations and some do not. However we should really prevent any fallocate operation on swapfile so move the check to vfs and remove the redundant checks from the file systems fallocate implementations. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ceph/file.c | 3 --- fs/ext4/extents.c | 5 ----- fs/ext4/inode.c | 5 ----- fs/open.c | 7 +++++++ 4 files changed, 7 insertions(+), 13 deletions(-) diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 09c7afe32e49..596e6cc9f9c4 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -1215,9 +1215,6 @@ static long ceph_fallocate(struct file *file, int mode, if (!S_ISREG(inode->i_mode)) return -EOPNOTSUPP; - if (IS_SWAPFILE(inode)) - return -ETXTBSY; - mutex_lock(&inode->i_mutex); if (ceph_snap(inode) != CEPH_NOSNAP) { diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index ac5460d0d133..b2d3869b5762 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5405,11 +5405,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) goto out_mutex; } - if (IS_SWAPFILE(inode)) { - ret = -ETXTBSY; - goto out_mutex; - } - /* Currently just for extent based files */ if (!ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) { ret = -EOPNOTSUPP; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e2bba76f0d7b..b74cfd2a42ec 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3542,11 +3542,6 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) mutex_lock(&inode->i_mutex); - if (IS_SWAPFILE(inode)) { - ret = -ETXTBSY; - goto out_mutex; - } - /* No need to punch hole beyond i_size */ if (offset >= inode->i_size) goto out_mutex; diff --git a/fs/open.c b/fs/open.c index adf34202213a..7b823daa6a93 100644 --- a/fs/open.c +++ b/fs/open.c @@ -262,6 +262,13 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (IS_IMMUTABLE(inode)) return -EPERM; + /* + * We can not allow to do any fallocate operation on an active + * swapfile + */ + if (IS_SWAPFILE(inode)) + ret = -ETXTBSY; + /* * Revalidate the write permissions, in case security policy has * changed since the files were opened. -- GitLab From 6e6358fc3c3c862bfe9a5bc029d3f8ce43dc9765 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 12 Apr 2014 12:45:25 -0400 Subject: [PATCH 098/797] ext4: use i_size_read in ext4_unaligned_aio() We haven't taken i_mutex yet, so we need to use i_size_read(). Signed-off-by: "Theodore Ts'o" Cc: stable@vger.kernel.org --- fs/ext4/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 6db7f7db7777..bc765591101a 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -82,7 +82,7 @@ ext4_unaligned_aio(struct inode *inode, const struct iovec *iov, size_t count = iov_length(iov, nr_segs); loff_t final_size = pos + count; - if (pos >= inode->i_size) + if (pos >= i_size_read(inode)) return 0; if ((pos & blockmask) || (final_size & blockmask)) -- GitLab From 847c6c422aa0ae81a5517a9558ec2737806dca48 Mon Sep 17 00:00:00 2001 From: Zheng Liu Date: Sat, 12 Apr 2014 12:45:55 -0400 Subject: [PATCH 099/797] ext4: fix byte order problems introduced by the COLLAPSE_RANGE patches This commit tries to fix some byte order issues that is found by sparse check. $ make M=fs/ext4 C=2 CF=-D__CHECK_ENDIAN__ ... CHECK fs/ext4/extents.c fs/ext4/extents.c:5232:41: warning: restricted __le32 degrades to integer fs/ext4/extents.c:5236:52: warning: bad assignment (-=) to restricted __le32 fs/ext4/extents.c:5258:45: warning: bad assignment (-=) to restricted __le32 fs/ext4/extents.c:5303:28: warning: restricted __le32 degrades to integer fs/ext4/extents.c:5318:18: warning: incorrect type in assignment (different base types) fs/ext4/extents.c:5318:18: expected unsigned int [unsigned] [usertype] ex_start fs/ext4/extents.c:5318:18: got restricted __le32 [usertype] ee_block fs/ext4/extents.c:5319:24: warning: restricted __le32 degrades to integer fs/ext4/extents.c:5334:31: warning: incorrect type in assignment (different base types) ... Cc: Andreas Dilger Cc: Namjae Jeon Signed-off-by: Zheng Liu Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index b2d3869b5762..f24ef8697609 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5229,11 +5229,11 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, if (ex_start == EXT_FIRST_EXTENT(path[depth].p_hdr)) update = 1; - *start = ex_last->ee_block + + *start = le32_to_cpu(ex_last->ee_block) + ext4_ext_get_actual_len(ex_last); while (ex_start <= ex_last) { - ex_start->ee_block -= shift; + le32_add_cpu(&ex_start->ee_block, -shift); if (ex_start > EXT_FIRST_EXTENT(path[depth].p_hdr)) { if (ext4_ext_try_to_merge_right(inode, @@ -5255,7 +5255,7 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, if (err) goto out; - path[depth].p_idx->ei_block -= shift; + le32_add_cpu(&path[depth].p_idx->ei_block, -shift); err = ext4_ext_dirty(handle, inode, path + depth); if (err) goto out; @@ -5300,7 +5300,8 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, return ret; } - stop_block = extent->ee_block + ext4_ext_get_actual_len(extent); + stop_block = le32_to_cpu(extent->ee_block) + + ext4_ext_get_actual_len(extent); ext4_ext_drop_refs(path); kfree(path); @@ -5315,8 +5316,9 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, path = ext4_ext_find_extent(inode, start - 1, NULL, 0); depth = path->p_depth; extent = path[depth].p_ext; - ex_start = extent->ee_block; - ex_end = extent->ee_block + ext4_ext_get_actual_len(extent); + ex_start = le32_to_cpu(extent->ee_block); + ex_end = le32_to_cpu(extent->ee_block) + + ext4_ext_get_actual_len(extent); ext4_ext_drop_refs(path); kfree(path); @@ -5331,7 +5333,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, return PTR_ERR(path); depth = path->p_depth; extent = path[depth].p_ext; - current_block = extent->ee_block; + current_block = le32_to_cpu(extent->ee_block); if (start > current_block) { /* Hole, move to the next extent */ ret = mext_next_extent(inode, path, &extent); -- GitLab From 40c406c74eb9eed58ae7d4d12a0197f7279c9499 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 12 Apr 2014 22:53:53 -0400 Subject: [PATCH 100/797] ext4: COLLAPSE_RANGE only works on extent-based files Unfortunately, we weren't checking to make sure of this the inode was extent-based before attempt operate on it. Hilarity ensues. Signed-off-by: "Theodore Ts'o" Cc: Namjae Jeon --- fs/ext4/extents.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f24ef8697609..96e0a4bc8faa 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4878,9 +4878,6 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (mode & FALLOC_FL_PUNCH_HOLE) return ext4_punch_hole(inode, offset, len); - if (mode & FALLOC_FL_COLLAPSE_RANGE) - return ext4_collapse_range(inode, offset, len); - ret = ext4_convert_inline_data(inode); if (ret) return ret; @@ -4892,6 +4889,9 @@ long ext4_fallocate(struct file *file, int mode, loff_t offset, loff_t len) if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) return -EOPNOTSUPP; + if (mode & FALLOC_FL_COLLAPSE_RANGE) + return ext4_collapse_range(inode, offset, len); + if (mode & FALLOC_FL_ZERO_RANGE) return ext4_zero_range(file, offset, len, mode); -- GitLab From e2cbd587418251bb73c4c1e8e2c7c1816d7a98d9 Mon Sep 17 00:00:00 2001 From: jon ernst Date: Sat, 12 Apr 2014 23:01:28 -0400 Subject: [PATCH 101/797] ext4: silence sparse check warning for function ext4_trim_extent This fixes the following sparse warning: CHECK fs/ext4/mballoc.c fs/ext4/mballoc.c:5019:9: warning: context imbalance in 'ext4_trim_extent' - unexpected unlock Signed-off-by: "Jon Ernst" Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 73ccbb3b973b..c8238a26818c 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -5016,6 +5016,8 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, */ static int ext4_trim_extent(struct super_block *sb, int start, int count, ext4_group_t group, struct ext4_buddy *e4b) +__releases(bitlock) +__acquires(bitlock) { struct ext4_free_extent ex; int ret = 0; -- GitLab From 0229cdafb6f67064a217591d48b0f6abf14e8385 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 19 Mar 2014 18:36:39 +0100 Subject: [PATCH 102/797] iwlwifi: mvm: delay enabling smart FIFO until after beacon RX If we have no beacon data before association, delay smart FIFO enablement until after we have this data. Not doing so can cause association failures in extremely silent environments (usually only a shielded box/room) as beacon RX is not sent to the host immediately, and then the association time event ends without the host receiving any beacon even though it was on the air - it's just stuck on the FIFO. Cc: [3.14] Fixes: 1f3b0ff8ecce ("iwlwifi: mvm: Add Smart FIFO support") Signed-off-by: Johannes Berg Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 1 + drivers/net/wireless/iwlwifi/mvm/sf.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 4dd9ff43b8b6..f0cebf12c7b8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -1332,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, */ iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); + iwl_mvm_sf_update(mvm, vif, false); WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC)); } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | BSS_CHANGED_QOS)) { diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c index 8401627c0030..88809b2d1654 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/iwlwifi/mvm/sf.c @@ -274,7 +274,8 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif, return -EINVAL; if (changed_vif->type != NL80211_IFTYPE_STATION) { new_state = SF_UNINIT; - } else if (changed_vif->bss_conf.assoc) { + } else if (changed_vif->bss_conf.assoc && + changed_vif->bss_conf.dtim_period) { mvmvif = iwl_mvm_vif_from_mac80211(changed_vif); sta_id = mvmvif->ap_sta_id; new_state = SF_FULL_ON; -- GitLab From d9088f60425e0acd8a8f05fdfcfdd288d3258641 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 25 Mar 2014 10:25:44 +0200 Subject: [PATCH 103/797] iwlwifi: mvm: rs: fix mimo delimiter in LQ cmd mimo_delim was always set to 0 instead of pointing to the first SISO entry after MIMO rates. This can cause keep transmitting in MIMO even when we shouldn't. For example when the peer is requesting static SMPS. Cc: [3.14] Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 568abd61b14f..dd13629d0187 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -2547,6 +2547,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm, if (is_siso(&rate)) { num_rates = RS_SECONDARY_SISO_NUM_RATES; num_retries = RS_SECONDARY_SISO_RETRIES; + lq_cmd->mimo_delim = index; } else if (is_legacy(&rate)) { num_rates = RS_SECONDARY_LEGACY_NUM_RATES; num_retries = RS_LEGACY_RETRIES_PER_RATE; -- GitLab From fff47eb05a287e1a47836126573a750ff9ed22dd Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 2 Apr 2014 15:29:07 +0300 Subject: [PATCH 104/797] iwlwifi: mvm: BT Coex - send the new LUT upon antenna coupling change I forgot to send the new Look Up Table to the firmware and I also forgot to free the command which is kzalloc'ed. This code is relevant for 7265 device only. Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 685f7e8e6943..f9c7b302e3df 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -1262,6 +1262,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt = rxb_addr(rxb); u32 ant_isolation = le32_to_cpup((void *)pkt->data); u8 __maybe_unused lower_bound, upper_bound; + int ret; u8 lut; struct iwl_bt_coex_cmd *bt_cmd; @@ -1318,5 +1319,8 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20, sizeof(bt_cmd->bt4_corun_lut40)); - return 0; + ret = iwl_mvm_send_cmd(mvm, &cmd); + + kfree(bt_cmd); + return ret; } -- GitLab From 80f2679e589503bd6cbaaa1f9c1cd9dd7dfae032 Mon Sep 17 00:00:00 2001 From: Oren Givon Date: Wed, 2 Apr 2014 14:04:20 +0300 Subject: [PATCH 105/797] iwlwifi: add new 7265 HW IDs Add 2 new HW IDs for the 7265 series. Cc: [3.13+] Signed-off-by: Oren Givon Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/pcie/drv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index edb015c99049..3d1d57f9f5bc 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -373,12 +373,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x5102, iwl7265_n_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, + {IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)}, -- GitLab From 431031851ea72a25abb9ad4df56a0f3b997e3026 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 9 Apr 2014 19:27:25 +0300 Subject: [PATCH 106/797] iwlwifi: 7000: bump API to 9 This will allow to load the new firmware. Cc: [3.14] Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-7000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 003a546571d4..8425130273f6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -67,8 +67,8 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL7260_UCODE_API_MAX 8 -#define IWL3160_UCODE_API_MAX 8 +#define IWL7260_UCODE_API_MAX 9 +#define IWL3160_UCODE_API_MAX 9 /* Oldest version we won't warn about */ #define IWL7260_UCODE_API_OK 8 -- GitLab From adeb25905c644350baf1f446bcd856517e58060e Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Wed, 9 Apr 2014 10:20:39 +0800 Subject: [PATCH 107/797] iommu/vt-d: fix memory leakage caused by commit ea8ea46 Commit ea8ea46 "iommu/vt-d: Clean up and fix page table clear/free behaviour" introduces possible leakage of DMA page tables due to: for (pte = page_address(pg); !first_pte_in_page(pte); pte++) { if (dma_pte_present(pte) && !dma_pte_superpage(pte)) freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist); } For the first pte in a page, first_pte_in_page(pte) will always be true, thus dma_pte_list_pagetables() will never be called and leak DMA page tables if level is bigger than 1. Signed-off-by: Jiang Liu Signed-off-by: David Woodhouse --- drivers/iommu/intel-iommu.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 69fa7da5e48b..13dc2318e17a 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -1009,11 +1009,13 @@ static struct page *dma_pte_list_pagetables(struct dmar_domain *domain, if (level == 1) return freelist; - for (pte = page_address(pg); !first_pte_in_page(pte); pte++) { + pte = page_address(pg); + do { if (dma_pte_present(pte) && !dma_pte_superpage(pte)) freelist = dma_pte_list_pagetables(domain, level - 1, pte, freelist); - } + pte++; + } while (!first_pte_in_page(pte)); return freelist; } -- GitLab From 0ef36bd2b37815719e31a72d2beecc28ca8ecd26 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 9 Apr 2014 19:49:28 +0200 Subject: [PATCH 108/797] parisc: change value of SHMLBA from 0x00400000 to PAGE_SIZE On parisc, SHMLBA was defined to 0x00400000 (4MB) to reflect that we need to take care of our caches for shared mappings. But actually, we can map a file at any multiple address of PAGE_SIZE, so let us correct that now with a value of PAGE_SIZE for SHMLBA. Instead we now take care of this cache colouring via the constant SHM_COLOUR while we map shared pages. Signed-off-by: Helge Deller CC: Jeroen Roovers CC: John David Anglin CC: Carlos O'Donell Cc: stable@kernel.org [3.13+] --- arch/parisc/include/asm/shmparam.h | 5 ++--- arch/parisc/kernel/cache.c | 3 ++- arch/parisc/kernel/sys_parisc.c | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/parisc/include/asm/shmparam.h b/arch/parisc/include/asm/shmparam.h index 628ddc22faa8..afe1300ab667 100644 --- a/arch/parisc/include/asm/shmparam.h +++ b/arch/parisc/include/asm/shmparam.h @@ -1,8 +1,7 @@ #ifndef _ASMPARISC_SHMPARAM_H #define _ASMPARISC_SHMPARAM_H -#define __ARCH_FORCE_SHMLBA 1 - -#define SHMLBA 0x00400000 /* attach addr needs to be 4 Mb aligned */ +#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ +#define SHM_COLOUR 0x00400000 /* shared mappings colouring */ #endif /* _ASMPARISC_SHMPARAM_H */ diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index a6ffc775a9f8..f6448c7c62b5 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -323,7 +323,8 @@ void flush_dcache_page(struct page *page) * specifically accesses it, of course) */ flush_tlb_page(mpnt, addr); - if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) { + if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1)) + != (addr & (SHM_COLOUR - 1))) { __flush_cache_page(mpnt, addr, page_to_phys(page)); if (old_addr) printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)"); diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index b7cadc4a06cd..31ffa9b55322 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -45,7 +45,7 @@ static int get_offset(unsigned int last_mmap) { - return (last_mmap & (SHMLBA-1)) >> PAGE_SHIFT; + return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT; } static unsigned long shared_align_offset(unsigned int last_mmap, @@ -57,8 +57,8 @@ static unsigned long shared_align_offset(unsigned int last_mmap, static inline unsigned long COLOR_ALIGN(unsigned long addr, unsigned int last_mmap, unsigned long pgoff) { - unsigned long base = (addr+SHMLBA-1) & ~(SHMLBA-1); - unsigned long off = (SHMLBA-1) & + unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1); + unsigned long off = (SHM_COLOUR-1) & (shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT); return base + off; @@ -101,7 +101,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, if (flags & MAP_FIXED) { if ((flags & MAP_SHARED) && last_mmap && (addr - shared_align_offset(last_mmap, pgoff)) - & (SHMLBA - 1)) + & (SHM_COLOUR - 1)) return -EINVAL; goto found_addr; } @@ -122,7 +122,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, info.length = len; info.low_limit = mm->mmap_legacy_base; info.high_limit = mmap_upper_limit(); - info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0; + info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0; info.align_offset = shared_align_offset(last_mmap, pgoff); addr = vm_unmapped_area(&info); @@ -161,7 +161,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, if (flags & MAP_FIXED) { if ((flags & MAP_SHARED) && last_mmap && (addr - shared_align_offset(last_mmap, pgoff)) - & (SHMLBA - 1)) + & (SHM_COLOUR - 1)) return -EINVAL; goto found_addr; } @@ -182,7 +182,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.length = len; info.low_limit = PAGE_SIZE; info.high_limit = mm->mmap_base; - info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0; + info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0; info.align_offset = shared_align_offset(last_mmap, pgoff); addr = vm_unmapped_area(&info); if (!(addr & ~PAGE_MASK)) -- GitLab From ab3e55b119c9653b19ea4edffb86f04db867ac98 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Sun, 13 Apr 2014 00:03:55 +0200 Subject: [PATCH 109/797] parisc: fix epoll_pwait syscall on compat kernel This bug was detected with the libio-epoll-perl debian package where the test case IO-Ppoll-compat.t failed. Signed-off-by: Helge Deller CC: stable@kernel.org # 3.0+ --- arch/parisc/kernel/syscall_table.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 80e5dd248934..83ead0ea127d 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S @@ -392,7 +392,7 @@ ENTRY_COMP(vmsplice) ENTRY_COMP(move_pages) /* 295 */ ENTRY_SAME(getcpu) - ENTRY_SAME(epoll_pwait) + ENTRY_COMP(epoll_pwait) ENTRY_COMP(statfs64) ENTRY_COMP(fstatfs64) ENTRY_COMP(kexec_load) /* 300 */ -- GitLab From 08a732f4e4a842f0101e5ea03d79e9d613ffadbe Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 24 Mar 2014 22:17:15 +0200 Subject: [PATCH 110/797] iwlwifi: add MODULE_FIRMWARE for 7265 It was missing. Cc: [3.13+] Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/iwl-7000.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 8425130273f6..4c2d4ef28b22 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -244,3 +244,4 @@ const struct iwl_cfg iwl7265_n_cfg = { MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); +MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); -- GitLab From 198266a3c110e8a68895a24e937003f5da0c5f60 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Mon, 31 Mar 2014 22:37:39 +0300 Subject: [PATCH 111/797] iwlwifi: mvm: rs: use correct max expected throughput figures The selection of the max expected throughput for a column didn't take into account the maximal allowed rate for the current peer. This can cause unnecessary switches during the search cycle to columns which have no chance of beating the current throughput. Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 55 ++++++++++++++++++++------- drivers/net/wireless/iwlwifi/mvm/rs.h | 12 ++++-- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index dd13629d0187..cd32ad54384e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1186,9 +1186,26 @@ static void rs_set_stay_in_table(struct iwl_mvm *mvm, u8 is_legacy, lq_sta->visited_columns = 0; } +static int rs_get_max_allowed_rate(struct iwl_lq_sta *lq_sta, + const struct rs_tx_column *column) +{ + switch (column->mode) { + case RS_LEGACY: + return lq_sta->max_legacy_rate_idx; + case RS_SISO: + return lq_sta->max_siso_rate_idx; + case RS_MIMO2: + return lq_sta->max_mimo2_rate_idx; + default: + WARN_ON_ONCE(1); + } + + return lq_sta->max_legacy_rate_idx; +} + static const u16 *rs_get_expected_tpt_table(struct iwl_lq_sta *lq_sta, - const struct rs_tx_column *column, - u32 bw) + const struct rs_tx_column *column, + u32 bw) { /* Used to choose among HT tables */ const u16 (*ht_tbl_pointer)[IWL_RATE_COUNT]; @@ -1485,14 +1502,14 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct iwl_scale_tbl_info *tbl) { - int i, j, n; + int i, j, max_rate; enum rs_column next_col_id; const struct rs_tx_column *curr_col = &rs_tx_columns[tbl->column]; const struct rs_tx_column *next_col; allow_column_func_t allow_func; u8 valid_ants = mvm->fw->valid_tx_ant; const u16 *expected_tpt_tbl; - s32 tpt, max_expected_tpt; + u16 tpt, max_expected_tpt; for (i = 0; i < MAX_NEXT_COLUMNS; i++) { next_col_id = curr_col->next_columns[i]; @@ -1535,11 +1552,11 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm, if (WARN_ON_ONCE(!expected_tpt_tbl)) continue; - max_expected_tpt = 0; - for (n = 0; n < IWL_RATE_COUNT; n++) - if (expected_tpt_tbl[n] > max_expected_tpt) - max_expected_tpt = expected_tpt_tbl[n]; + max_rate = rs_get_max_allowed_rate(lq_sta, next_col); + if (WARN_ON_ONCE(max_rate == IWL_RATE_INVALID)) + continue; + max_expected_tpt = expected_tpt_tbl[max_rate]; if (tpt >= max_expected_tpt) { IWL_DEBUG_RATE(mvm, "Skip column %d: can't beat current TPT. Max expected %d current %d\n", @@ -1547,14 +1564,15 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm, continue; } + IWL_DEBUG_RATE(mvm, + "Found potential column %d. Max expected %d current %d\n", + next_col_id, max_expected_tpt, tpt); break; } if (i == MAX_NEXT_COLUMNS) return RS_COLUMN_INVALID; - IWL_DEBUG_RATE(mvm, "Found potential column %d\n", next_col_id); - return next_col_id; } @@ -2388,11 +2406,22 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, lq_sta->is_vht = true; } - IWL_DEBUG_RATE(mvm, - "SISO-RATE=%X MIMO2-RATE=%X VHT=%d\n", + lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, + BITS_PER_LONG); + lq_sta->max_siso_rate_idx = find_last_bit(&lq_sta->active_siso_rate, + BITS_PER_LONG); + lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, + BITS_PER_LONG); + + IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n", + lq_sta->active_legacy_rate, lq_sta->active_siso_rate, lq_sta->active_mimo2_rate, lq_sta->is_vht); + IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", + lq_sta->max_legacy_rate_idx, + lq_sta->max_siso_rate_idx, + lq_sta->max_mimo2_rate_idx); /* These values will be overridden later */ lq_sta->lq.single_stream_ant_msk = @@ -2750,7 +2779,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, return -ENOMEM; desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); - desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", + desc += sprintf(buff+desc, "failed=%d success=%d rate=0%lX\n", lq_sta->total_failed, lq_sta->total_success, lq_sta->active_legacy_rate); desc += sprintf(buff+desc, "fixed rate 0x%X\n", diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index 3332b396011e..9892d92d5901 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h @@ -314,9 +314,15 @@ struct iwl_lq_sta { enum ieee80211_band band; /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ - u16 active_legacy_rate; - u16 active_siso_rate; - u16 active_mimo2_rate; + unsigned long active_legacy_rate; + unsigned long active_siso_rate; + unsigned long active_mimo2_rate; + + /* Highest rate per Tx mode */ + u8 max_legacy_rate_idx; + u8 max_siso_rate_idx; + u8 max_mimo2_rate_idx; + s8 max_rate_idx; /* Max rate set by user */ u8 missed_rate_counter; -- GitLab From e53839eb9882c99d3781eab0fe1b2d4369a6a2cc Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 6 Apr 2014 02:42:18 +0300 Subject: [PATCH 112/797] iwlwifi: mvm: rs: fix and cleanup rs_get_rate_action Change the down/upscale decision logic a bit to be based on different success ratio thresholds. This fixes the implementation compared to the rate scale algorithm which was planned to yield optimal results. Also fix a case where a lower rate wasn't explored despite being a potential for better throughput. While at it rewrite rs_get_rate_action to be more clear and clean. Cc: [3.14] Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 127 ++++++++++++-------------- drivers/net/wireless/iwlwifi/mvm/rs.h | 1 + 2 files changed, 60 insertions(+), 68 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index cd32ad54384e..97b8fac214a1 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -1658,85 +1658,76 @@ static enum rs_action rs_get_rate_action(struct iwl_mvm *mvm, { enum rs_action action = RS_ACTION_STAY; - /* Too many failures, decrease rate */ if ((sr <= RS_SR_FORCE_DECREASE) || (current_tpt == 0)) { IWL_DEBUG_RATE(mvm, - "decrease rate because of low SR\n"); - action = RS_ACTION_DOWNSCALE; - /* No throughput measured yet for adjacent rates; try increase. */ - } else if ((low_tpt == IWL_INVALID_VALUE) && - (high_tpt == IWL_INVALID_VALUE)) { - if (high != IWL_RATE_INVALID && sr >= IWL_RATE_INCREASE_TH) { - IWL_DEBUG_RATE(mvm, - "Good SR and no high rate measurement. " - "Increase rate\n"); - action = RS_ACTION_UPSCALE; - } else if (low != IWL_RATE_INVALID) { - IWL_DEBUG_RATE(mvm, - "Remain in current rate\n"); - action = RS_ACTION_STAY; - } + "Decrease rate because of low SR\n"); + return RS_ACTION_DOWNSCALE; } - /* Both adjacent throughputs are measured, but neither one has better - * throughput; we're using the best rate, don't change it! - */ - else if ((low_tpt != IWL_INVALID_VALUE) && - (high_tpt != IWL_INVALID_VALUE) && - (low_tpt < current_tpt) && - (high_tpt < current_tpt)) { + if ((low_tpt == IWL_INVALID_VALUE) && + (high_tpt == IWL_INVALID_VALUE) && + (high != IWL_RATE_INVALID)) { IWL_DEBUG_RATE(mvm, - "Both high and low are worse. " - "Maintain rate\n"); - action = RS_ACTION_STAY; + "No data about high/low rates. Increase rate\n"); + return RS_ACTION_UPSCALE; } - /* At least one adjacent rate's throughput is measured, - * and may have better performance. - */ - else { - /* Higher adjacent rate's throughput is measured */ - if (high_tpt != IWL_INVALID_VALUE) { - /* Higher rate has better throughput */ - if (high_tpt > current_tpt && - sr >= IWL_RATE_INCREASE_TH) { - IWL_DEBUG_RATE(mvm, - "Higher rate is better and good " - "SR. Increate rate\n"); - action = RS_ACTION_UPSCALE; - } else { - IWL_DEBUG_RATE(mvm, - "Higher rate isn't better OR " - "no good SR. Maintain rate\n"); - action = RS_ACTION_STAY; - } + if ((high_tpt == IWL_INVALID_VALUE) && + (high != IWL_RATE_INVALID) && + (low_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt)) { + IWL_DEBUG_RATE(mvm, + "No data about high rate and low rate is worse. Increase rate\n"); + return RS_ACTION_UPSCALE; + } - /* Lower adjacent rate's throughput is measured */ - } else if (low_tpt != IWL_INVALID_VALUE) { - /* Lower rate has better throughput */ - if (low_tpt > current_tpt) { - IWL_DEBUG_RATE(mvm, - "Lower rate is better. " - "Decrease rate\n"); - action = RS_ACTION_DOWNSCALE; - } else if (sr >= IWL_RATE_INCREASE_TH) { - IWL_DEBUG_RATE(mvm, - "Lower rate isn't better and " - "good SR. Increase rate\n"); - action = RS_ACTION_UPSCALE; - } - } + if ((high_tpt != IWL_INVALID_VALUE) && + (high_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Higher rate is better. Increate rate\n"); + return RS_ACTION_UPSCALE; } - /* Sanity check; asked for decrease, but success rate or throughput - * has been good at old rate. Don't change it. - */ - if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID) && - ((sr > IWL_RATE_HIGH_TH) || - (current_tpt > (100 * tbl->expected_tpt[low])))) { + if ((low_tpt != IWL_INVALID_VALUE) && + (high_tpt != IWL_INVALID_VALUE) && + (low_tpt < current_tpt) && + (high_tpt < current_tpt)) { IWL_DEBUG_RATE(mvm, - "Sanity check failed. Maintain rate\n"); - action = RS_ACTION_STAY; + "Both high and low are worse. Maintain rate\n"); + return RS_ACTION_STAY; + } + + if ((low_tpt != IWL_INVALID_VALUE) && + (low_tpt > current_tpt)) { + IWL_DEBUG_RATE(mvm, + "Lower rate is better\n"); + action = RS_ACTION_DOWNSCALE; + goto out; + } + + if ((low_tpt == IWL_INVALID_VALUE) && + (low != IWL_RATE_INVALID)) { + IWL_DEBUG_RATE(mvm, + "No data about lower rate\n"); + action = RS_ACTION_DOWNSCALE; + goto out; + } + + IWL_DEBUG_RATE(mvm, "Maintain rate\n"); + +out: + if ((action == RS_ACTION_DOWNSCALE) && (low != IWL_RATE_INVALID)) { + if (sr >= RS_SR_NO_DECREASE) { + IWL_DEBUG_RATE(mvm, + "SR is above NO DECREASE. Avoid downscale\n"); + action = RS_ACTION_STAY; + } else if (current_tpt > (100 * tbl->expected_tpt[low])) { + IWL_DEBUG_RATE(mvm, + "Current TPT is higher than max expected in low rate. Avoid downscale\n"); + action = RS_ACTION_STAY; + } else { + IWL_DEBUG_RATE(mvm, "Decrease rate\n"); + } } return action; diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index 9892d92d5901..fbb476aadb22 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h @@ -156,6 +156,7 @@ enum { #define IWL_RATE_HIGH_TH 10880 /* 85% */ #define IWL_RATE_INCREASE_TH 6400 /* 50% */ #define RS_SR_FORCE_DECREASE 1920 /* 15% */ +#define RS_SR_NO_DECREASE 10880 /* 85% */ #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ #define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) -- GitLab From 87d5e4155c0088e6766b4f0193b63fa0eab71220 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 6 Apr 2014 18:13:22 +0300 Subject: [PATCH 113/797] iwlwifi: mvm: rs: reinit rs if no tx for a long time After being idle for a long time (>5sec) the rs statistics will be stale so we prefer to reset rs and start from legacy rates again. This gives better results when the attenuation increased signficantly (e.g. we got further from the AP) and after a while we start Tx Note that the first Tx after the idle period will still go out in the old modulation and rate but this seemed a simpler approach compared to adding a timer or modifying mac80211 for this. The negative impact is negligble as we'll recover quickly. Cc: [3.14] Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 22 +++++++++++++++++++++- drivers/net/wireless/iwlwifi/mvm/rs.h | 1 + 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 97b8fac214a1..0d03dcd2fc3d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -59,7 +59,7 @@ /* max allowed rate miss before sync LQ cmd */ #define IWL_MISSED_RATE_MAX 15 #define RS_STAY_IN_COLUMN_TIMEOUT (5*HZ) - +#define RS_IDLE_TIMEOUT (5*HZ) static u8 rs_ht_to_legacy[] = { [IWL_RATE_MCS_0_INDEX] = IWL_RATE_6M_INDEX, @@ -992,6 +992,13 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband, return; } +#ifdef CPTCFG_MAC80211_DEBUGFS + /* Disable last tx check if we are debugging with fixed rate */ + if (lq_sta->dbg_fixed_rate) { + IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n"); + return; + } +#endif if (!ieee80211_is_data(hdr->frame_control) || info->flags & IEEE80211_TX_CTL_NO_ACK) return; @@ -1034,6 +1041,18 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband, mac_index++; } + if (time_after(jiffies, + (unsigned long)(lq_sta->last_tx + RS_IDLE_TIMEOUT))) { + int tid; + IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n"); + for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) + ieee80211_stop_tx_ba_session(sta, tid); + + iwl_mvm_rs_rate_init(mvm, sta, sband->band, false); + return; + } + lq_sta->last_tx = jiffies; + /* Here we actually compare this rate to the latest LQ command */ if ((mac_index < 0) || (rate.sgi != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || @@ -2354,6 +2373,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, rs_rate_scale_clear_tbl_windows(&lq_sta->lq_info[j]); lq_sta->flush_timer = 0; + lq_sta->last_tx = jiffies; IWL_DEBUG_RATE(mvm, "LQ: *** rate scale station global init for station %d ***\n", diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index fbb476aadb22..0acfac96a56c 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h @@ -311,6 +311,7 @@ struct iwl_lq_sta { u32 visited_columns; /* Bitmask marking which Tx columns were * explored during a search cycle */ + u64 last_tx; bool is_vht; enum ieee80211_band band; -- GitLab From fd7dbee51b3d98402edb11fec0c93d96476e0ae1 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 6 Apr 2014 04:39:23 +0300 Subject: [PATCH 114/797] iwlwifi: mvm: rs: fallback to legacy Tx columns Allow switching back to legacy Tx columns so we'll stop doing HT/VHT in case we're far from the AP. Stop active aggregation when making a deciding to stay in a legacy column. Despite having low legacy rates in the LQ table lower entries it doesn't help much in case we're doing aggregations as the aggregation was being transmitted in the initial rate of the table. This should help traffic stalls when far from the AP. Cc: [3.14] Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 30 +++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 0d03dcd2fc3d..b007db9cf3aa 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -142,7 +142,7 @@ enum rs_column_mode { RS_MIMO2, }; -#define MAX_NEXT_COLUMNS 5 +#define MAX_NEXT_COLUMNS 7 #define MAX_COLUMN_CHECKS 3 typedef bool (*allow_column_func_t) (struct iwl_mvm *mvm, @@ -214,6 +214,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_B, RS_COLUMN_MIMO2, RS_COLUMN_MIMO2_SGI, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, }, }, [RS_COLUMN_LEGACY_ANT_B] = { @@ -225,6 +227,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_B, RS_COLUMN_MIMO2, RS_COLUMN_MIMO2_SGI, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, }, }, [RS_COLUMN_SISO_ANT_A] = { @@ -236,6 +240,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_A_SGI, RS_COLUMN_SISO_ANT_B_SGI, RS_COLUMN_MIMO2_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, }, .checks = { rs_siso_allow, @@ -250,6 +256,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_B_SGI, RS_COLUMN_SISO_ANT_A_SGI, RS_COLUMN_MIMO2_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, }, .checks = { rs_siso_allow, @@ -265,6 +273,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_A, RS_COLUMN_SISO_ANT_B, RS_COLUMN_MIMO2, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, }, .checks = { rs_siso_allow, @@ -281,6 +291,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_B, RS_COLUMN_SISO_ANT_A, RS_COLUMN_MIMO2, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, }, .checks = { rs_siso_allow, @@ -296,6 +308,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_A_SGI, RS_COLUMN_SISO_ANT_B_SGI, RS_COLUMN_MIMO2_SGI, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, }, .checks = { rs_mimo_allow, @@ -311,6 +325,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_SISO_ANT_A, RS_COLUMN_SISO_ANT_B, RS_COLUMN_MIMO2, + RS_COLUMN_LEGACY_ANT_A, + RS_COLUMN_LEGACY_ANT_B, }, .checks = { rs_mimo_allow, @@ -2070,8 +2086,18 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, * stay with best antenna legacy modulation for a while * before next round of mode comparisons. */ tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); - if (is_legacy(&tbl1->rate) && !sta->ht_cap.ht_supported) { + if (is_legacy(&tbl1->rate)) { IWL_DEBUG_RATE(mvm, "LQ: STAY in legacy table\n"); + + if (tid != IWL_MAX_TID_COUNT) { + tid_data = &sta_priv->tid_data[tid]; + if (tid_data->state != IWL_AGG_OFF) { + IWL_DEBUG_RATE(mvm, + "Stop aggregation on tid %d\n", + tid); + ieee80211_stop_tx_ba_session(sta, tid); + } + } rs_set_stay_in_table(mvm, 1, lq_sta); } else { /* If we're in an HT mode, and all 3 mode switch actions -- GitLab From d8fff919ecd7820084675c2814913445e95640ac Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 6 Apr 2014 05:27:36 +0300 Subject: [PATCH 115/797] iwlwifi: mvm: avoid searching unnecessary columns Don't search columns which are unlikely to succeed as previous columns searched with less aggressive modulation failed. Cc: [3.14] Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index b007db9cf3aa..5cab26ecc17a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -212,8 +212,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_LEGACY_ANT_B, RS_COLUMN_SISO_ANT_A, RS_COLUMN_SISO_ANT_B, - RS_COLUMN_MIMO2, - RS_COLUMN_MIMO2_SGI, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, RS_COLUMN_INVALID, RS_COLUMN_INVALID, }, @@ -225,8 +225,8 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_LEGACY_ANT_A, RS_COLUMN_SISO_ANT_A, RS_COLUMN_SISO_ANT_B, - RS_COLUMN_MIMO2, - RS_COLUMN_MIMO2_SGI, + RS_COLUMN_INVALID, + RS_COLUMN_INVALID, RS_COLUMN_INVALID, RS_COLUMN_INVALID, }, @@ -239,9 +239,9 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_MIMO2, RS_COLUMN_SISO_ANT_A_SGI, RS_COLUMN_SISO_ANT_B_SGI, - RS_COLUMN_MIMO2_SGI, RS_COLUMN_LEGACY_ANT_A, RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, }, .checks = { rs_siso_allow, @@ -255,9 +255,9 @@ static const struct rs_tx_column rs_tx_columns[] = { RS_COLUMN_MIMO2, RS_COLUMN_SISO_ANT_B_SGI, RS_COLUMN_SISO_ANT_A_SGI, - RS_COLUMN_MIMO2_SGI, RS_COLUMN_LEGACY_ANT_A, RS_COLUMN_LEGACY_ANT_B, + RS_COLUMN_INVALID, }, .checks = { rs_siso_allow, -- GitLab From b804eeb6649d75caeccbeae9f5623fc7b8bdfdfa Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 6 Apr 2014 04:27:06 +0300 Subject: [PATCH 116/797] iwlwifi: mvm: rs: clear per rate stats when aggregation changes The per rate stats should be cleared when aggregation state changes to avoid making rate scale decisions based on throughput figures which were collected prior to the aggregation state change and are now stale. While at it make sure any clearing of the per rate stats will get logged. Cc: [3.14] Signed-off-by: Eyal Shapira Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/rs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 5cab26ecc17a..9f52c5b3f0ec 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -519,10 +519,12 @@ static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) window->average_tpt = IWL_INVALID_VALUE; } -static void rs_rate_scale_clear_tbl_windows(struct iwl_scale_tbl_info *tbl) +static void rs_rate_scale_clear_tbl_windows(struct iwl_mvm *mvm, + struct iwl_scale_tbl_info *tbl) { int i; + IWL_DEBUG_RATE(mvm, "Clearing up window stats\n"); for (i = 0; i < IWL_RATE_COUNT; i++) rs_rate_scale_clear_window(&tbl->win[i]); } @@ -1490,7 +1492,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) IWL_DEBUG_RATE(mvm, "LQ: stay in table clear win\n"); - rs_rate_scale_clear_tbl_windows(tbl); + rs_rate_scale_clear_tbl_windows(mvm, tbl); } } @@ -1498,8 +1500,7 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) * bitmaps and stats in active table (this will become the new * "search" table). */ if (lq_sta->rs_state == RS_STATE_SEARCH_CYCLE_STARTED) { - IWL_DEBUG_RATE(mvm, "Clearing up window stats\n"); - rs_rate_scale_clear_tbl_windows(tbl); + rs_rate_scale_clear_tbl_windows(mvm, tbl); } } } @@ -1836,6 +1837,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, "Aggregation changed: prev %d current %d. Update expected TPT table\n", prev_agg, lq_sta->is_agg); rs_set_expected_tpt_table(lq_sta, tbl); + rs_rate_scale_clear_tbl_windows(mvm, tbl); } /* current tx rate */ @@ -2065,7 +2067,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, if (lq_sta->search_better_tbl) { /* Access the "search" table, clear its history. */ tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); - rs_rate_scale_clear_tbl_windows(tbl); + rs_rate_scale_clear_tbl_windows(mvm, tbl); /* Use new "search" start rate */ index = tbl->rate.index; @@ -2396,7 +2398,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, lq_sta->lq.sta_id = sta_priv->sta_id; for (j = 0; j < LQ_SIZE; j++) - rs_rate_scale_clear_tbl_windows(&lq_sta->lq_info[j]); + rs_rate_scale_clear_tbl_windows(mvm, &lq_sta->lq_info[j]); lq_sta->flush_timer = 0; lq_sta->last_tx = jiffies; -- GitLab From a6bc92803e7f765e02c923cf37c8e280e729642a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 13 Apr 2014 15:51:41 +0300 Subject: [PATCH 117/797] iwlwifi: mvm: BT Coex - fix Look Up Table A few entries were wrong and this caused throughput issues. Cc: [3.13+] Fixes: dac94da8dba3 ("iwlwifi: mvm: new BT Coex API") Signed-off-by: Emmanuel Grumbach --- drivers/net/wireless/iwlwifi/mvm/coex.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index f9c7b302e3df..fa858d548d13 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c @@ -190,7 +190,7 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = { cpu_to_le32(0xcc00aaaa), cpu_to_le32(0x0000aaaa), cpu_to_le32(0xc0004000), - cpu_to_le32(0x00000000), + cpu_to_le32(0x00004000), cpu_to_le32(0xf0005000), cpu_to_le32(0xf0005000), }, @@ -213,16 +213,16 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = { /* Tx Tx disabled */ cpu_to_le32(0xaaaaaaaa), cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xeeaaaaaa), cpu_to_le32(0xaaaaaaaa), cpu_to_le32(0xcc00ff28), cpu_to_le32(0x0000aaaa), cpu_to_le32(0xcc00aaaa), cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xC0004000), - cpu_to_le32(0xC0004000), - cpu_to_le32(0xF0005000), - cpu_to_le32(0xF0005000), + cpu_to_le32(0xc0004000), + cpu_to_le32(0xc0004000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), }, }; -- GitLab From 8dc79ec4c0537e1b83c0739af82a7babefb30012 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Sun, 13 Apr 2014 15:05:42 -0400 Subject: [PATCH 118/797] ext4: fix error handling in ext4_ext_shift_extents Fix error handling by adding some. :-) Signed-off-by: Dmitry Monakhov Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 96e0a4bc8faa..38be06354b88 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5314,11 +5314,18 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, * enough to accomodate the shift. */ path = ext4_ext_find_extent(inode, start - 1, NULL, 0); + if (IS_ERR(path)) + return PTR_ERR(path); depth = path->p_depth; extent = path[depth].p_ext; - ex_start = le32_to_cpu(extent->ee_block); - ex_end = le32_to_cpu(extent->ee_block) + + if (extent) { + ex_start = le32_to_cpu(extent->ee_block); + ex_end = le32_to_cpu(extent->ee_block) + ext4_ext_get_actual_len(extent); + } else { + ex_start = 0; + ex_end = 0; + } ext4_ext_drop_refs(path); kfree(path); -- GitLab From a18ed359bdddcded4f97ff5e2f07793ff9336913 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Sun, 13 Apr 2014 15:41:13 -0400 Subject: [PATCH 119/797] ext4: always check ext4_ext_find_extent result Where are some places where logic guaranties us that extent we are searching exits, but this may not be true due to on-disk data corruption. If such corruption happens we must prevent possible null pointer dereferences. Signed-off-by: Dmitry Monakhov Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 38be06354b88..64b400356cad 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3313,6 +3313,11 @@ static int ext4_split_extent(handle_t *handle, return PTR_ERR(path); depth = ext_depth(inode); ex = path[depth].p_ext; + if (!ex) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) map->m_lblk); + return -EIO; + } uninitialized = ext4_ext_is_uninitialized(ex); split_flag1 = 0; @@ -3694,6 +3699,12 @@ static int ext4_convert_initialized_extents(handle_t *handle, } depth = ext_depth(inode); ex = path[depth].p_ext; + if (!ex) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) map->m_lblk); + err = -EIO; + goto out; + } } err = ext4_ext_get_access(handle, inode, path + depth); @@ -5340,6 +5351,12 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, return PTR_ERR(path); depth = path->p_depth; extent = path[depth].p_ext; + if (!extent) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) start); + return -EIO; + } + current_block = le32_to_cpu(extent->ee_block); if (start > current_block) { /* Hole, move to the next extent */ -- GitLab From 07134a365f1c4be6e840a00ae452d1593f15c5fc Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 5 Mar 2014 14:25:50 +0100 Subject: [PATCH 120/797] ARM: dts: imx6: add PCIe interrupt mapping properties As defined by the common PCI bindings. Signed-off-by: Lucas Stach Acked-by: Arnd Bergmann Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 55cb926fa3f7..e27408f5371f 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -10,6 +10,8 @@ * http://www.gnu.org/copyleft/gpl.html */ +#include + #include "skeleton.dtsi" / { @@ -138,6 +140,12 @@ 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */ num-lanes = <1>; interrupts = <0 123 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clks 189>, <&clks 187>, <&clks 206>, <&clks 144>; clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi"; status = "disabled"; -- GitLab From 2b33319003bfd97decd9b4768ecfe70a6dfdba53 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 28 Mar 2014 02:09:13 -0300 Subject: [PATCH 121/797] ARM: dts: imx53-qsb-common: Fix memory region description On mx53qsb there are two DRAM chip selects: CS0 at 0x70000000 CS1 at 0xb0000000 Each bank has a 512MB DRAM, giving a total of 1GB of system DRAM. Fix the memory layout to describe the hardware appropriately. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-qsb-common.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-qsb-common.dtsi b/arch/arm/boot/dts/imx53-qsb-common.dtsi index 3f825a6813da..ede04fa4161f 100644 --- a/arch/arm/boot/dts/imx53-qsb-common.dtsi +++ b/arch/arm/boot/dts/imx53-qsb-common.dtsi @@ -14,7 +14,8 @@ / { memory { - reg = <0x70000000 0x40000000>; + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; }; display0: display@di0 { -- GitLab From 8668d49896cc19354917ff67503e72f3f48ffaaa Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 28 Mar 2014 02:09:14 -0300 Subject: [PATCH 122/797] ARM: dts: imx53-m53evk: Fix memory region description On m53evk there are two DRAM chip selects: CS0 at 0x70000000 CS1 at 0xb0000000 Each bank has a 512MB DRAM, giving a total of 1GB of system DRAM. Fix the memory layout to describe the hardware appropriately. Signed-off-by: Fabio Estevam Acked-by: Marek Vasut Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-m53evk.dts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index f6d3ac3e5587..7fa2d1b5d60e 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -17,7 +17,8 @@ compatible = "denx,imx53-m53evk", "fsl,imx53"; memory { - reg = <0x70000000 0x20000000>; + reg = <0x70000000 0x20000000>, + <0xb0000000 0x20000000>; }; soc { -- GitLab From 7b6b2f4bf76e72d0599bd0d4ca1c850f8308d50f Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 2 Apr 2014 19:05:37 +0200 Subject: [PATCH 123/797] ARM: dts: mx5: fix wrong stmpe-ts bindings Fix bindings for STMPE touchscreen controller to match the documented bindings and the actual bindings used by the driver. Signed-off-by: Stefan Agner Reviewed-by: Marek Vasut Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-m53evk.dts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index 7fa2d1b5d60e..d5d146a8b149 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -194,17 +194,17 @@ irq-trigger = <0x1>; stmpe_touchscreen { - compatible = "stmpe,ts"; + compatible = "st,stmpe-ts"; reg = <0>; - ts,sample-time = <4>; - ts,mod-12b = <1>; - ts,ref-sel = <0>; - ts,adc-freq = <1>; - ts,ave-ctrl = <3>; - ts,touch-det-delay = <3>; - ts,settling = <4>; - ts,fraction-z = <7>; - ts,i-drive = <1>; + st,sample-time = <4>; + st,mod-12b = <1>; + st,ref-sel = <0>; + st,adc-freq = <1>; + st,ave-ctrl = <3>; + st,touch-det-delay = <3>; + st,settling = <4>; + st,fraction-z = <7>; + st,i-drive = <1>; }; }; -- GitLab From 54e8eaeec1227a024373e37315770cc79d69917b Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 28 Mar 2014 17:25:51 +0100 Subject: [PATCH 124/797] ARM: dts: imx: drop invalid size and address cells properties Those two properties should have been set to zero, which is the same as not specifying them. Having address-cells set to 1 causes OF interrupt mapping routines to add 1 to the interrupt-cells property and as result fail because all calculations are off by one. Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl.dtsi | 2 -- arch/arm/boot/dts/imx6sl.dtsi | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index e27408f5371f..2d04a5185fe9 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -48,8 +48,6 @@ intc: interrupt-controller@00a01000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; interrupt-controller; reg = <0x00a01000 0x1000>, <0x00a00100 0x100>; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index 3cb4941afeef..d92df0ab02e4 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -68,8 +68,6 @@ intc: interrupt-controller@00a01000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; interrupt-controller; reg = <0x00a01000 0x1000>, <0x00a00100 0x100>; -- GitLab From c2bece3cb1215bdb68f2345f6a9b5d0b27c8724e Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 28 Mar 2014 17:52:52 +0100 Subject: [PATCH 125/797] ARM: imx6q-clk: parent lvds_gate from lvds_sel Allows fror proper refcounting of the parent clocks when enabling the clock output on CLK1/2 pads. Signed-off-by: Lucas Stach Reviewed-by: Marek Vasut Acked-by: Richard Zhu Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index b0e7f9d2c245..3ed67b592b48 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -208,8 +208,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) * the "output_enable" bit as a gate, even though it's really just * enabling clock output. */ - clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "dummy", base + 0x160, 10); - clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "dummy", base + 0x160, 11); + clk[lvds1_gate] = imx_clk_gate("lvds1_gate", "lvds1_sel", base + 0x160, 10); + clk[lvds2_gate] = imx_clk_gate("lvds2_gate", "lvds2_sel", base + 0x160, 11); /* name parent_name reg idx */ clk[pll2_pfd0_352m] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); -- GitLab From 2e3b9650561ae791ca0bd8c5f4868ef4df3cb842 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 6 Apr 2014 23:32:25 +0100 Subject: [PATCH 126/797] ARM: dt: microsom: don't set bit 7 for ethernet mux settings Bit 6,7 are marked as reserved for the ethernet RGMII pins, so avoid setting these bits. Signed-off-by: Russell King Signed-off-by: Shawn Guo --- .../arm/boot/dts/imx6qdl-microsom-ar8035.dtsi | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi index a3cb2fff8f61..d16066608e21 100644 --- a/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi +++ b/arch/arm/boot/dts/imx6qdl-microsom-ar8035.dtsi @@ -26,25 +26,25 @@ /* GPIO16 -> AR8035 25MHz */ MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0xc0000000 MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x80000000 - MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 - MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 - MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 - MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 - MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b030 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b030 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b030 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b030 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b030 /* AR8035 CLK_25M --> ENET_REF_CLK (V22) */ MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x0a0b1 /* AR8035 pin strapping: IO voltage: pull up */ - MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b030 /* AR8035 pin strapping: PHYADDR#0: pull down */ - MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x130b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x13030 /* AR8035 pin strapping: PHYADDR#1: pull down */ - MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x130b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x13030 /* AR8035 pin strapping: MODE#1: pull up */ - MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b030 /* AR8035 pin strapping: MODE#3: pull up */ - MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b030 /* AR8035 pin strapping: MODE#0: pull down */ - MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x130b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x13030 /* * As the RMII pins are also connected to RGMII -- GitLab From 19f7cb6dec7408da8753bf3250098edab60cdbb6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 7 Apr 2014 16:29:24 +0200 Subject: [PATCH 127/797] ARM: dts: imx6: edmqmx6: Fix usbotg id pin Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index a63bbb3d46bb..39ffa766384f 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -293,7 +293,7 @@ pinctrl_usbotg: usbotggrp { fsl,pins = < - MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x17059 + MX6QDL_PAD_ENET_RX_ER__USB_OTG_ID 0x17059 >; }; -- GitLab From 465ca5dc4ad57b40ea632aabb32bf81a66632c4a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 7 Apr 2014 16:29:25 +0200 Subject: [PATCH 128/797] ARM: dts: imx6: edmqmx6: Do not use the OTG switch as VBUS regulator GPIO7_12 switches the D+/D- USB lines on and off. When we use this as VBUS regulator it means that USB device mode can never work as VBUS is never turned on in Device mode. Signed-off-by: Sascha Hauer Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index 39ffa766384f..af32944cf9ae 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -40,13 +40,15 @@ regulator-always-on; }; - reg_usb_otg_vbus: regulator@1 { + reg_usb_otg_switch: regulator@1 { compatible = "regulator-fixed"; reg = <1>; - regulator-name = "usb_otg_vbus"; + regulator-name = "usb_otg_switch"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; gpio = <&gpio7 12 0>; + regulator-boot-on; + regulator-always-on; }; reg_usb_host1: regulator@2 { @@ -348,7 +350,6 @@ }; &usbotg { - vbus-supply = <®_usb_otg_vbus>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usbotg>; disable-over-current; -- GitLab From 8dde78e8d62ac5b5b8c07cd965928536c3556bc0 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 7 Apr 2014 16:29:26 +0200 Subject: [PATCH 129/797] ARM: dts: imx6: edmqmx6: USB H1 only supports host mode Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index af32944cf9ae..e7762e456cbe 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -346,6 +346,7 @@ &usbh1 { vbus-supply = <®_usb_host1>; disable-over-current; + dr_mode = "host"; status = "okay"; }; -- GitLab From 52d13453df9aef536da6b93c7253fd618292a1cf Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 7 Apr 2014 16:29:27 +0200 Subject: [PATCH 130/797] ARM: dts: imx6: edmqmx6: add second STMPE Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts | 38 +++++++++++++++++++------ 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts index e7762e456cbe..e4ae38fd0269 100644 --- a/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts +++ b/arch/arm/boot/dts/imx6q-dmo-edmqmx6.dts @@ -19,7 +19,10 @@ compatible = "dmo,imx6q-edmqmx6", "fsl,imx6q"; aliases { - gpio7 = &stmpe_gpio; + gpio7 = &stmpe_gpio1; + gpio8 = &stmpe_gpio2; + stmpe-i2c0 = &stmpe1; + stmpe-i2c1 = &stmpe2; }; memory { @@ -67,23 +70,23 @@ led-blue { label = "blue"; - gpios = <&stmpe_gpio 8 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 8 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; }; led-green { label = "green"; - gpios = <&stmpe_gpio 9 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 9 GPIO_ACTIVE_HIGH>; }; led-pink { label = "pink"; - gpios = <&stmpe_gpio 10 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 10 GPIO_ACTIVE_HIGH>; }; led-red { label = "red"; - gpios = <&stmpe_gpio 11 GPIO_ACTIVE_HIGH>; + gpios = <&stmpe_gpio1 11 GPIO_ACTIVE_HIGH>; }; }; }; @@ -101,7 +104,8 @@ clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2 - &pinctrl_stmpe>; + &pinctrl_stmpe1 + &pinctrl_stmpe2>; status = "okay"; pmic: pfuze100@08 { @@ -207,13 +211,25 @@ }; }; - stmpe: stmpe1601@40 { + stmpe1: stmpe1601@40 { compatible = "st,stmpe1601"; reg = <0x40>; interrupts = <30 0>; interrupt-parent = <&gpio3>; - stmpe_gpio: stmpe_gpio { + stmpe_gpio1: stmpe_gpio { + #gpio-cells = <2>; + compatible = "st,stmpe-gpio"; + }; + }; + + stmpe2: stmpe1601@44 { + compatible = "st,stmpe1601"; + reg = <0x44>; + interrupts = <2 0>; + interrupt-parent = <&gpio5>; + + stmpe_gpio2: stmpe_gpio { #gpio-cells = <2>; compatible = "st,stmpe-gpio"; }; @@ -275,10 +291,14 @@ >; }; - pinctrl_stmpe: stmpegrp { + pinctrl_stmpe1: stmpe1grp { fsl,pins = ; }; + pinctrl_stmpe2: stmpe2grp { + fsl,pins = ; + }; + pinctrl_uart1: uart1grp { fsl,pins = < MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA 0x1b0b1 -- GitLab From 0c658c48cbe952d2689211a09f456d7319e59b33 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 10 Apr 2014 15:14:14 +0800 Subject: [PATCH 131/797] ARM: dts: imx53-tx53: add IPU DI ports and endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the recent imx-drm device tree binding changes, we need to add IPU DI ports and endpoints for adapting. Signed-off-by: Shawn Guo Acked-by: Lothar Waßmann --- arch/arm/boot/dts/imx53-tx53-x03x.dts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-tx53-x03x.dts b/arch/arm/boot/dts/imx53-tx53-x03x.dts index 0217dde3b36b..3b73e81dc3f0 100644 --- a/arch/arm/boot/dts/imx53-tx53-x03x.dts +++ b/arch/arm/boot/dts/imx53-tx53-x03x.dts @@ -25,12 +25,17 @@ soc { display: display@di0 { compatible = "fsl,imx-parallel-display"; - crtcs = <&ipu 0>; interface-pix-fmt = "rgb24"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rgb24_vga1>; status = "okay"; + port { + display0_in: endpoint { + remote-endpoint = <&ipu_di0_disp0>; + }; + }; + display-timings { VGA { clock-frequency = <25200000>; @@ -293,6 +298,10 @@ }; }; +&ipu_di0_disp0 { + remote-endpoint = <&display0_in>; +}; + &kpp { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_kpp>; -- GitLab From 139412290de46a7d4ff3359c8989485840764572 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Thu, 10 Apr 2014 15:22:56 +0800 Subject: [PATCH 132/797] ARM: dts: imx6q-gw5xxx: remove dead 'crtcs' property Since commit (655b43c staging: imx-drm-core: Use OF graph to find components and connections between encoder and crtcs), 'crtcs' becomes a dead property. Remove it. Signed-off-by: Shawn Guo Acked-by: Tim Harvey --- arch/arm/boot/dts/imx6q-gw5400-a.dts | 3 --- arch/arm/boot/dts/imx6qdl-gw52xx.dtsi | 3 --- 2 files changed, 6 deletions(-) diff --git a/arch/arm/boot/dts/imx6q-gw5400-a.dts b/arch/arm/boot/dts/imx6q-gw5400-a.dts index 902f98310481..e51bb3f0fd56 100644 --- a/arch/arm/boot/dts/imx6q-gw5400-a.dts +++ b/arch/arm/boot/dts/imx6q-gw5400-a.dts @@ -487,9 +487,6 @@ &ldb { status = "okay"; - lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; - }; }; &pcie { diff --git a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi index 8e99c9a9bc76..035d3a85c318 100644 --- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi @@ -436,9 +436,6 @@ &ldb { status = "okay"; - lvds-channel@0 { - crtcs = <&ipu1 0>, <&ipu1 1>; - }; }; &pcie { -- GitLab From fa1746ae3829ed8865a10a7fe3946ef91bddd458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= Date: Thu, 10 Apr 2014 10:03:40 +0200 Subject: [PATCH 133/797] ARM: dts: imx53: fix apparent copy/paste error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'remote-endpoint' property should point back to ipu_di1_lvds1 rather than ipu_di0_lvds0. Signed-off-by: Lothar Waßmann Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index b57ab57740f6..a99b64bfb046 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -430,7 +430,7 @@ port { lvds1_in: endpoint { - remote-endpoint = <&ipu_di0_lvds0>; + remote-endpoint = <&ipu_di1_lvds1>; }; }; }; -- GitLab From 2cd36711e2b9714c0bb500b4060714666f37ca2c Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 11 Apr 2014 09:09:39 -0300 Subject: [PATCH 134/797] ARM: dts: imx6sl-evk: Add an entry for MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 In case the bootloader has incorrectly configured the ALT mode of MX6SL_PAD_ECSPI1_SS0 pad, we end up with the following probe error: m25p80 spi0.0: found mr25h256, expected m25p32 m25p80 spi0.0: mr25h256 (32 Kbytes) In order to avoid this issue, add an entry for MX6SL_PAD_ECSPI1_SS0 pad, so that kernel configures the ECSPI chip select as GPIO functionality, which results in correct SPI NOR probe. Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6sl-evk.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/imx6sl-evk.dts b/arch/arm/boot/dts/imx6sl-evk.dts index 864d8dfb51ca..a8d9a93fab85 100644 --- a/arch/arm/boot/dts/imx6sl-evk.dts +++ b/arch/arm/boot/dts/imx6sl-evk.dts @@ -282,6 +282,7 @@ MX6SL_PAD_ECSPI1_MISO__ECSPI1_MISO 0x100b1 MX6SL_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x100b1 MX6SL_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x100b1 + MX6SL_PAD_ECSPI1_SS0__GPIO4_IO11 0x80000000 >; }; -- GitLab From 308965f94d00b670ca3a0f799839a68412da34d9 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 11 Apr 2014 16:59:38 +0200 Subject: [PATCH 135/797] ARM: dts: vybrid: drop address and size cells from GIC node This is likely a copy-and-paste error from the ARM GIC documentation, that has already been fixed. address-cells should have been set to 0, as with the size cells. As having those properties set to 0 is the same thing as not specifying them, drop them completely. Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Shawn Guo --- arch/arm/boot/dts/vf610.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index 804873367669..bb78e901ed5d 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -72,8 +72,6 @@ intc: interrupt-controller@40002000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; - #size-cells = <1>; interrupt-controller; reg = <0x40003000 0x1000>, <0x40002100 0x100>; -- GitLab From 4b2b404309f90e1ba12b0b187ca2490be19a22a6 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Fri, 11 Apr 2014 09:56:46 +0800 Subject: [PATCH 136/797] ARM: dts: imx: add required #clock-cells for fixed-clock Per bindings of fixed-clock, #clock-cells is a required property. Let's add it for those fixed rate clocks. Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx25.dtsi | 1 + arch/arm/boot/dts/imx27-apf27.dts | 1 + arch/arm/boot/dts/imx27.dtsi | 1 + arch/arm/boot/dts/imx50.dtsi | 4 ++++ arch/arm/boot/dts/imx51.dtsi | 4 ++++ arch/arm/boot/dts/imx53.dtsi | 4 ++++ arch/arm/boot/dts/imx6qdl.dtsi | 3 +++ arch/arm/boot/dts/imx6sl.dtsi | 2 ++ arch/arm/boot/dts/vf610-twr.dts | 2 ++ arch/arm/boot/dts/vf610.dtsi | 2 ++ 10 files changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi index 32f760e24898..ea323f09dc78 100644 --- a/arch/arm/boot/dts/imx25.dtsi +++ b/arch/arm/boot/dts/imx25.dtsi @@ -56,6 +56,7 @@ osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx27-apf27.dts b/arch/arm/boot/dts/imx27-apf27.dts index 09f57b39e3ef..73aae4f5e539 100644 --- a/arch/arm/boot/dts/imx27-apf27.dts +++ b/arch/arm/boot/dts/imx27-apf27.dts @@ -29,6 +29,7 @@ osc26m { compatible = "fsl,imx-osc26m", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; }; diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 6279e0b4f768..137e010eab35 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi @@ -48,6 +48,7 @@ osc26m { compatible = "fsl,imx-osc26m", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <26000000>; }; }; diff --git a/arch/arm/boot/dts/imx50.dtsi b/arch/arm/boot/dts/imx50.dtsi index 0c75fe3deb35..9c89d1ca97c2 100644 --- a/arch/arm/boot/dts/imx50.dtsi +++ b/arch/arm/boot/dts/imx50.dtsi @@ -53,21 +53,25 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <22579200>; }; ckih2 { compatible = "fsl,imx-ckih2", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 5f8216d08f6b..150bb4e2f744 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi @@ -50,21 +50,25 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; ckih2 { compatible = "fsl,imx-ckih2", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index a99b64bfb046..9c2bff2252d0 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi @@ -70,21 +70,25 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <22579200>; }; ckih2 { compatible = "fsl,imx-ckih2", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 2d04a5185fe9..eca0971d4db1 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -59,16 +59,19 @@ ckil { compatible = "fsl,imx-ckil", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; ckih1 { compatible = "fsl,imx-ckih1", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <0>; }; osc { compatible = "fsl,imx-osc", "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi index d92df0ab02e4..d26b099260a3 100644 --- a/arch/arm/boot/dts/imx6sl.dtsi +++ b/arch/arm/boot/dts/imx6sl.dtsi @@ -79,11 +79,13 @@ ckil { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; osc { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts index 7dd1d6ede525..ded361075aab 100644 --- a/arch/arm/boot/dts/vf610-twr.dts +++ b/arch/arm/boot/dts/vf610-twr.dts @@ -25,11 +25,13 @@ clocks { audio_ext { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24576000>; }; enet_ext { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <50000000>; }; }; diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi index bb78e901ed5d..b8ce0aa7b157 100644 --- a/arch/arm/boot/dts/vf610.dtsi +++ b/arch/arm/boot/dts/vf610.dtsi @@ -45,11 +45,13 @@ sxosc { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <32768>; }; fxosc { compatible = "fixed-clock"; + #clock-cells = <0>; clock-frequency = <24000000>; }; }; -- GitLab From b04c46190219a4f845e46a459e3102137b7f6cac Mon Sep 17 00:00:00 2001 From: "Wang, Xiaoming" Date: Mon, 14 Apr 2014 12:30:45 -0400 Subject: [PATCH 137/797] net: ipv4: current group_info should be put after using. Plug a group_info refcount leak in ping_init. group_info is only needed during initialization and the code failed to release the reference on exit. While here move grabbing the reference to a place where it is actually needed. Signed-off-by: Chuansheng Liu Signed-off-by: Zhang Dongxing Signed-off-by: xiaoming wang Signed-off-by: David S. Miller --- net/ipv4/ping.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index f4b19e5dde54..8210964a9f19 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk) { struct net *net = sock_net(sk); kgid_t group = current_egid(); - struct group_info *group_info = get_current_groups(); - int i, j, count = group_info->ngroups; + struct group_info *group_info; + int i, j, count; kgid_t low, high; + int ret = 0; inet_get_ping_group_range_net(net, &low, &high); if (gid_lte(low, group) && gid_lte(group, high)) return 0; + group_info = get_current_groups(); + count = group_info->ngroups; for (i = 0; i < group_info->nblocks; i++) { int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); for (j = 0; j < cp_count; j++) { kgid_t gid = group_info->blocks[i][j]; if (gid_lte(low, gid) && gid_lte(gid, high)) - return 0; + goto out_release_group; } count -= cp_count; } - return -EACCES; + ret = -EACCES; + +out_release_group: + put_group_info(group_info); + return ret; } EXPORT_SYMBOL_GPL(ping_init_sock); -- GitLab From befdf8978accecac2e0739e6b5075afc62db37fe Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Mon, 14 Apr 2014 09:51:19 +0800 Subject: [PATCH 138/797] net/mlx4_core: Preserve pci_dev_data after __mlx4_remove_one() pci_match_id() just match the static pci_device_id, which may return NULL if someone binds the driver to a device manually using /sys/bus/pci/drivers/.../new_id. This patch wrap up a helper function __mlx4_remove_one() which does the tear down function but preserve the drv_data. Functions like mlx4_pci_err_detected() and mlx4_restart_one() will call this one with out releasing drvdata. Fixes: 97a5221 "net/mlx4_core: pass pci_device_id.driver_data to __mlx4_init_one during reset". CC: Bjorn Helgaas CC: Amir Vadai CC: Jack Morgenstein CC: Or Gerlitz Signed-off-by: Wei Yang Acked-by: Jack Morgenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 172 ++++++++++++---------- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 1 + 2 files changed, 96 insertions(+), 77 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index f0ae95f66ceb..4b86c7af2a7a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2301,13 +2301,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) /* Allow large DMA segments, up to the firmware limit of 1 GB */ dma_set_max_seg_size(&pdev->dev, 1024 * 1024 * 1024); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - err = -ENOMEM; - goto err_release_regions; - } - - dev = &priv->dev; + dev = pci_get_drvdata(pdev); + priv = mlx4_priv(dev); dev->pdev = pdev; INIT_LIST_HEAD(&priv->ctx_list); spin_lock_init(&priv->ctx_lock); @@ -2535,8 +2530,7 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) mlx4_sense_init(dev); mlx4_start_sense(dev); - priv->pci_dev_data = pci_dev_data; - pci_set_drvdata(pdev, dev); + priv->removed = 0; return 0; @@ -2604,85 +2598,109 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { + struct mlx4_priv *priv; + struct mlx4_dev *dev; + printk_once(KERN_INFO "%s", mlx4_version); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + dev = &priv->dev; + pci_set_drvdata(pdev, dev); + priv->pci_dev_data = id->driver_data; + return __mlx4_init_one(pdev, id->driver_data); } -static void mlx4_remove_one(struct pci_dev *pdev) +static void __mlx4_remove_one(struct pci_dev *pdev) { struct mlx4_dev *dev = pci_get_drvdata(pdev); struct mlx4_priv *priv = mlx4_priv(dev); + int pci_dev_data; int p; - if (dev) { - /* in SRIOV it is not allowed to unload the pf's - * driver while there are alive vf's */ - if (mlx4_is_master(dev)) { - if (mlx4_how_many_lives_vf(dev)) - printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n"); - } - mlx4_stop_sense(dev); - mlx4_unregister_device(dev); + if (priv->removed) + return; - for (p = 1; p <= dev->caps.num_ports; p++) { - mlx4_cleanup_port_info(&priv->port[p]); - mlx4_CLOSE_PORT(dev, p); - } + pci_dev_data = priv->pci_dev_data; - if (mlx4_is_master(dev)) - mlx4_free_resource_tracker(dev, - RES_TR_FREE_SLAVES_ONLY); - - mlx4_cleanup_counters_table(dev); - mlx4_cleanup_qp_table(dev); - mlx4_cleanup_srq_table(dev); - mlx4_cleanup_cq_table(dev); - mlx4_cmd_use_polling(dev); - mlx4_cleanup_eq_table(dev); - mlx4_cleanup_mcg_table(dev); - mlx4_cleanup_mr_table(dev); - mlx4_cleanup_xrcd_table(dev); - mlx4_cleanup_pd_table(dev); + /* in SRIOV it is not allowed to unload the pf's + * driver while there are alive vf's */ + if (mlx4_is_master(dev) && mlx4_how_many_lives_vf(dev)) + printk(KERN_ERR "Removing PF when there are assigned VF's !!!\n"); + mlx4_stop_sense(dev); + mlx4_unregister_device(dev); - if (mlx4_is_master(dev)) - mlx4_free_resource_tracker(dev, - RES_TR_FREE_STRUCTS_ONLY); - - iounmap(priv->kar); - mlx4_uar_free(dev, &priv->driver_uar); - mlx4_cleanup_uar_table(dev); - if (!mlx4_is_slave(dev)) - mlx4_clear_steering(dev); - mlx4_free_eq_table(dev); - if (mlx4_is_master(dev)) - mlx4_multi_func_cleanup(dev); - mlx4_close_hca(dev); - if (mlx4_is_slave(dev)) - mlx4_multi_func_cleanup(dev); - mlx4_cmd_cleanup(dev); - - if (dev->flags & MLX4_FLAG_MSI_X) - pci_disable_msix(pdev); - if (dev->flags & MLX4_FLAG_SRIOV) { - mlx4_warn(dev, "Disabling SR-IOV\n"); - pci_disable_sriov(pdev); - } + for (p = 1; p <= dev->caps.num_ports; p++) { + mlx4_cleanup_port_info(&priv->port[p]); + mlx4_CLOSE_PORT(dev, p); + } - if (!mlx4_is_slave(dev)) - mlx4_free_ownership(dev); + if (mlx4_is_master(dev)) + mlx4_free_resource_tracker(dev, + RES_TR_FREE_SLAVES_ONLY); + + mlx4_cleanup_counters_table(dev); + mlx4_cleanup_qp_table(dev); + mlx4_cleanup_srq_table(dev); + mlx4_cleanup_cq_table(dev); + mlx4_cmd_use_polling(dev); + mlx4_cleanup_eq_table(dev); + mlx4_cleanup_mcg_table(dev); + mlx4_cleanup_mr_table(dev); + mlx4_cleanup_xrcd_table(dev); + mlx4_cleanup_pd_table(dev); - kfree(dev->caps.qp0_tunnel); - kfree(dev->caps.qp0_proxy); - kfree(dev->caps.qp1_tunnel); - kfree(dev->caps.qp1_proxy); - kfree(dev->dev_vfs); + if (mlx4_is_master(dev)) + mlx4_free_resource_tracker(dev, + RES_TR_FREE_STRUCTS_ONLY); - kfree(priv); - pci_release_regions(pdev); - pci_disable_device(pdev); - pci_set_drvdata(pdev, NULL); + iounmap(priv->kar); + mlx4_uar_free(dev, &priv->driver_uar); + mlx4_cleanup_uar_table(dev); + if (!mlx4_is_slave(dev)) + mlx4_clear_steering(dev); + mlx4_free_eq_table(dev); + if (mlx4_is_master(dev)) + mlx4_multi_func_cleanup(dev); + mlx4_close_hca(dev); + if (mlx4_is_slave(dev)) + mlx4_multi_func_cleanup(dev); + mlx4_cmd_cleanup(dev); + + if (dev->flags & MLX4_FLAG_MSI_X) + pci_disable_msix(pdev); + if (dev->flags & MLX4_FLAG_SRIOV) { + mlx4_warn(dev, "Disabling SR-IOV\n"); + pci_disable_sriov(pdev); } + + if (!mlx4_is_slave(dev)) + mlx4_free_ownership(dev); + + kfree(dev->caps.qp0_tunnel); + kfree(dev->caps.qp0_proxy); + kfree(dev->caps.qp1_tunnel); + kfree(dev->caps.qp1_proxy); + kfree(dev->dev_vfs); + + pci_release_regions(pdev); + pci_disable_device(pdev); + memset(priv, 0, sizeof(*priv)); + priv->pci_dev_data = pci_dev_data; + priv->removed = 1; +} + +static void mlx4_remove_one(struct pci_dev *pdev) +{ + struct mlx4_dev *dev = pci_get_drvdata(pdev); + struct mlx4_priv *priv = mlx4_priv(dev); + + __mlx4_remove_one(pdev); + kfree(priv); + pci_set_drvdata(pdev, NULL); } int mlx4_restart_one(struct pci_dev *pdev) @@ -2692,7 +2710,7 @@ int mlx4_restart_one(struct pci_dev *pdev) int pci_dev_data; pci_dev_data = priv->pci_dev_data; - mlx4_remove_one(pdev); + __mlx4_remove_one(pdev); return __mlx4_init_one(pdev, pci_dev_data); } @@ -2747,7 +2765,7 @@ MODULE_DEVICE_TABLE(pci, mlx4_pci_table); static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, pci_channel_state_t state) { - mlx4_remove_one(pdev); + __mlx4_remove_one(pdev); return state == pci_channel_io_perm_failure ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET; @@ -2755,11 +2773,11 @@ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev, static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev) { - const struct pci_device_id *id; - int ret; + struct mlx4_dev *dev = pci_get_drvdata(pdev); + struct mlx4_priv *priv = mlx4_priv(dev); + int ret; - id = pci_match_id(mlx4_pci_table, pdev); - ret = __mlx4_init_one(pdev, id->driver_data); + ret = __mlx4_init_one(pdev, priv->pci_dev_data); return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; } diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index cf8be41abb36..f9c465101963 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -800,6 +800,7 @@ struct mlx4_priv { spinlock_t ctx_lock; int pci_dev_data; + int removed; struct list_head pgdir_list; struct mutex pgdir_mutex; -- GitLab From cc6ca3023f2c2bbcd062e9d4cf6afc2ba2821ada Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 13 Apr 2014 11:15:33 +0200 Subject: [PATCH 139/797] Revert "net: mvneta: fix usage as a module on RGMII configurations" This reverts commit e3a8786c10e75903f1269474e21fe8cb49c3a670. While this commit allows to use the mvneta driver as a module on some configurations, it breaks other configurations even if mvneta is used built-in. This breakage is due to the fact that on some RGMII platforms, the PCS bit has to be set, and on some other platforms, it has to be cleared. At the moment, we lack informations to know exactly the significance of this bit (the datasheet only says "enables PCS"), and so we can't produce a patch that will work on all platforms at this point. And since this change is breaking the network completely for many users, it's much better to revert it for now. We'll come back later with a proper fix that takes into account all platforms. Basically: * Armada XP GP is configured as RGMII-ID, and needs the PCS bit to be set. * Armada 370 Mirabox is configured as RGMII-ID, and needs the PCS bit to be cleared. And at the moment, we don't know how to make the distinction between those two cases. One hint is that the Armada XP GP appears in fact to be using a QSGMII connection with the PHY (Quad-SGMII), but configuring it as SGMII doesn't work, while RGMII-ID works. This needs more investigation, but in the mean time, let's unbreak the network for all those users. Signed-off-by: Thomas Petazzoni Reported-by: Arnaud Ebalard Reported-by: Alexander Reuter Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=73401 Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 41 +++++++++++++++++++++------ 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index d04b1c3c9b85..b248bcbdae63 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -89,9 +89,8 @@ #define MVNETA_TX_IN_PRGRS BIT(1) #define MVNETA_TX_FIFO_EMPTY BIT(8) #define MVNETA_RX_MIN_FRAME_SIZE 0x247c -#define MVNETA_SERDES_CFG 0x24A0 +#define MVNETA_SGMII_SERDES_CFG 0x24A0 #define MVNETA_SGMII_SERDES_PROTO 0x0cc7 -#define MVNETA_RGMII_SERDES_PROTO 0x0667 #define MVNETA_TYPE_PRIO 0x24bc #define MVNETA_FORCE_UNI BIT(21) #define MVNETA_TXQ_CMD_1 0x24e4 @@ -712,6 +711,35 @@ static void mvneta_rxq_bm_disable(struct mvneta_port *pp, mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); } + + +/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */ +static void mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable) +{ + u32 val; + + val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); + + if (enable) + val |= MVNETA_GMAC2_PORT_RGMII; + else + val &= ~MVNETA_GMAC2_PORT_RGMII; + + mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); +} + +/* Config SGMII port */ +static void mvneta_port_sgmii_config(struct mvneta_port *pp) +{ + u32 val; + + val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); + val |= MVNETA_GMAC2_PCS_ENABLE; + mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); + + mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); +} + /* Start the Ethernet port RX and TX activity */ static void mvneta_port_up(struct mvneta_port *pp) { @@ -2729,15 +2757,12 @@ static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0); if (phy_mode == PHY_INTERFACE_MODE_SGMII) - mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); - else - mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_RGMII_SERDES_PROTO); + mvneta_port_sgmii_config(pp); - val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); - - val |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII; + mvneta_gmac_rgmii_set(pp, 1); /* Cancel Port Reset */ + val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); val &= ~MVNETA_GMAC2_PORT_RESET; mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -- GitLab From 91146153da2feab18efab2e13b0945b6bb704ded Mon Sep 17 00:00:00 2001 From: Julian Anastasov Date: Sun, 13 Apr 2014 18:08:02 +0300 Subject: [PATCH 140/797] ipv4: return valid RTA_IIF on ip route get Extend commit 13378cad02afc2adc6c0e07fca03903c7ada0b37 ("ipv4: Change rt->rt_iif encoding.") from 3.6 to return valid RTA_IIF on 'ip route get ... iif DEVICE' instead of rt_iif 0 which is displayed as 'iif *'. inet_iif is not appropriate to use because skb_iif is not set. Use the skb->dev->ifindex instead. Signed-off-by: Julian Anastasov Signed-off-by: David S. Miller --- net/ipv4/route.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 34d094cadb11..20a59c388e6e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2357,7 +2357,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, } } else #endif - if (nla_put_u32(skb, RTA_IIF, rt->rt_iif)) + if (nla_put_u32(skb, RTA_IIF, skb->dev->ifindex)) goto nla_put_failure; } -- GitLab From 05ab8f2647e4221cbdb3856dd7d32bd5407316b3 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sun, 13 Apr 2014 18:23:33 +0200 Subject: [PATCH 141/797] filter: prevent nla extensions to peek beyond the end of the message The BPF_S_ANC_NLATTR and BPF_S_ANC_NLATTR_NEST extensions fail to check for a minimal message length before testing the supplied offset to be within the bounds of the message. This allows the subtraction of the nla header to underflow and therefore -- as the data type is unsigned -- allowing far to big offset and length values for the search of the netlink attribute. The remainder calculation for the BPF_S_ANC_NLATTR_NEST extension is also wrong. It has the minuend and subtrahend mixed up, therefore calculates a huge length value, allowing to overrun the end of the message while looking for the netlink attribute. The following three BPF snippets will trigger the bugs when attached to a UNIX datagram socket and parsing a message with length 1, 2 or 3. ,-[ PoC for missing size check in BPF_S_ANC_NLATTR ]-- | ld #0x87654321 | ldx #42 | ld #nla | ret a `--- ,-[ PoC for the same bug in BPF_S_ANC_NLATTR_NEST ]-- | ld #0x87654321 | ldx #42 | ld #nlan | ret a `--- ,-[ PoC for wrong remainder calculation in BPF_S_ANC_NLATTR_NEST ]-- | ; (needs a fake netlink header at offset 0) | ld #0 | ldx #42 | ld #nlan | ret a `--- Fix the first issue by ensuring the message length fulfills the minimal size constrains of a nla header. Fix the second bug by getting the math for the remainder calculation right. Fixes: 4738c1db15 ("[SKFILTER]: Add SKF_ADF_NLATTR instruction") Fixes: d214c7537b ("filter: add SKF_AD_NLATTR_NEST to look for nested..") Cc: Patrick McHardy Cc: Pablo Neira Ayuso Signed-off-by: Mathias Krause Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- net/core/filter.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/net/core/filter.c b/net/core/filter.c index e08b3822c72a..0e0856f5d708 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -600,6 +600,9 @@ static u64 __skb_get_nlattr(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) if (skb_is_nonlinear(skb)) return 0; + if (skb->len < sizeof(struct nlattr)) + return 0; + if (A > skb->len - sizeof(struct nlattr)) return 0; @@ -618,11 +621,14 @@ static u64 __skb_get_nlattr_nest(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) if (skb_is_nonlinear(skb)) return 0; + if (skb->len < sizeof(struct nlattr)) + return 0; + if (A > skb->len - sizeof(struct nlattr)) return 0; nla = (struct nlattr *) &skb->data[A]; - if (nla->nla_len > A - skb->len) + if (nla->nla_len > skb->len - A) return 0; nla = nla_find_nested(nla, X); -- GitLab From 9f85ff849c21b429c1e2137f2646f9cc667d8ded Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:59:34 -0700 Subject: [PATCH 142/797] ARM: shmobile: lager: fixup SND_SOC_DAIFMT_CBx_CFx flags e1508289404ab6ca28e0dc931612600f0441c417 (ASoC: rcar: fixup SND_SOC_DAIFMT_CBx_CFx flags) corrected SND_SOC_DAIFMT_CBx_CFx definition. But then, Lager board was maintenanced other branch. This patch correct SND_SOC_DAIFMT_CBx_CFx flag for lager Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-lager.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index f0104bfe544e..18c7e0311aa6 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -588,14 +588,12 @@ static struct asoc_simple_card_info rsnd_card_info = { .card = "SSI01-AK4643", .codec = "ak4642-codec.2-0012", .platform = "rcar_sound", - .daifmt = SND_SOC_DAIFMT_LEFT_J, + .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { .name = "rcar_sound", - .fmt = SND_SOC_DAIFMT_CBS_CFS, }, .codec_dai = { .name = "ak4642-hifi", - .fmt = SND_SOC_DAIFMT_CBM_CFM, .sysclk = 11289600, }, }; -- GitLab From 7b707277e734c553a8043e9b4d530eb47f4d60c8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Sun, 13 Apr 2014 17:59:47 -0700 Subject: [PATCH 143/797] ARM: shmobile: armadillo800eva: fixup SND_SOC_DAIFMT_CBx_CFx flags c7a507eea1db1430476289f525f9c853d5d485e8 (ASoC: fsi: fixup SND_SOC_DAIFMT_CBx_CFx flags) exchanged sound flags, but armadillo800eva flags needs IB_NF. The recorded sound will be noise without this patch. Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-armadillo800eva.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c index 2858f380beae..486063db2a2f 100644 --- a/arch/arm/mach-shmobile/board-armadillo800eva.c +++ b/arch/arm/mach-shmobile/board-armadillo800eva.c @@ -992,6 +992,7 @@ static struct asoc_simple_card_info fsi_wm8978_info = { .platform = "sh_fsi2", .daifmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM, .cpu_dai = { + .fmt = SND_SOC_DAIFMT_IB_NF, .name = "fsia-dai", }, .codec_dai = { -- GitLab From 5fc68a6cad658e45dca3e0a6607df3a8e5df4ef9 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Wed, 19 Mar 2014 11:25:50 +0530 Subject: [PATCH 144/797] dma: edma: fix incorrect SG list handling The code to handle any length SG lists calls edma_resume() even before edma_start() is called. This is incorrect because edma_resume() enables edma events on the channel after which CPU (in edma_start) cannot clear posted events by writing to ECR (per the EDMA user's guide). Because of this EDMA transfers fail to start if due to some reason there is a pending EDMA event registered even before EDMA transfers are started. This can happen if an EDMA event is a byproduct of device initialization. Fix this by calling edma_resume() only if it is not the first batch of MAX_NR_SG elements. Without this patch, MMC/SD fails to function on DA850 EVM with DMA. The behaviour is triggered by specific IP and this can explain why the issue was not reported before (example with MMC/SD on AM335x). Tested on DA850 EVM and AM335x EVM-SK using MMC/SD card. Cc: stable@vger.kernel.org # v3.12.x+ Cc: Joel Fernandes Acked-by: Joel Fernandes Tested-by: Jon Ringle Tested-by: Alexander Holler Reported-by: Jon Ringle Signed-off-by: Sekhar Nori Signed-off-by: Vinod Koul --- drivers/dma/edma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index cd04eb7b182e..926360c2db6a 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -182,11 +182,13 @@ static void edma_execute(struct edma_chan *echan) echan->ecc->dummy_slot); } - edma_resume(echan->ch_num); - if (edesc->processed <= MAX_NR_SG) { dev_dbg(dev, "first transfer starting %d\n", echan->ch_num); edma_start(echan->ch_num); + } else { + dev_dbg(dev, "chan: %d: completed %d elements, resuming\n", + echan->ch_num, edesc->processed); + edma_resume(echan->ch_num); } /* -- GitLab From f96364041ccda63ff4bed96fd06b267d8d841dc0 Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sun, 13 Apr 2014 16:26:08 +0800 Subject: [PATCH 145/797] x86/platform: Fix "make O=dir kvmconfig" Running: make O=dir x86_64_defconfig make O=dir kvmconfig the second command dirties the source tree with file ".config", symlink "source" and objects in folder "scripts". Fixed by using properly prefixed paths in the arch Makefile. Signed-off-by: Antonio Borneo Acked-by: Borislav Petkov Cc: Pekka Enberg Link: http://lkml.kernel.org/r/1397377568-8375-1-git-send-email-borneo.antonio@gmail.com Signed-off-by: Ingo Molnar --- arch/x86/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index 3b9348a0c1a4..0db89106854e 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -250,8 +250,8 @@ archclean: PHONY += kvmconfig kvmconfig: $(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config - $(Q)yes "" | $(MAKE) oldconfig + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config + $(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig define archhelp echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' -- GitLab From 86e587623a0ca8426267dad8d3eaebd6fc2d00f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sun, 13 Apr 2014 12:45:03 +0300 Subject: [PATCH 146/797] x86/gpu: Fix sign extension issue in Intel graphics stolen memory quirks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Have the KB(),MB(),GB() macros produce unsigned longs to avoid unintended sign extension issues with the gen2 memory size detection. What happens is first the uint8_t returned by read_pci_config_byte() gets promoted to an int which gets multiplied by another int from the MB() macro, and finally the result gets sign extended to size_t. Although this shouldn't be a problem in practice as all affected gen2 platforms are 32bit AFAIK, so size_t will be 32 bits. Reported-by: Bjorn Helgaas Suggested-by: H. Peter Anvin Signed-off-by: Ville Syrjälä Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/1397382303-17525-1-git-send-email-ville.syrjala@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/early-quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index b0cc3809723d..6e2537c32190 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -240,7 +240,7 @@ static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_s return base; } -#define KB(x) ((x) * 1024) +#define KB(x) ((x) * 1024UL) #define MB(x) (KB (KB (x))) #define GB(x) (MB (KB (x))) -- GitLab From b34f8624a7ddaca51a00d5bb35f55324e851b314 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Apr 2014 16:21:02 +0200 Subject: [PATCH 147/797] ARM: ux500: update defconfig Update the ux500 defconfig to match the latest output of savedefconfig. Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 65f77885c167..d130a01d9342 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -1,6 +1,6 @@ # CONFIG_SWAP is not set CONFIG_SYSVIPC=y -CONFIG_NO_HZ=y +CONFIG_NO_HZ_IDLE=y CONFIG_HIGH_RES_TIMERS=y CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y @@ -10,7 +10,6 @@ CONFIG_MODULE_UNLOAD=y CONFIG_ARCH_U8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y -CONFIG_MACH_UX500_DT=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_PREEMPT=y @@ -85,8 +84,6 @@ CONFIG_AB8500_USB=y CONFIG_USB_GADGET=y CONFIG_USB_ETH=m CONFIG_MMC=y -CONFIG_MMC_UNSAFE_RESUME=y -# CONFIG_MMC_BLOCK_BOUNCE is not set CONFIG_MMC_ARMMMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y -- GitLab From ccc3e2a463e25ccbbd6cc4dcfff23b8c81c669dc Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 26 Mar 2014 14:19:07 +0100 Subject: [PATCH 148/797] ARM: ux500: u8500_defconfig: Enable PARTITION_ADVANCED There are both (e)MMC/SD-card support in ux500, thus it's reasonable to support partitions for block devices as default. While updating the defconfig, we rebase it towards Kconfig changes. Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index d130a01d9342..dac0a876e737 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -7,6 +7,7 @@ CONFIG_KALLSYMS_ALL=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y CONFIG_ARCH_U8500=y CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y @@ -36,6 +37,8 @@ CONFIG_PHONET=y # CONFIG_WIRELESS is not set CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65536 CONFIG_SENSORS_BH1780=y @@ -107,8 +110,6 @@ CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT3_FS=y CONFIG_EXT4_FS=y CONFIG_VFAT_FS=y -CONFIG_DEVTMPFS=y -CONFIG_DEVTMPFS_MOUNT=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y # CONFIG_MISC_FILESYSTEMS is not set -- GitLab From f661e7733f8c45692147ea52a16c9c1856cf152b Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 26 Mar 2014 14:30:53 +0100 Subject: [PATCH 149/797] ARM: u300: u300_defconfig: Enable PARTITION_ADVANCED Since there are SD-card support in u300, it's reasonable to support partitions for block devices as default. While updating the defconfig, we rebase it towards Kconfig changes. Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij --- arch/arm/configs/u300_defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index fd81a1b99cce..aaa95ab606a8 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig @@ -11,6 +11,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_LBDAF is not set # CONFIG_BLK_DEV_BSG is not set +CONFIG_PARTITION_ADVANCED=y # CONFIG_IOSCHED_CFQ is not set # CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_U300=y @@ -21,7 +22,6 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_CMDLINE="root=/dev/ram0 rw rootfstype=rootfs console=ttyAMA0,115200n8 lpj=515072" CONFIG_CPU_IDLE=y -CONFIG_FPE_NWFPE=y # CONFIG_SUSPEND is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_PREVENT_FIRMWARE_BUILD is not set @@ -64,8 +64,8 @@ CONFIG_TMPFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO=y CONFIG_DEBUG_FS=y # CONFIG_SCHED_DEBUG is not set CONFIG_TIMER_STATS=y # CONFIG_DEBUG_PREEMPT is not set -CONFIG_DEBUG_INFO=y -- GitLab From 7c60a6ed10e7d7146fbae52a7f5d59c05169ce4d Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Apr 2014 16:31:53 +0200 Subject: [PATCH 150/797] ARM: ux500: configure in sensors This enables the STMicroelectronics MEMS sensors for accelerometer, gyroscope, magnetometer and pressure that are mounted on the Ux500 models. Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index dac0a876e737..726b1fa786f7 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -103,6 +103,11 @@ CONFIG_STE_DMA40=y CONFIG_STAGING=y CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y CONFIG_HSEM_U8500=y +CONFIG_IIO=y +CONFIG_IIO_ST_ACCEL_3AXIS=y +CONFIG_IIO_ST_GYRO_3AXIS=y +CONFIG_IIO_ST_MAGN_3AXIS=y +CONFIG_IIO_ST_PRESS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y -- GitLab From 22c0d7e36f74352f7b80679003bf7edf85736b2b Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 24 Mar 2014 23:36:01 +0100 Subject: [PATCH 151/797] pinctrl: rockchip: fix offset of mux registers for rk3188 The correct value of .mux_offset for rk3188 seems to be 0x60 instead of 0x68. Heiko adds: GPIO0 only has the second two IOMUX registers: - GRF_GPIO0C_IOMUX at 0x68 - GRF_GPIO0D_IOMUX at 0x6c which I guess is where my mistake comes from. It looks like there does no iomux register exist at all for the first 16 pins. In any case, the current number is wrong, and the 0x60 offset is the correct one, but I guess we need to determine what the affected pins do - do they always have a gpio mux or such? Signed-off-by: Beniamino Galvani Reviewed-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 46dddc159286..23e8812d3115 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -1534,7 +1534,7 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = { .nr_banks = ARRAY_SIZE(rk3188_pin_banks), .label = "RK3188-GPIO", .type = RK3188, - .mux_offset = 0x68, + .mux_offset = 0x60, .pull_calc_reg = rk3188_calc_pull_reg_and_bit, }; -- GitLab From 14797189b35e9ec4344eeb75bdca4120cba88b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Wed, 26 Mar 2014 00:57:00 +0100 Subject: [PATCH 152/797] pinctrl: rockchip: add return value to rockchip_set_mux In a following change, rockchip_set_mux gets the possibility to fail. Therefore add a return value to it and honor error codes in functions using rockchip_set_mux. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 32 +++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 23e8812d3115..2ac194370b73 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -342,7 +342,7 @@ static const struct pinctrl_ops rockchip_pctrl_ops = { * @pin: pin to change * @mux: new mux function to set */ -static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) +static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) { struct rockchip_pinctrl *info = bank->drvdata; void __iomem *reg = info->reg_base + info->ctrl->mux_offset; @@ -365,6 +365,8 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) writel(data, reg); spin_unlock_irqrestore(&bank->slock, flags); + + return 0; } #define RK2928_PULL_OFFSET 0x118 @@ -560,7 +562,7 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, const unsigned int *pins = info->groups[group].pins; const struct rockchip_pin_config *data = info->groups[group].data; struct rockchip_pin_bank *bank; - int cnt; + int cnt, ret = 0; dev_dbg(info->dev, "enable function %s group %s\n", info->functions[selector].name, info->groups[group].name); @@ -571,8 +573,18 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, */ for (cnt = 0; cnt < info->groups[group].npins; cnt++) { bank = pin_to_bank(info, pins[cnt]); - rockchip_set_mux(bank, pins[cnt] - bank->pin_base, - data[cnt].func); + ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base, + data[cnt].func); + if (ret) + break; + } + + if (ret) { + /* revert the already done pin settings */ + for (cnt--; cnt >= 0; cnt--) + rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0); + + return ret; } return 0; @@ -607,7 +619,7 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); struct rockchip_pin_bank *bank; struct gpio_chip *chip; - int pin; + int pin, ret; u32 data; chip = range->gc; @@ -617,7 +629,9 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev, dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n", offset, range->name, pin, input ? "input" : "output"); - rockchip_set_mux(bank, pin, RK_FUNC_GPIO); + ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO); + if (ret < 0) + return ret; data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); /* set bit to 1 for output, 0 for input */ @@ -1144,9 +1158,13 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type) u32 polarity; u32 level; u32 data; + int ret; /* make sure the pin is configured as gpio input */ - rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); + ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO); + if (ret < 0) + return ret; + data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR); data &= ~mask; writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR); -- GitLab From c4a532dee6b6e433d267d76d643e62ab90ca9eb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Wed, 26 Mar 2014 00:57:52 +0100 Subject: [PATCH 153/797] pinctrl: rockchip: handle first half of rk3188-bank0 correctly The first half of pinbank 0 only has one muxing function (as gpios) and does not have a special mux-register. Therefore ensure that no other mux function can be selected and also do not write to a non-existent register. Signed-off-by: Heiko Stuebner Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 2ac194370b73..96c60d230c13 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -350,6 +350,20 @@ static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) u8 bit; u32 data; + /* + * The first 16 pins of rk3188_bank0 are always gpios and do not have + * a mux register at all. + */ + if (bank->bank_type == RK3188_BANK0 && pin < 16) { + if (mux != RK_FUNC_GPIO) { + dev_err(info->dev, + "pin %d only supports a gpio mux\n", pin); + return -ENOTSUPP; + } else { + return 0; + } + } + dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux); -- GitLab From 6888c75b243307e616f95159a917b80121c426c7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 09:18:18 +0200 Subject: [PATCH 154/797] pinctrl: nomadik: delete stray debug print I left this in by mistake, get rid of it. Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-nomadik.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 208341fd57d2..8f6f16ef73f3 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c @@ -877,7 +877,6 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc) struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip); u32 status; - pr_err("PLONK IRQ %d\n", irq); clk_enable(nmk_chip->clk); status = readl(nmk_chip->addr + NMK_GPIO_IS); clk_disable(nmk_chip->clk); -- GitLab From 48f15e94f5a30bf335c3c972d592bc9212aca9ff Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Mon, 31 Mar 2014 14:49:54 -0700 Subject: [PATCH 155/797] pinctrl: msm: Correct interrupt code for TLMM v2 Acking interrupts are done differently between on v2 and v3, so add an extra attribute to the pingroup struct to let the platform definitions control this. Also make sure to start dual edge detection by detecting the rising edge. Signed-off-by: Bjorn Andersson Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-msm.c | 6 +++++- drivers/pinctrl/pinctrl-msm.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c index 38d579b47f31..e43fbce56598 100644 --- a/drivers/pinctrl/pinctrl-msm.c +++ b/drivers/pinctrl/pinctrl-msm.c @@ -665,7 +665,10 @@ static void msm_gpio_irq_ack(struct irq_data *d) spin_lock_irqsave(&pctrl->lock, flags); val = readl(pctrl->regs + g->intr_status_reg); - val &= ~BIT(g->intr_status_bit); + if (g->intr_ack_high) + val |= BIT(g->intr_status_bit); + else + val &= ~BIT(g->intr_status_bit); writel(val, pctrl->regs + g->intr_status_reg); if (test_bit(d->hwirq, pctrl->dual_edge_irqs)) @@ -744,6 +747,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type) break; case IRQ_TYPE_EDGE_BOTH: val |= BIT(g->intr_detection_bit); + val |= BIT(g->intr_polarity_bit); break; case IRQ_TYPE_LEVEL_LOW: break; diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h index 8fbe9fb19f36..6e26f1b676d7 100644 --- a/drivers/pinctrl/pinctrl-msm.h +++ b/drivers/pinctrl/pinctrl-msm.h @@ -84,6 +84,7 @@ struct msm_pingroup { unsigned intr_enable_bit:5; unsigned intr_status_bit:5; + unsigned intr_ack_high:1; unsigned intr_target_bit:5; unsigned intr_raw_status_bit:5; -- GitLab From 7418b5cc81185e4ae1fec66156c464eb0b8d8f5a Mon Sep 17 00:00:00 2001 From: Sherman Yin Date: Wed, 2 Apr 2014 15:40:37 -0700 Subject: [PATCH 156/797] pinctrl: Rename Broadcom Capri pinctrl driver To be consistent with other Broadcom drivers, the Broadcom Capri pinctrl driver and its related CONFIG option are renamed to bcm281xx. Devicetree compatible string and binding documentation use "brcm,bcm11351-pinctrl" to match the machine binding here: Documentation/devicetree/bindings/arm/bcm/bcm11351.txt This driver supports pinctrl on BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155 SoCs. Signed-off-by: Sherman Yin Reviewed-by: Matt Porter Acked-by: Linus Walleij Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 8 +- drivers/pinctrl/Makefile | 2 +- drivers/pinctrl/pinctrl-bcm281xx.c | 1461 ++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-capri.c | 1454 --------------------------- 4 files changed, 1466 insertions(+), 1459 deletions(-) create mode 100644 drivers/pinctrl/pinctrl-bcm281xx.c delete mode 100644 drivers/pinctrl/pinctrl-capri.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e49324032611..e00c02d0a094 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -104,16 +104,16 @@ config PINCTRL_BCM2835 select PINMUX select PINCONF -config PINCTRL_CAPRI - bool "Broadcom Capri pinctrl driver" +config PINCTRL_BCM281XX + bool "Broadcom BCM281xx pinctrl driver" depends on OF select PINMUX select PINCONF select GENERIC_PINCONF select REGMAP_MMIO help - Say Y here to support Broadcom Capri pinctrl driver, which is used for - the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351, + Say Y here to support Broadcom BCM281xx pinctrl driver, which is used + for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351, BCM28145, and BCM28155 SoCs. This driver requires the pinctrl framework. GPIO is provided by a separate GPIO driver. diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 4b835880cf80..6d3fd62b9ae8 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -21,7 +21,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o -obj-$(CONFIG_PINCTRL_CAPRI) += pinctrl-capri.o +obj-$(CONFIG_PINCTRL_BCM281XX) += pinctrl-bcm281xx.o obj-$(CONFIG_PINCTRL_IMX) += pinctrl-imx.o obj-$(CONFIG_PINCTRL_IMX1_CORE) += pinctrl-imx1-core.o obj-$(CONFIG_PINCTRL_IMX27) += pinctrl-imx27.o diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c new file mode 100644 index 000000000000..3bed792b2c03 --- /dev/null +++ b/drivers/pinctrl/pinctrl-bcm281xx.c @@ -0,0 +1,1461 @@ +/* + * Copyright (C) 2013 Broadcom 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. + * + * 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 +#include +#include +#include +#include +#include +#include +#include "core.h" +#include "pinctrl-utils.h" + +/* BCM281XX Pin Control Registers Definitions */ + +/* Function Select bits are the same for all pin control registers */ +#define BCM281XX_PIN_REG_F_SEL_MASK 0x0700 +#define BCM281XX_PIN_REG_F_SEL_SHIFT 8 + +/* Standard pin register */ +#define BCM281XX_STD_PIN_REG_DRV_STR_MASK 0x0007 +#define BCM281XX_STD_PIN_REG_DRV_STR_SHIFT 0 +#define BCM281XX_STD_PIN_REG_INPUT_DIS_MASK 0x0008 +#define BCM281XX_STD_PIN_REG_INPUT_DIS_SHIFT 3 +#define BCM281XX_STD_PIN_REG_SLEW_MASK 0x0010 +#define BCM281XX_STD_PIN_REG_SLEW_SHIFT 4 +#define BCM281XX_STD_PIN_REG_PULL_UP_MASK 0x0020 +#define BCM281XX_STD_PIN_REG_PULL_UP_SHIFT 5 +#define BCM281XX_STD_PIN_REG_PULL_DN_MASK 0x0040 +#define BCM281XX_STD_PIN_REG_PULL_DN_SHIFT 6 +#define BCM281XX_STD_PIN_REG_HYST_MASK 0x0080 +#define BCM281XX_STD_PIN_REG_HYST_SHIFT 7 + +/* I2C pin register */ +#define BCM281XX_I2C_PIN_REG_INPUT_DIS_MASK 0x0004 +#define BCM281XX_I2C_PIN_REG_INPUT_DIS_SHIFT 2 +#define BCM281XX_I2C_PIN_REG_SLEW_MASK 0x0008 +#define BCM281XX_I2C_PIN_REG_SLEW_SHIFT 3 +#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_MASK 0x0070 +#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_SHIFT 4 + +/* HDMI pin register */ +#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_MASK 0x0008 +#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_SHIFT 3 +#define BCM281XX_HDMI_PIN_REG_MODE_MASK 0x0010 +#define BCM281XX_HDMI_PIN_REG_MODE_SHIFT 4 + +/** + * bcm281xx_pin_type - types of pin register + */ +enum bcm281xx_pin_type { + BCM281XX_PIN_TYPE_UNKNOWN = 0, + BCM281XX_PIN_TYPE_STD, + BCM281XX_PIN_TYPE_I2C, + BCM281XX_PIN_TYPE_HDMI, +}; + +static enum bcm281xx_pin_type std_pin = BCM281XX_PIN_TYPE_STD; +static enum bcm281xx_pin_type i2c_pin = BCM281XX_PIN_TYPE_I2C; +static enum bcm281xx_pin_type hdmi_pin = BCM281XX_PIN_TYPE_HDMI; + +/** + * bcm281xx_pin_function- define pin function + */ +struct bcm281xx_pin_function { + const char *name; + const char * const *groups; + const unsigned ngroups; +}; + +/** + * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data + * @reg_base - base of pinctrl registers + */ +struct bcm281xx_pinctrl_data { + void __iomem *reg_base; + + /* List of all pins */ + const struct pinctrl_pin_desc *pins; + const unsigned npins; + + const struct bcm281xx_pin_function *functions; + const unsigned nfunctions; + + struct regmap *regmap; +}; + +/* + * Pin number definition. The order here must be the same as defined in the + * PADCTRLREG block in the RDB. + */ +#define BCM281XX_PIN_ADCSYNC 0 +#define BCM281XX_PIN_BAT_RM 1 +#define BCM281XX_PIN_BSC1_SCL 2 +#define BCM281XX_PIN_BSC1_SDA 3 +#define BCM281XX_PIN_BSC2_SCL 4 +#define BCM281XX_PIN_BSC2_SDA 5 +#define BCM281XX_PIN_CLASSGPWR 6 +#define BCM281XX_PIN_CLK_CX8 7 +#define BCM281XX_PIN_CLKOUT_0 8 +#define BCM281XX_PIN_CLKOUT_1 9 +#define BCM281XX_PIN_CLKOUT_2 10 +#define BCM281XX_PIN_CLKOUT_3 11 +#define BCM281XX_PIN_CLKREQ_IN_0 12 +#define BCM281XX_PIN_CLKREQ_IN_1 13 +#define BCM281XX_PIN_CWS_SYS_REQ1 14 +#define BCM281XX_PIN_CWS_SYS_REQ2 15 +#define BCM281XX_PIN_CWS_SYS_REQ3 16 +#define BCM281XX_PIN_DIGMIC1_CLK 17 +#define BCM281XX_PIN_DIGMIC1_DQ 18 +#define BCM281XX_PIN_DIGMIC2_CLK 19 +#define BCM281XX_PIN_DIGMIC2_DQ 20 +#define BCM281XX_PIN_GPEN13 21 +#define BCM281XX_PIN_GPEN14 22 +#define BCM281XX_PIN_GPEN15 23 +#define BCM281XX_PIN_GPIO00 24 +#define BCM281XX_PIN_GPIO01 25 +#define BCM281XX_PIN_GPIO02 26 +#define BCM281XX_PIN_GPIO03 27 +#define BCM281XX_PIN_GPIO04 28 +#define BCM281XX_PIN_GPIO05 29 +#define BCM281XX_PIN_GPIO06 30 +#define BCM281XX_PIN_GPIO07 31 +#define BCM281XX_PIN_GPIO08 32 +#define BCM281XX_PIN_GPIO09 33 +#define BCM281XX_PIN_GPIO10 34 +#define BCM281XX_PIN_GPIO11 35 +#define BCM281XX_PIN_GPIO12 36 +#define BCM281XX_PIN_GPIO13 37 +#define BCM281XX_PIN_GPIO14 38 +#define BCM281XX_PIN_GPS_PABLANK 39 +#define BCM281XX_PIN_GPS_TMARK 40 +#define BCM281XX_PIN_HDMI_SCL 41 +#define BCM281XX_PIN_HDMI_SDA 42 +#define BCM281XX_PIN_IC_DM 43 +#define BCM281XX_PIN_IC_DP 44 +#define BCM281XX_PIN_KP_COL_IP_0 45 +#define BCM281XX_PIN_KP_COL_IP_1 46 +#define BCM281XX_PIN_KP_COL_IP_2 47 +#define BCM281XX_PIN_KP_COL_IP_3 48 +#define BCM281XX_PIN_KP_ROW_OP_0 49 +#define BCM281XX_PIN_KP_ROW_OP_1 50 +#define BCM281XX_PIN_KP_ROW_OP_2 51 +#define BCM281XX_PIN_KP_ROW_OP_3 52 +#define BCM281XX_PIN_LCD_B_0 53 +#define BCM281XX_PIN_LCD_B_1 54 +#define BCM281XX_PIN_LCD_B_2 55 +#define BCM281XX_PIN_LCD_B_3 56 +#define BCM281XX_PIN_LCD_B_4 57 +#define BCM281XX_PIN_LCD_B_5 58 +#define BCM281XX_PIN_LCD_B_6 59 +#define BCM281XX_PIN_LCD_B_7 60 +#define BCM281XX_PIN_LCD_G_0 61 +#define BCM281XX_PIN_LCD_G_1 62 +#define BCM281XX_PIN_LCD_G_2 63 +#define BCM281XX_PIN_LCD_G_3 64 +#define BCM281XX_PIN_LCD_G_4 65 +#define BCM281XX_PIN_LCD_G_5 66 +#define BCM281XX_PIN_LCD_G_6 67 +#define BCM281XX_PIN_LCD_G_7 68 +#define BCM281XX_PIN_LCD_HSYNC 69 +#define BCM281XX_PIN_LCD_OE 70 +#define BCM281XX_PIN_LCD_PCLK 71 +#define BCM281XX_PIN_LCD_R_0 72 +#define BCM281XX_PIN_LCD_R_1 73 +#define BCM281XX_PIN_LCD_R_2 74 +#define BCM281XX_PIN_LCD_R_3 75 +#define BCM281XX_PIN_LCD_R_4 76 +#define BCM281XX_PIN_LCD_R_5 77 +#define BCM281XX_PIN_LCD_R_6 78 +#define BCM281XX_PIN_LCD_R_7 79 +#define BCM281XX_PIN_LCD_VSYNC 80 +#define BCM281XX_PIN_MDMGPIO0 81 +#define BCM281XX_PIN_MDMGPIO1 82 +#define BCM281XX_PIN_MDMGPIO2 83 +#define BCM281XX_PIN_MDMGPIO3 84 +#define BCM281XX_PIN_MDMGPIO4 85 +#define BCM281XX_PIN_MDMGPIO5 86 +#define BCM281XX_PIN_MDMGPIO6 87 +#define BCM281XX_PIN_MDMGPIO7 88 +#define BCM281XX_PIN_MDMGPIO8 89 +#define BCM281XX_PIN_MPHI_DATA_0 90 +#define BCM281XX_PIN_MPHI_DATA_1 91 +#define BCM281XX_PIN_MPHI_DATA_2 92 +#define BCM281XX_PIN_MPHI_DATA_3 93 +#define BCM281XX_PIN_MPHI_DATA_4 94 +#define BCM281XX_PIN_MPHI_DATA_5 95 +#define BCM281XX_PIN_MPHI_DATA_6 96 +#define BCM281XX_PIN_MPHI_DATA_7 97 +#define BCM281XX_PIN_MPHI_DATA_8 98 +#define BCM281XX_PIN_MPHI_DATA_9 99 +#define BCM281XX_PIN_MPHI_DATA_10 100 +#define BCM281XX_PIN_MPHI_DATA_11 101 +#define BCM281XX_PIN_MPHI_DATA_12 102 +#define BCM281XX_PIN_MPHI_DATA_13 103 +#define BCM281XX_PIN_MPHI_DATA_14 104 +#define BCM281XX_PIN_MPHI_DATA_15 105 +#define BCM281XX_PIN_MPHI_HA0 106 +#define BCM281XX_PIN_MPHI_HAT0 107 +#define BCM281XX_PIN_MPHI_HAT1 108 +#define BCM281XX_PIN_MPHI_HCE0_N 109 +#define BCM281XX_PIN_MPHI_HCE1_N 110 +#define BCM281XX_PIN_MPHI_HRD_N 111 +#define BCM281XX_PIN_MPHI_HWR_N 112 +#define BCM281XX_PIN_MPHI_RUN0 113 +#define BCM281XX_PIN_MPHI_RUN1 114 +#define BCM281XX_PIN_MTX_SCAN_CLK 115 +#define BCM281XX_PIN_MTX_SCAN_DATA 116 +#define BCM281XX_PIN_NAND_AD_0 117 +#define BCM281XX_PIN_NAND_AD_1 118 +#define BCM281XX_PIN_NAND_AD_2 119 +#define BCM281XX_PIN_NAND_AD_3 120 +#define BCM281XX_PIN_NAND_AD_4 121 +#define BCM281XX_PIN_NAND_AD_5 122 +#define BCM281XX_PIN_NAND_AD_6 123 +#define BCM281XX_PIN_NAND_AD_7 124 +#define BCM281XX_PIN_NAND_ALE 125 +#define BCM281XX_PIN_NAND_CEN_0 126 +#define BCM281XX_PIN_NAND_CEN_1 127 +#define BCM281XX_PIN_NAND_CLE 128 +#define BCM281XX_PIN_NAND_OEN 129 +#define BCM281XX_PIN_NAND_RDY_0 130 +#define BCM281XX_PIN_NAND_RDY_1 131 +#define BCM281XX_PIN_NAND_WEN 132 +#define BCM281XX_PIN_NAND_WP 133 +#define BCM281XX_PIN_PC1 134 +#define BCM281XX_PIN_PC2 135 +#define BCM281XX_PIN_PMU_INT 136 +#define BCM281XX_PIN_PMU_SCL 137 +#define BCM281XX_PIN_PMU_SDA 138 +#define BCM281XX_PIN_RFST2G_MTSLOTEN3G 139 +#define BCM281XX_PIN_RGMII_0_RX_CTL 140 +#define BCM281XX_PIN_RGMII_0_RXC 141 +#define BCM281XX_PIN_RGMII_0_RXD_0 142 +#define BCM281XX_PIN_RGMII_0_RXD_1 143 +#define BCM281XX_PIN_RGMII_0_RXD_2 144 +#define BCM281XX_PIN_RGMII_0_RXD_3 145 +#define BCM281XX_PIN_RGMII_0_TX_CTL 146 +#define BCM281XX_PIN_RGMII_0_TXC 147 +#define BCM281XX_PIN_RGMII_0_TXD_0 148 +#define BCM281XX_PIN_RGMII_0_TXD_1 149 +#define BCM281XX_PIN_RGMII_0_TXD_2 150 +#define BCM281XX_PIN_RGMII_0_TXD_3 151 +#define BCM281XX_PIN_RGMII_1_RX_CTL 152 +#define BCM281XX_PIN_RGMII_1_RXC 153 +#define BCM281XX_PIN_RGMII_1_RXD_0 154 +#define BCM281XX_PIN_RGMII_1_RXD_1 155 +#define BCM281XX_PIN_RGMII_1_RXD_2 156 +#define BCM281XX_PIN_RGMII_1_RXD_3 157 +#define BCM281XX_PIN_RGMII_1_TX_CTL 158 +#define BCM281XX_PIN_RGMII_1_TXC 159 +#define BCM281XX_PIN_RGMII_1_TXD_0 160 +#define BCM281XX_PIN_RGMII_1_TXD_1 161 +#define BCM281XX_PIN_RGMII_1_TXD_2 162 +#define BCM281XX_PIN_RGMII_1_TXD_3 163 +#define BCM281XX_PIN_RGMII_GPIO_0 164 +#define BCM281XX_PIN_RGMII_GPIO_1 165 +#define BCM281XX_PIN_RGMII_GPIO_2 166 +#define BCM281XX_PIN_RGMII_GPIO_3 167 +#define BCM281XX_PIN_RTXDATA2G_TXDATA3G1 168 +#define BCM281XX_PIN_RTXEN2G_TXDATA3G2 169 +#define BCM281XX_PIN_RXDATA3G0 170 +#define BCM281XX_PIN_RXDATA3G1 171 +#define BCM281XX_PIN_RXDATA3G2 172 +#define BCM281XX_PIN_SDIO1_CLK 173 +#define BCM281XX_PIN_SDIO1_CMD 174 +#define BCM281XX_PIN_SDIO1_DATA_0 175 +#define BCM281XX_PIN_SDIO1_DATA_1 176 +#define BCM281XX_PIN_SDIO1_DATA_2 177 +#define BCM281XX_PIN_SDIO1_DATA_3 178 +#define BCM281XX_PIN_SDIO4_CLK 179 +#define BCM281XX_PIN_SDIO4_CMD 180 +#define BCM281XX_PIN_SDIO4_DATA_0 181 +#define BCM281XX_PIN_SDIO4_DATA_1 182 +#define BCM281XX_PIN_SDIO4_DATA_2 183 +#define BCM281XX_PIN_SDIO4_DATA_3 184 +#define BCM281XX_PIN_SIM_CLK 185 +#define BCM281XX_PIN_SIM_DATA 186 +#define BCM281XX_PIN_SIM_DET 187 +#define BCM281XX_PIN_SIM_RESETN 188 +#define BCM281XX_PIN_SIM2_CLK 189 +#define BCM281XX_PIN_SIM2_DATA 190 +#define BCM281XX_PIN_SIM2_DET 191 +#define BCM281XX_PIN_SIM2_RESETN 192 +#define BCM281XX_PIN_SRI_C 193 +#define BCM281XX_PIN_SRI_D 194 +#define BCM281XX_PIN_SRI_E 195 +#define BCM281XX_PIN_SSP_EXTCLK 196 +#define BCM281XX_PIN_SSP0_CLK 197 +#define BCM281XX_PIN_SSP0_FS 198 +#define BCM281XX_PIN_SSP0_RXD 199 +#define BCM281XX_PIN_SSP0_TXD 200 +#define BCM281XX_PIN_SSP2_CLK 201 +#define BCM281XX_PIN_SSP2_FS_0 202 +#define BCM281XX_PIN_SSP2_FS_1 203 +#define BCM281XX_PIN_SSP2_FS_2 204 +#define BCM281XX_PIN_SSP2_FS_3 205 +#define BCM281XX_PIN_SSP2_RXD_0 206 +#define BCM281XX_PIN_SSP2_RXD_1 207 +#define BCM281XX_PIN_SSP2_TXD_0 208 +#define BCM281XX_PIN_SSP2_TXD_1 209 +#define BCM281XX_PIN_SSP3_CLK 210 +#define BCM281XX_PIN_SSP3_FS 211 +#define BCM281XX_PIN_SSP3_RXD 212 +#define BCM281XX_PIN_SSP3_TXD 213 +#define BCM281XX_PIN_SSP4_CLK 214 +#define BCM281XX_PIN_SSP4_FS 215 +#define BCM281XX_PIN_SSP4_RXD 216 +#define BCM281XX_PIN_SSP4_TXD 217 +#define BCM281XX_PIN_SSP5_CLK 218 +#define BCM281XX_PIN_SSP5_FS 219 +#define BCM281XX_PIN_SSP5_RXD 220 +#define BCM281XX_PIN_SSP5_TXD 221 +#define BCM281XX_PIN_SSP6_CLK 222 +#define BCM281XX_PIN_SSP6_FS 223 +#define BCM281XX_PIN_SSP6_RXD 224 +#define BCM281XX_PIN_SSP6_TXD 225 +#define BCM281XX_PIN_STAT_1 226 +#define BCM281XX_PIN_STAT_2 227 +#define BCM281XX_PIN_SYSCLKEN 228 +#define BCM281XX_PIN_TRACECLK 229 +#define BCM281XX_PIN_TRACEDT00 230 +#define BCM281XX_PIN_TRACEDT01 231 +#define BCM281XX_PIN_TRACEDT02 232 +#define BCM281XX_PIN_TRACEDT03 233 +#define BCM281XX_PIN_TRACEDT04 234 +#define BCM281XX_PIN_TRACEDT05 235 +#define BCM281XX_PIN_TRACEDT06 236 +#define BCM281XX_PIN_TRACEDT07 237 +#define BCM281XX_PIN_TRACEDT08 238 +#define BCM281XX_PIN_TRACEDT09 239 +#define BCM281XX_PIN_TRACEDT10 240 +#define BCM281XX_PIN_TRACEDT11 241 +#define BCM281XX_PIN_TRACEDT12 242 +#define BCM281XX_PIN_TRACEDT13 243 +#define BCM281XX_PIN_TRACEDT14 244 +#define BCM281XX_PIN_TRACEDT15 245 +#define BCM281XX_PIN_TXDATA3G0 246 +#define BCM281XX_PIN_TXPWRIND 247 +#define BCM281XX_PIN_UARTB1_UCTS 248 +#define BCM281XX_PIN_UARTB1_URTS 249 +#define BCM281XX_PIN_UARTB1_URXD 250 +#define BCM281XX_PIN_UARTB1_UTXD 251 +#define BCM281XX_PIN_UARTB2_URXD 252 +#define BCM281XX_PIN_UARTB2_UTXD 253 +#define BCM281XX_PIN_UARTB3_UCTS 254 +#define BCM281XX_PIN_UARTB3_URTS 255 +#define BCM281XX_PIN_UARTB3_URXD 256 +#define BCM281XX_PIN_UARTB3_UTXD 257 +#define BCM281XX_PIN_UARTB4_UCTS 258 +#define BCM281XX_PIN_UARTB4_URTS 259 +#define BCM281XX_PIN_UARTB4_URXD 260 +#define BCM281XX_PIN_UARTB4_UTXD 261 +#define BCM281XX_PIN_VC_CAM1_SCL 262 +#define BCM281XX_PIN_VC_CAM1_SDA 263 +#define BCM281XX_PIN_VC_CAM2_SCL 264 +#define BCM281XX_PIN_VC_CAM2_SDA 265 +#define BCM281XX_PIN_VC_CAM3_SCL 266 +#define BCM281XX_PIN_VC_CAM3_SDA 267 + +#define BCM281XX_PIN_DESC(a, b, c) \ + { .number = a, .name = b, .drv_data = &c##_pin } + +/* + * Pin description definition. The order here must be the same as defined in + * the PADCTRLREG block in the RDB, since the pin number is used as an index + * into this array. + */ +static const struct pinctrl_pin_desc bcm281xx_pinctrl_pins[] = { + BCM281XX_PIN_DESC(BCM281XX_PIN_ADCSYNC, "adcsync", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_BAT_RM, "bat_rm", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SCL, "bsc1_scl", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SDA, "bsc1_sda", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SCL, "bsc2_scl", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SDA, "bsc2_sda", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLASSGPWR, "classgpwr", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLK_CX8, "clk_cx8", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_0, "clkout_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_1, "clkout_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_2, "clkout_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_3, "clkout_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_0, "clkreq_in_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_1, "clkreq_in_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ1, "cws_sys_req1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ2, "cws_sys_req2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ3, "cws_sys_req3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_CLK, "digmic1_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_DQ, "digmic1_dq", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_CLK, "digmic2_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_DQ, "digmic2_dq", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN13, "gpen13", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN14, "gpen14", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN15, "gpen15", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO00, "gpio00", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO01, "gpio01", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO02, "gpio02", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO03, "gpio03", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO04, "gpio04", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO05, "gpio05", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO06, "gpio06", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO07, "gpio07", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO08, "gpio08", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO09, "gpio09", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO10, "gpio10", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO11, "gpio11", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO12, "gpio12", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO13, "gpio13", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO14, "gpio14", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_PABLANK, "gps_pablank", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_TMARK, "gps_tmark", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SCL, "hdmi_scl", hdmi), + BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SDA, "hdmi_sda", hdmi), + BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DM, "ic_dm", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DP, "ic_dp", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_0, "kp_col_ip_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_1, "kp_col_ip_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_2, "kp_col_ip_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_3, "kp_col_ip_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_0, "kp_row_op_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_1, "kp_row_op_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_2, "kp_row_op_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_3, "kp_row_op_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_0, "lcd_b_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_1, "lcd_b_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_2, "lcd_b_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_3, "lcd_b_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_4, "lcd_b_4", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_5, "lcd_b_5", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_6, "lcd_b_6", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_7, "lcd_b_7", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_0, "lcd_g_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_1, "lcd_g_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_2, "lcd_g_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_3, "lcd_g_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_4, "lcd_g_4", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_5, "lcd_g_5", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_6, "lcd_g_6", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_7, "lcd_g_7", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_HSYNC, "lcd_hsync", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_OE, "lcd_oe", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_PCLK, "lcd_pclk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_0, "lcd_r_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_1, "lcd_r_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_2, "lcd_r_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_3, "lcd_r_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_4, "lcd_r_4", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_5, "lcd_r_5", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_6, "lcd_r_6", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_7, "lcd_r_7", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_VSYNC, "lcd_vsync", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO0, "mdmgpio0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO1, "mdmgpio1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO2, "mdmgpio2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO3, "mdmgpio3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO4, "mdmgpio4", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO5, "mdmgpio5", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO6, "mdmgpio6", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO7, "mdmgpio7", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO8, "mdmgpio8", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_0, "mphi_data_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_1, "mphi_data_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_2, "mphi_data_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_3, "mphi_data_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_4, "mphi_data_4", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_5, "mphi_data_5", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_6, "mphi_data_6", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_7, "mphi_data_7", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_8, "mphi_data_8", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_9, "mphi_data_9", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_10, "mphi_data_10", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_11, "mphi_data_11", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_12, "mphi_data_12", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_13, "mphi_data_13", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_14, "mphi_data_14", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_15, "mphi_data_15", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HA0, "mphi_ha0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT0, "mphi_hat0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT1, "mphi_hat1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE0_N, "mphi_hce0_n", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE1_N, "mphi_hce1_n", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HRD_N, "mphi_hrd_n", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HWR_N, "mphi_hwr_n", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN0, "mphi_run0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN1, "mphi_run1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_DATA, "mtx_scan_data", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_0, "nand_ad_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_1, "nand_ad_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_2, "nand_ad_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_3, "nand_ad_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_4, "nand_ad_4", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_5, "nand_ad_5", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_6, "nand_ad_6", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_7, "nand_ad_7", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_ALE, "nand_ale", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_0, "nand_cen_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_1, "nand_cen_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CLE, "nand_cle", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_OEN, "nand_oen", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_0, "nand_rdy_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_1, "nand_rdy_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WEN, "nand_wen", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WP, "nand_wp", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_PC1, "pc1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_PC2, "pc2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_INT, "pmu_int", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SCL, "pmu_scl", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SDA, "pmu_sda", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g", + std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXC, "rgmii_0_rxc", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXC, "rgmii_0_txc", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXC, "rgmii_1_rxc", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXC, "rgmii_1_txc", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RTXDATA2G_TXDATA3G1, + "rtxdata2g_txdata3g1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2", + std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G0, "rxdata3g0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G1, "rxdata3g1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G2, "rxdata3g2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CLK, "sdio1_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CMD, "sdio1_cmd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_0, "sdio1_data_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_1, "sdio1_data_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_2, "sdio1_data_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_3, "sdio1_data_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CLK, "sdio4_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CMD, "sdio4_cmd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_0, "sdio4_data_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_1, "sdio4_data_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_2, "sdio4_data_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_3, "sdio4_data_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_CLK, "sim_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DATA, "sim_data", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DET, "sim_det", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_RESETN, "sim_resetn", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_CLK, "sim2_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DATA, "sim2_data", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DET, "sim2_det", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_RESETN, "sim2_resetn", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_C, "sri_c", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_D, "sri_d", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_E, "sri_e", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP_EXTCLK, "ssp_extclk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_CLK, "ssp0_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_FS, "ssp0_fs", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_RXD, "ssp0_rxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_TXD, "ssp0_txd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_CLK, "ssp2_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_0, "ssp2_fs_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_1, "ssp2_fs_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_2, "ssp2_fs_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_3, "ssp2_fs_3", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_0, "ssp2_rxd_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_1, "ssp2_rxd_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_0, "ssp2_txd_0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_1, "ssp2_txd_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_CLK, "ssp3_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_FS, "ssp3_fs", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_RXD, "ssp3_rxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_TXD, "ssp3_txd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_CLK, "ssp4_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_FS, "ssp4_fs", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_RXD, "ssp4_rxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_TXD, "ssp4_txd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_CLK, "ssp5_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_FS, "ssp5_fs", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_RXD, "ssp5_rxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_TXD, "ssp5_txd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_CLK, "ssp6_clk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_FS, "ssp6_fs", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_RXD, "ssp6_rxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_TXD, "ssp6_txd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_1, "stat_1", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_2, "stat_2", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_SYSCLKEN, "sysclken", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACECLK, "traceclk", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT00, "tracedt00", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT01, "tracedt01", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT02, "tracedt02", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT03, "tracedt03", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT04, "tracedt04", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT05, "tracedt05", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT06, "tracedt06", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT07, "tracedt07", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT08, "tracedt08", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT09, "tracedt09", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT10, "tracedt10", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT11, "tracedt11", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT12, "tracedt12", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT13, "tracedt13", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT14, "tracedt14", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT15, "tracedt15", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TXDATA3G0, "txdata3g0", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_TXPWRIND, "txpwrind", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UCTS, "uartb1_ucts", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URTS, "uartb1_urts", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URXD, "uartb1_urxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UTXD, "uartb1_utxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_URXD, "uartb2_urxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_UTXD, "uartb2_utxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UCTS, "uartb3_ucts", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URTS, "uartb3_urts", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URXD, "uartb3_urxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UTXD, "uartb3_utxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UCTS, "uartb4_ucts", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URTS, "uartb4_urts", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URXD, "uartb4_urxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UTXD, "uartb4_utxd", std), + BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c), + BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c), +}; + +static const char * const bcm281xx_alt_groups[] = { + "adcsync", + "bat_rm", + "bsc1_scl", + "bsc1_sda", + "bsc2_scl", + "bsc2_sda", + "classgpwr", + "clk_cx8", + "clkout_0", + "clkout_1", + "clkout_2", + "clkout_3", + "clkreq_in_0", + "clkreq_in_1", + "cws_sys_req1", + "cws_sys_req2", + "cws_sys_req3", + "digmic1_clk", + "digmic1_dq", + "digmic2_clk", + "digmic2_dq", + "gpen13", + "gpen14", + "gpen15", + "gpio00", + "gpio01", + "gpio02", + "gpio03", + "gpio04", + "gpio05", + "gpio06", + "gpio07", + "gpio08", + "gpio09", + "gpio10", + "gpio11", + "gpio12", + "gpio13", + "gpio14", + "gps_pablank", + "gps_tmark", + "hdmi_scl", + "hdmi_sda", + "ic_dm", + "ic_dp", + "kp_col_ip_0", + "kp_col_ip_1", + "kp_col_ip_2", + "kp_col_ip_3", + "kp_row_op_0", + "kp_row_op_1", + "kp_row_op_2", + "kp_row_op_3", + "lcd_b_0", + "lcd_b_1", + "lcd_b_2", + "lcd_b_3", + "lcd_b_4", + "lcd_b_5", + "lcd_b_6", + "lcd_b_7", + "lcd_g_0", + "lcd_g_1", + "lcd_g_2", + "lcd_g_3", + "lcd_g_4", + "lcd_g_5", + "lcd_g_6", + "lcd_g_7", + "lcd_hsync", + "lcd_oe", + "lcd_pclk", + "lcd_r_0", + "lcd_r_1", + "lcd_r_2", + "lcd_r_3", + "lcd_r_4", + "lcd_r_5", + "lcd_r_6", + "lcd_r_7", + "lcd_vsync", + "mdmgpio0", + "mdmgpio1", + "mdmgpio2", + "mdmgpio3", + "mdmgpio4", + "mdmgpio5", + "mdmgpio6", + "mdmgpio7", + "mdmgpio8", + "mphi_data_0", + "mphi_data_1", + "mphi_data_2", + "mphi_data_3", + "mphi_data_4", + "mphi_data_5", + "mphi_data_6", + "mphi_data_7", + "mphi_data_8", + "mphi_data_9", + "mphi_data_10", + "mphi_data_11", + "mphi_data_12", + "mphi_data_13", + "mphi_data_14", + "mphi_data_15", + "mphi_ha0", + "mphi_hat0", + "mphi_hat1", + "mphi_hce0_n", + "mphi_hce1_n", + "mphi_hrd_n", + "mphi_hwr_n", + "mphi_run0", + "mphi_run1", + "mtx_scan_clk", + "mtx_scan_data", + "nand_ad_0", + "nand_ad_1", + "nand_ad_2", + "nand_ad_3", + "nand_ad_4", + "nand_ad_5", + "nand_ad_6", + "nand_ad_7", + "nand_ale", + "nand_cen_0", + "nand_cen_1", + "nand_cle", + "nand_oen", + "nand_rdy_0", + "nand_rdy_1", + "nand_wen", + "nand_wp", + "pc1", + "pc2", + "pmu_int", + "pmu_scl", + "pmu_sda", + "rfst2g_mtsloten3g", + "rgmii_0_rx_ctl", + "rgmii_0_rxc", + "rgmii_0_rxd_0", + "rgmii_0_rxd_1", + "rgmii_0_rxd_2", + "rgmii_0_rxd_3", + "rgmii_0_tx_ctl", + "rgmii_0_txc", + "rgmii_0_txd_0", + "rgmii_0_txd_1", + "rgmii_0_txd_2", + "rgmii_0_txd_3", + "rgmii_1_rx_ctl", + "rgmii_1_rxc", + "rgmii_1_rxd_0", + "rgmii_1_rxd_1", + "rgmii_1_rxd_2", + "rgmii_1_rxd_3", + "rgmii_1_tx_ctl", + "rgmii_1_txc", + "rgmii_1_txd_0", + "rgmii_1_txd_1", + "rgmii_1_txd_2", + "rgmii_1_txd_3", + "rgmii_gpio_0", + "rgmii_gpio_1", + "rgmii_gpio_2", + "rgmii_gpio_3", + "rtxdata2g_txdata3g1", + "rtxen2g_txdata3g2", + "rxdata3g0", + "rxdata3g1", + "rxdata3g2", + "sdio1_clk", + "sdio1_cmd", + "sdio1_data_0", + "sdio1_data_1", + "sdio1_data_2", + "sdio1_data_3", + "sdio4_clk", + "sdio4_cmd", + "sdio4_data_0", + "sdio4_data_1", + "sdio4_data_2", + "sdio4_data_3", + "sim_clk", + "sim_data", + "sim_det", + "sim_resetn", + "sim2_clk", + "sim2_data", + "sim2_det", + "sim2_resetn", + "sri_c", + "sri_d", + "sri_e", + "ssp_extclk", + "ssp0_clk", + "ssp0_fs", + "ssp0_rxd", + "ssp0_txd", + "ssp2_clk", + "ssp2_fs_0", + "ssp2_fs_1", + "ssp2_fs_2", + "ssp2_fs_3", + "ssp2_rxd_0", + "ssp2_rxd_1", + "ssp2_txd_0", + "ssp2_txd_1", + "ssp3_clk", + "ssp3_fs", + "ssp3_rxd", + "ssp3_txd", + "ssp4_clk", + "ssp4_fs", + "ssp4_rxd", + "ssp4_txd", + "ssp5_clk", + "ssp5_fs", + "ssp5_rxd", + "ssp5_txd", + "ssp6_clk", + "ssp6_fs", + "ssp6_rxd", + "ssp6_txd", + "stat_1", + "stat_2", + "sysclken", + "traceclk", + "tracedt00", + "tracedt01", + "tracedt02", + "tracedt03", + "tracedt04", + "tracedt05", + "tracedt06", + "tracedt07", + "tracedt08", + "tracedt09", + "tracedt10", + "tracedt11", + "tracedt12", + "tracedt13", + "tracedt14", + "tracedt15", + "txdata3g0", + "txpwrind", + "uartb1_ucts", + "uartb1_urts", + "uartb1_urxd", + "uartb1_utxd", + "uartb2_urxd", + "uartb2_utxd", + "uartb3_ucts", + "uartb3_urts", + "uartb3_urxd", + "uartb3_utxd", + "uartb4_ucts", + "uartb4_urts", + "uartb4_urxd", + "uartb4_utxd", + "vc_cam1_scl", + "vc_cam1_sda", + "vc_cam2_scl", + "vc_cam2_sda", + "vc_cam3_scl", + "vc_cam3_sda", +}; + +/* Every pin can implement all ALT1-ALT4 functions */ +#define BCM281XX_PIN_FUNCTION(fcn_name) \ +{ \ + .name = #fcn_name, \ + .groups = bcm281xx_alt_groups, \ + .ngroups = ARRAY_SIZE(bcm281xx_alt_groups), \ +} + +static const struct bcm281xx_pin_function bcm281xx_functions[] = { + BCM281XX_PIN_FUNCTION(alt1), + BCM281XX_PIN_FUNCTION(alt2), + BCM281XX_PIN_FUNCTION(alt3), + BCM281XX_PIN_FUNCTION(alt4), +}; + +static struct bcm281xx_pinctrl_data bcm281xx_pinctrl = { + .pins = bcm281xx_pinctrl_pins, + .npins = ARRAY_SIZE(bcm281xx_pinctrl_pins), + .functions = bcm281xx_functions, + .nfunctions = ARRAY_SIZE(bcm281xx_functions), +}; + +static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev, + unsigned pin) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + if (pin >= pdata->npins) + return BCM281XX_PIN_TYPE_UNKNOWN; + + return *(enum bcm281xx_pin_type *)(pdata->pins[pin].drv_data); +} + +#define BCM281XX_PIN_SHIFT(type, param) \ + (BCM281XX_ ## type ## _PIN_REG_ ## param ## _SHIFT) + +#define BCM281XX_PIN_MASK(type, param) \ + (BCM281XX_ ## type ## _PIN_REG_ ## param ## _MASK) + +/* + * This helper function is used to build up the value and mask used to write to + * a pin register, but does not actually write to the register. + */ +static inline void bcm281xx_pin_update(u32 *reg_val, u32 *reg_mask, + u32 param_val, u32 param_shift, + u32 param_mask) +{ + *reg_val &= ~param_mask; + *reg_val |= (param_val << param_shift) & param_mask; + *reg_mask |= param_mask; +} + +static struct regmap_config bcm281xx_pinctrl_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = BCM281XX_PIN_VC_CAM3_SDA, +}; + +static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + return pdata->npins; +} + +static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned group) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + return pdata->pins[group].name; +} + +static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned group, + const unsigned **pins, + unsigned *num_pins) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + *pins = &pdata->pins[group].number; + *num_pins = 1; + + return 0; +} + +static void bcm281xx_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, + struct seq_file *s, + unsigned offset) +{ + seq_printf(s, " %s", dev_name(pctldev->dev)); +} + +static struct pinctrl_ops bcm281xx_pinctrl_ops = { + .get_groups_count = bcm281xx_pinctrl_get_groups_count, + .get_group_name = bcm281xx_pinctrl_get_group_name, + .get_group_pins = bcm281xx_pinctrl_get_group_pins, + .pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_dt_free_map, +}; + +static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + return pdata->nfunctions; +} + +static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev, + unsigned function) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + return pdata->functions[function].name; +} + +static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev, + unsigned function, + const char * const **groups, + unsigned * const num_groups) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + + *groups = pdata->functions[function].groups; + *num_groups = pdata->functions[function].ngroups; + + return 0; +} + +static int bcm281xx_pinmux_enable(struct pinctrl_dev *pctldev, + unsigned function, + unsigned group) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + const struct bcm281xx_pin_function *f = &pdata->functions[function]; + u32 offset = 4 * pdata->pins[group].number; + int rc = 0; + + dev_dbg(pctldev->dev, + "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n", + __func__, f->name, function, pdata->pins[group].name, + pdata->pins[group].number, offset); + + rc = regmap_update_bits(pdata->regmap, offset, + BCM281XX_PIN_REG_F_SEL_MASK, + function << BCM281XX_PIN_REG_F_SEL_SHIFT); + if (rc) + dev_err(pctldev->dev, + "Error updating register for pin %s (%d).\n", + pdata->pins[group].name, pdata->pins[group].number); + + return rc; +} + +static struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = { + .get_functions_count = bcm281xx_pinctrl_get_fcns_count, + .get_function_name = bcm281xx_pinctrl_get_fcn_name, + .get_function_groups = bcm281xx_pinctrl_get_fcn_groups, + .enable = bcm281xx_pinmux_enable, +}; + +static int bcm281xx_pinctrl_pin_config_get(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *config) +{ + return -ENOTSUPP; +} + + +/* Goes through the configs and update register val/mask */ +static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *configs, + unsigned num_configs, + u32 *val, + u32 *mask) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + int i; + enum pin_config_param param; + u16 arg; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + arg = (arg >= 1 ? 1 : 0); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(STD, HYST), + BCM281XX_PIN_MASK(STD, HYST)); + break; + /* + * The pin bias can only be one of pull-up, pull-down, or + * disable. The user does not need to specify a value for the + * property, and the default value from pinconf-generic is + * ignored. + */ + case PIN_CONFIG_BIAS_DISABLE: + bcm281xx_pin_update(val, mask, 0, + BCM281XX_PIN_SHIFT(STD, PULL_UP), + BCM281XX_PIN_MASK(STD, PULL_UP)); + bcm281xx_pin_update(val, mask, 0, + BCM281XX_PIN_SHIFT(STD, PULL_DN), + BCM281XX_PIN_MASK(STD, PULL_DN)); + break; + + case PIN_CONFIG_BIAS_PULL_UP: + bcm281xx_pin_update(val, mask, 1, + BCM281XX_PIN_SHIFT(STD, PULL_UP), + BCM281XX_PIN_MASK(STD, PULL_UP)); + bcm281xx_pin_update(val, mask, 0, + BCM281XX_PIN_SHIFT(STD, PULL_DN), + BCM281XX_PIN_MASK(STD, PULL_DN)); + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + bcm281xx_pin_update(val, mask, 0, + BCM281XX_PIN_SHIFT(STD, PULL_UP), + BCM281XX_PIN_MASK(STD, PULL_UP)); + bcm281xx_pin_update(val, mask, 1, + BCM281XX_PIN_SHIFT(STD, PULL_DN), + BCM281XX_PIN_MASK(STD, PULL_DN)); + break; + + case PIN_CONFIG_SLEW_RATE: + arg = (arg >= 1 ? 1 : 0); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(STD, SLEW), + BCM281XX_PIN_MASK(STD, SLEW)); + break; + + case PIN_CONFIG_INPUT_ENABLE: + /* inversed since register is for input _disable_ */ + arg = (arg >= 1 ? 0 : 1); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(STD, INPUT_DIS), + BCM281XX_PIN_MASK(STD, INPUT_DIS)); + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + /* Valid range is 2-16 mA, even numbers only */ + if ((arg < 2) || (arg > 16) || (arg % 2)) { + dev_err(pctldev->dev, + "Invalid Drive Strength value (%d) for " + "pin %s (%d). Valid values are " + "(2..16) mA, even numbers only.\n", + arg, pdata->pins[pin].name, pin); + return -EINVAL; + } + bcm281xx_pin_update(val, mask, (arg/2)-1, + BCM281XX_PIN_SHIFT(STD, DRV_STR), + BCM281XX_PIN_MASK(STD, DRV_STR)); + break; + + default: + dev_err(pctldev->dev, + "Unrecognized pin config %d for pin %s (%d).\n", + param, pdata->pins[pin].name, pin); + return -EINVAL; + + } /* switch config */ + } /* for each config */ + + return 0; +} + +/* + * The pull-up strength for an I2C pin is represented by bits 4-6 in the + * register with the following mapping: + * 0b000: No pull-up + * 0b001: 1200 Ohm + * 0b010: 1800 Ohm + * 0b011: 720 Ohm + * 0b100: 2700 Ohm + * 0b101: 831 Ohm + * 0b110: 1080 Ohm + * 0b111: 568 Ohm + * This array maps pull-up strength in Ohms to register values (1+index). + */ +static const u16 bcm281xx_pullup_map[] = { + 1200, 1800, 720, 2700, 831, 1080, 568 +}; + +/* Goes through the configs and update register val/mask */ +static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *configs, + unsigned num_configs, + u32 *val, + u32 *mask) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + int i, j; + enum pin_config_param param; + u16 arg; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + for (j = 0; j < ARRAY_SIZE(bcm281xx_pullup_map); j++) + if (bcm281xx_pullup_map[j] == arg) + break; + + if (j == ARRAY_SIZE(bcm281xx_pullup_map)) { + dev_err(pctldev->dev, + "Invalid pull-up value (%d) for pin %s " + "(%d). Valid values are 568, 720, 831, " + "1080, 1200, 1800, 2700 Ohms.\n", + arg, pdata->pins[pin].name, pin); + return -EINVAL; + } + + bcm281xx_pin_update(val, mask, j+1, + BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR), + BCM281XX_PIN_MASK(I2C, PULL_UP_STR)); + break; + + case PIN_CONFIG_BIAS_DISABLE: + bcm281xx_pin_update(val, mask, 0, + BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR), + BCM281XX_PIN_MASK(I2C, PULL_UP_STR)); + break; + + case PIN_CONFIG_SLEW_RATE: + arg = (arg >= 1 ? 1 : 0); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(I2C, SLEW), + BCM281XX_PIN_MASK(I2C, SLEW)); + break; + + case PIN_CONFIG_INPUT_ENABLE: + /* inversed since register is for input _disable_ */ + arg = (arg >= 1 ? 0 : 1); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(I2C, INPUT_DIS), + BCM281XX_PIN_MASK(I2C, INPUT_DIS)); + break; + + default: + dev_err(pctldev->dev, + "Unrecognized pin config %d for pin %s (%d).\n", + param, pdata->pins[pin].name, pin); + return -EINVAL; + + } /* switch config */ + } /* for each config */ + + return 0; +} + +/* Goes through the configs and update register val/mask */ +static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *configs, + unsigned num_configs, + u32 *val, + u32 *mask) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + int i; + enum pin_config_param param; + u16 arg; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_SLEW_RATE: + arg = (arg >= 1 ? 1 : 0); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(HDMI, MODE), + BCM281XX_PIN_MASK(HDMI, MODE)); + break; + + case PIN_CONFIG_INPUT_ENABLE: + /* inversed since register is for input _disable_ */ + arg = (arg >= 1 ? 0 : 1); + bcm281xx_pin_update(val, mask, arg, + BCM281XX_PIN_SHIFT(HDMI, INPUT_DIS), + BCM281XX_PIN_MASK(HDMI, INPUT_DIS)); + break; + + default: + dev_err(pctldev->dev, + "Unrecognized pin config %d for pin %s (%d).\n", + param, pdata->pins[pin].name, pin); + return -EINVAL; + + } /* switch config */ + } /* for each config */ + + return 0; +} + +static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev, + unsigned pin, + unsigned long *configs, + unsigned num_configs) +{ + struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); + enum bcm281xx_pin_type pin_type; + u32 offset = 4 * pin; + u32 cfg_val, cfg_mask; + int rc; + + cfg_val = 0; + cfg_mask = 0; + pin_type = pin_type_get(pctldev, pin); + + /* Different pins have different configuration options */ + switch (pin_type) { + case BCM281XX_PIN_TYPE_STD: + rc = bcm281xx_std_pin_update(pctldev, pin, configs, + num_configs, &cfg_val, &cfg_mask); + break; + + case BCM281XX_PIN_TYPE_I2C: + rc = bcm281xx_i2c_pin_update(pctldev, pin, configs, + num_configs, &cfg_val, &cfg_mask); + break; + + case BCM281XX_PIN_TYPE_HDMI: + rc = bcm281xx_hdmi_pin_update(pctldev, pin, configs, + num_configs, &cfg_val, &cfg_mask); + break; + + default: + dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n", + pdata->pins[pin].name, pin); + return -EINVAL; + + } /* switch pin type */ + + if (rc) + return rc; + + dev_dbg(pctldev->dev, + "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n", + __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask); + + rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val); + if (rc) { + dev_err(pctldev->dev, + "Error updating register for pin %s (%d).\n", + pdata->pins[pin].name, pin); + return rc; + } + + return 0; +} + +static struct pinconf_ops bcm281xx_pinctrl_pinconf_ops = { + .pin_config_get = bcm281xx_pinctrl_pin_config_get, + .pin_config_set = bcm281xx_pinctrl_pin_config_set, +}; + +static struct pinctrl_desc bcm281xx_pinctrl_desc = { + /* name, pins, npins members initialized in probe function */ + .pctlops = &bcm281xx_pinctrl_ops, + .pmxops = &bcm281xx_pinctrl_pinmux_ops, + .confops = &bcm281xx_pinctrl_pinconf_ops, + .owner = THIS_MODULE, +}; + +int __init bcm281xx_pinctrl_probe(struct platform_device *pdev) +{ + struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl; + struct resource *res; + struct pinctrl_dev *pctl; + + /* So far We can assume there is only 1 bank of registers */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Missing MEM resource\n"); + return -ENODEV; + } + + pdata->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pdata->reg_base)) { + dev_err(&pdev->dev, "Failed to ioremap MEM resource\n"); + return -ENODEV; + } + + /* Initialize the dynamic part of pinctrl_desc */ + pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base, + &bcm281xx_pinctrl_regmap_config); + if (IS_ERR(pdata->regmap)) { + dev_err(&pdev->dev, "Regmap MMIO init failed.\n"); + return -ENODEV; + } + + bcm281xx_pinctrl_desc.name = dev_name(&pdev->dev); + bcm281xx_pinctrl_desc.pins = bcm281xx_pinctrl.pins; + bcm281xx_pinctrl_desc.npins = bcm281xx_pinctrl.npins; + + pctl = pinctrl_register(&bcm281xx_pinctrl_desc, + &pdev->dev, + pdata); + if (!pctl) { + dev_err(&pdev->dev, "Failed to register pinctrl\n"); + return -ENODEV; + } + + platform_set_drvdata(pdev, pdata); + + return 0; +} + +static struct of_device_id bcm281xx_pinctrl_of_match[] = { + { .compatible = "brcm,bcm11351-pinctrl", }, + { }, +}; + +static struct platform_driver bcm281xx_pinctrl_driver = { + .driver = { + .name = "bcm281xx-pinctrl", + .owner = THIS_MODULE, + .of_match_table = bcm281xx_pinctrl_of_match, + }, +}; + +module_platform_driver_probe(bcm281xx_pinctrl_driver, bcm281xx_pinctrl_probe); + +MODULE_AUTHOR("Broadcom Corporation "); +MODULE_AUTHOR("Sherman Yin "); +MODULE_DESCRIPTION("Broadcom BCM281xx pinctrl driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-capri.c b/drivers/pinctrl/pinctrl-capri.c deleted file mode 100644 index eb2500212147..000000000000 --- a/drivers/pinctrl/pinctrl-capri.c +++ /dev/null @@ -1,1454 +0,0 @@ -/* - * Copyright (C) 2013 Broadcom 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. - * - * 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 -#include -#include -#include -#include -#include -#include -#include "core.h" -#include "pinctrl-utils.h" - -/* Capri Pin Control Registers Definitions */ - -/* Function Select bits are the same for all pin control registers */ -#define CAPRI_PIN_REG_F_SEL_MASK 0x0700 -#define CAPRI_PIN_REG_F_SEL_SHIFT 8 - -/* Standard pin register */ -#define CAPRI_STD_PIN_REG_DRV_STR_MASK 0x0007 -#define CAPRI_STD_PIN_REG_DRV_STR_SHIFT 0 -#define CAPRI_STD_PIN_REG_INPUT_DIS_MASK 0x0008 -#define CAPRI_STD_PIN_REG_INPUT_DIS_SHIFT 3 -#define CAPRI_STD_PIN_REG_SLEW_MASK 0x0010 -#define CAPRI_STD_PIN_REG_SLEW_SHIFT 4 -#define CAPRI_STD_PIN_REG_PULL_UP_MASK 0x0020 -#define CAPRI_STD_PIN_REG_PULL_UP_SHIFT 5 -#define CAPRI_STD_PIN_REG_PULL_DN_MASK 0x0040 -#define CAPRI_STD_PIN_REG_PULL_DN_SHIFT 6 -#define CAPRI_STD_PIN_REG_HYST_MASK 0x0080 -#define CAPRI_STD_PIN_REG_HYST_SHIFT 7 - -/* I2C pin register */ -#define CAPRI_I2C_PIN_REG_INPUT_DIS_MASK 0x0004 -#define CAPRI_I2C_PIN_REG_INPUT_DIS_SHIFT 2 -#define CAPRI_I2C_PIN_REG_SLEW_MASK 0x0008 -#define CAPRI_I2C_PIN_REG_SLEW_SHIFT 3 -#define CAPRI_I2C_PIN_REG_PULL_UP_STR_MASK 0x0070 -#define CAPRI_I2C_PIN_REG_PULL_UP_STR_SHIFT 4 - -/* HDMI pin register */ -#define CAPRI_HDMI_PIN_REG_INPUT_DIS_MASK 0x0008 -#define CAPRI_HDMI_PIN_REG_INPUT_DIS_SHIFT 3 -#define CAPRI_HDMI_PIN_REG_MODE_MASK 0x0010 -#define CAPRI_HDMI_PIN_REG_MODE_SHIFT 4 - -/** - * capri_pin_type - types of pin register - */ -enum capri_pin_type { - CAPRI_PIN_TYPE_UNKNOWN = 0, - CAPRI_PIN_TYPE_STD, - CAPRI_PIN_TYPE_I2C, - CAPRI_PIN_TYPE_HDMI, -}; - -static enum capri_pin_type std_pin = CAPRI_PIN_TYPE_STD; -static enum capri_pin_type i2c_pin = CAPRI_PIN_TYPE_I2C; -static enum capri_pin_type hdmi_pin = CAPRI_PIN_TYPE_HDMI; - -/** - * capri_pin_function- define pin function - */ -struct capri_pin_function { - const char *name; - const char * const *groups; - const unsigned ngroups; -}; - -/** - * capri_pinctrl_data - Broadcom-specific pinctrl data - * @reg_base - base of pinctrl registers - */ -struct capri_pinctrl_data { - void __iomem *reg_base; - - /* List of all pins */ - const struct pinctrl_pin_desc *pins; - const unsigned npins; - - const struct capri_pin_function *functions; - const unsigned nfunctions; - - struct regmap *regmap; -}; - -/* - * Pin number definition. The order here must be the same as defined in the - * PADCTRLREG block in the RDB. - */ -#define CAPRI_PIN_ADCSYNC 0 -#define CAPRI_PIN_BAT_RM 1 -#define CAPRI_PIN_BSC1_SCL 2 -#define CAPRI_PIN_BSC1_SDA 3 -#define CAPRI_PIN_BSC2_SCL 4 -#define CAPRI_PIN_BSC2_SDA 5 -#define CAPRI_PIN_CLASSGPWR 6 -#define CAPRI_PIN_CLK_CX8 7 -#define CAPRI_PIN_CLKOUT_0 8 -#define CAPRI_PIN_CLKOUT_1 9 -#define CAPRI_PIN_CLKOUT_2 10 -#define CAPRI_PIN_CLKOUT_3 11 -#define CAPRI_PIN_CLKREQ_IN_0 12 -#define CAPRI_PIN_CLKREQ_IN_1 13 -#define CAPRI_PIN_CWS_SYS_REQ1 14 -#define CAPRI_PIN_CWS_SYS_REQ2 15 -#define CAPRI_PIN_CWS_SYS_REQ3 16 -#define CAPRI_PIN_DIGMIC1_CLK 17 -#define CAPRI_PIN_DIGMIC1_DQ 18 -#define CAPRI_PIN_DIGMIC2_CLK 19 -#define CAPRI_PIN_DIGMIC2_DQ 20 -#define CAPRI_PIN_GPEN13 21 -#define CAPRI_PIN_GPEN14 22 -#define CAPRI_PIN_GPEN15 23 -#define CAPRI_PIN_GPIO00 24 -#define CAPRI_PIN_GPIO01 25 -#define CAPRI_PIN_GPIO02 26 -#define CAPRI_PIN_GPIO03 27 -#define CAPRI_PIN_GPIO04 28 -#define CAPRI_PIN_GPIO05 29 -#define CAPRI_PIN_GPIO06 30 -#define CAPRI_PIN_GPIO07 31 -#define CAPRI_PIN_GPIO08 32 -#define CAPRI_PIN_GPIO09 33 -#define CAPRI_PIN_GPIO10 34 -#define CAPRI_PIN_GPIO11 35 -#define CAPRI_PIN_GPIO12 36 -#define CAPRI_PIN_GPIO13 37 -#define CAPRI_PIN_GPIO14 38 -#define CAPRI_PIN_GPS_PABLANK 39 -#define CAPRI_PIN_GPS_TMARK 40 -#define CAPRI_PIN_HDMI_SCL 41 -#define CAPRI_PIN_HDMI_SDA 42 -#define CAPRI_PIN_IC_DM 43 -#define CAPRI_PIN_IC_DP 44 -#define CAPRI_PIN_KP_COL_IP_0 45 -#define CAPRI_PIN_KP_COL_IP_1 46 -#define CAPRI_PIN_KP_COL_IP_2 47 -#define CAPRI_PIN_KP_COL_IP_3 48 -#define CAPRI_PIN_KP_ROW_OP_0 49 -#define CAPRI_PIN_KP_ROW_OP_1 50 -#define CAPRI_PIN_KP_ROW_OP_2 51 -#define CAPRI_PIN_KP_ROW_OP_3 52 -#define CAPRI_PIN_LCD_B_0 53 -#define CAPRI_PIN_LCD_B_1 54 -#define CAPRI_PIN_LCD_B_2 55 -#define CAPRI_PIN_LCD_B_3 56 -#define CAPRI_PIN_LCD_B_4 57 -#define CAPRI_PIN_LCD_B_5 58 -#define CAPRI_PIN_LCD_B_6 59 -#define CAPRI_PIN_LCD_B_7 60 -#define CAPRI_PIN_LCD_G_0 61 -#define CAPRI_PIN_LCD_G_1 62 -#define CAPRI_PIN_LCD_G_2 63 -#define CAPRI_PIN_LCD_G_3 64 -#define CAPRI_PIN_LCD_G_4 65 -#define CAPRI_PIN_LCD_G_5 66 -#define CAPRI_PIN_LCD_G_6 67 -#define CAPRI_PIN_LCD_G_7 68 -#define CAPRI_PIN_LCD_HSYNC 69 -#define CAPRI_PIN_LCD_OE 70 -#define CAPRI_PIN_LCD_PCLK 71 -#define CAPRI_PIN_LCD_R_0 72 -#define CAPRI_PIN_LCD_R_1 73 -#define CAPRI_PIN_LCD_R_2 74 -#define CAPRI_PIN_LCD_R_3 75 -#define CAPRI_PIN_LCD_R_4 76 -#define CAPRI_PIN_LCD_R_5 77 -#define CAPRI_PIN_LCD_R_6 78 -#define CAPRI_PIN_LCD_R_7 79 -#define CAPRI_PIN_LCD_VSYNC 80 -#define CAPRI_PIN_MDMGPIO0 81 -#define CAPRI_PIN_MDMGPIO1 82 -#define CAPRI_PIN_MDMGPIO2 83 -#define CAPRI_PIN_MDMGPIO3 84 -#define CAPRI_PIN_MDMGPIO4 85 -#define CAPRI_PIN_MDMGPIO5 86 -#define CAPRI_PIN_MDMGPIO6 87 -#define CAPRI_PIN_MDMGPIO7 88 -#define CAPRI_PIN_MDMGPIO8 89 -#define CAPRI_PIN_MPHI_DATA_0 90 -#define CAPRI_PIN_MPHI_DATA_1 91 -#define CAPRI_PIN_MPHI_DATA_2 92 -#define CAPRI_PIN_MPHI_DATA_3 93 -#define CAPRI_PIN_MPHI_DATA_4 94 -#define CAPRI_PIN_MPHI_DATA_5 95 -#define CAPRI_PIN_MPHI_DATA_6 96 -#define CAPRI_PIN_MPHI_DATA_7 97 -#define CAPRI_PIN_MPHI_DATA_8 98 -#define CAPRI_PIN_MPHI_DATA_9 99 -#define CAPRI_PIN_MPHI_DATA_10 100 -#define CAPRI_PIN_MPHI_DATA_11 101 -#define CAPRI_PIN_MPHI_DATA_12 102 -#define CAPRI_PIN_MPHI_DATA_13 103 -#define CAPRI_PIN_MPHI_DATA_14 104 -#define CAPRI_PIN_MPHI_DATA_15 105 -#define CAPRI_PIN_MPHI_HA0 106 -#define CAPRI_PIN_MPHI_HAT0 107 -#define CAPRI_PIN_MPHI_HAT1 108 -#define CAPRI_PIN_MPHI_HCE0_N 109 -#define CAPRI_PIN_MPHI_HCE1_N 110 -#define CAPRI_PIN_MPHI_HRD_N 111 -#define CAPRI_PIN_MPHI_HWR_N 112 -#define CAPRI_PIN_MPHI_RUN0 113 -#define CAPRI_PIN_MPHI_RUN1 114 -#define CAPRI_PIN_MTX_SCAN_CLK 115 -#define CAPRI_PIN_MTX_SCAN_DATA 116 -#define CAPRI_PIN_NAND_AD_0 117 -#define CAPRI_PIN_NAND_AD_1 118 -#define CAPRI_PIN_NAND_AD_2 119 -#define CAPRI_PIN_NAND_AD_3 120 -#define CAPRI_PIN_NAND_AD_4 121 -#define CAPRI_PIN_NAND_AD_5 122 -#define CAPRI_PIN_NAND_AD_6 123 -#define CAPRI_PIN_NAND_AD_7 124 -#define CAPRI_PIN_NAND_ALE 125 -#define CAPRI_PIN_NAND_CEN_0 126 -#define CAPRI_PIN_NAND_CEN_1 127 -#define CAPRI_PIN_NAND_CLE 128 -#define CAPRI_PIN_NAND_OEN 129 -#define CAPRI_PIN_NAND_RDY_0 130 -#define CAPRI_PIN_NAND_RDY_1 131 -#define CAPRI_PIN_NAND_WEN 132 -#define CAPRI_PIN_NAND_WP 133 -#define CAPRI_PIN_PC1 134 -#define CAPRI_PIN_PC2 135 -#define CAPRI_PIN_PMU_INT 136 -#define CAPRI_PIN_PMU_SCL 137 -#define CAPRI_PIN_PMU_SDA 138 -#define CAPRI_PIN_RFST2G_MTSLOTEN3G 139 -#define CAPRI_PIN_RGMII_0_RX_CTL 140 -#define CAPRI_PIN_RGMII_0_RXC 141 -#define CAPRI_PIN_RGMII_0_RXD_0 142 -#define CAPRI_PIN_RGMII_0_RXD_1 143 -#define CAPRI_PIN_RGMII_0_RXD_2 144 -#define CAPRI_PIN_RGMII_0_RXD_3 145 -#define CAPRI_PIN_RGMII_0_TX_CTL 146 -#define CAPRI_PIN_RGMII_0_TXC 147 -#define CAPRI_PIN_RGMII_0_TXD_0 148 -#define CAPRI_PIN_RGMII_0_TXD_1 149 -#define CAPRI_PIN_RGMII_0_TXD_2 150 -#define CAPRI_PIN_RGMII_0_TXD_3 151 -#define CAPRI_PIN_RGMII_1_RX_CTL 152 -#define CAPRI_PIN_RGMII_1_RXC 153 -#define CAPRI_PIN_RGMII_1_RXD_0 154 -#define CAPRI_PIN_RGMII_1_RXD_1 155 -#define CAPRI_PIN_RGMII_1_RXD_2 156 -#define CAPRI_PIN_RGMII_1_RXD_3 157 -#define CAPRI_PIN_RGMII_1_TX_CTL 158 -#define CAPRI_PIN_RGMII_1_TXC 159 -#define CAPRI_PIN_RGMII_1_TXD_0 160 -#define CAPRI_PIN_RGMII_1_TXD_1 161 -#define CAPRI_PIN_RGMII_1_TXD_2 162 -#define CAPRI_PIN_RGMII_1_TXD_3 163 -#define CAPRI_PIN_RGMII_GPIO_0 164 -#define CAPRI_PIN_RGMII_GPIO_1 165 -#define CAPRI_PIN_RGMII_GPIO_2 166 -#define CAPRI_PIN_RGMII_GPIO_3 167 -#define CAPRI_PIN_RTXDATA2G_TXDATA3G1 168 -#define CAPRI_PIN_RTXEN2G_TXDATA3G2 169 -#define CAPRI_PIN_RXDATA3G0 170 -#define CAPRI_PIN_RXDATA3G1 171 -#define CAPRI_PIN_RXDATA3G2 172 -#define CAPRI_PIN_SDIO1_CLK 173 -#define CAPRI_PIN_SDIO1_CMD 174 -#define CAPRI_PIN_SDIO1_DATA_0 175 -#define CAPRI_PIN_SDIO1_DATA_1 176 -#define CAPRI_PIN_SDIO1_DATA_2 177 -#define CAPRI_PIN_SDIO1_DATA_3 178 -#define CAPRI_PIN_SDIO4_CLK 179 -#define CAPRI_PIN_SDIO4_CMD 180 -#define CAPRI_PIN_SDIO4_DATA_0 181 -#define CAPRI_PIN_SDIO4_DATA_1 182 -#define CAPRI_PIN_SDIO4_DATA_2 183 -#define CAPRI_PIN_SDIO4_DATA_3 184 -#define CAPRI_PIN_SIM_CLK 185 -#define CAPRI_PIN_SIM_DATA 186 -#define CAPRI_PIN_SIM_DET 187 -#define CAPRI_PIN_SIM_RESETN 188 -#define CAPRI_PIN_SIM2_CLK 189 -#define CAPRI_PIN_SIM2_DATA 190 -#define CAPRI_PIN_SIM2_DET 191 -#define CAPRI_PIN_SIM2_RESETN 192 -#define CAPRI_PIN_SRI_C 193 -#define CAPRI_PIN_SRI_D 194 -#define CAPRI_PIN_SRI_E 195 -#define CAPRI_PIN_SSP_EXTCLK 196 -#define CAPRI_PIN_SSP0_CLK 197 -#define CAPRI_PIN_SSP0_FS 198 -#define CAPRI_PIN_SSP0_RXD 199 -#define CAPRI_PIN_SSP0_TXD 200 -#define CAPRI_PIN_SSP2_CLK 201 -#define CAPRI_PIN_SSP2_FS_0 202 -#define CAPRI_PIN_SSP2_FS_1 203 -#define CAPRI_PIN_SSP2_FS_2 204 -#define CAPRI_PIN_SSP2_FS_3 205 -#define CAPRI_PIN_SSP2_RXD_0 206 -#define CAPRI_PIN_SSP2_RXD_1 207 -#define CAPRI_PIN_SSP2_TXD_0 208 -#define CAPRI_PIN_SSP2_TXD_1 209 -#define CAPRI_PIN_SSP3_CLK 210 -#define CAPRI_PIN_SSP3_FS 211 -#define CAPRI_PIN_SSP3_RXD 212 -#define CAPRI_PIN_SSP3_TXD 213 -#define CAPRI_PIN_SSP4_CLK 214 -#define CAPRI_PIN_SSP4_FS 215 -#define CAPRI_PIN_SSP4_RXD 216 -#define CAPRI_PIN_SSP4_TXD 217 -#define CAPRI_PIN_SSP5_CLK 218 -#define CAPRI_PIN_SSP5_FS 219 -#define CAPRI_PIN_SSP5_RXD 220 -#define CAPRI_PIN_SSP5_TXD 221 -#define CAPRI_PIN_SSP6_CLK 222 -#define CAPRI_PIN_SSP6_FS 223 -#define CAPRI_PIN_SSP6_RXD 224 -#define CAPRI_PIN_SSP6_TXD 225 -#define CAPRI_PIN_STAT_1 226 -#define CAPRI_PIN_STAT_2 227 -#define CAPRI_PIN_SYSCLKEN 228 -#define CAPRI_PIN_TRACECLK 229 -#define CAPRI_PIN_TRACEDT00 230 -#define CAPRI_PIN_TRACEDT01 231 -#define CAPRI_PIN_TRACEDT02 232 -#define CAPRI_PIN_TRACEDT03 233 -#define CAPRI_PIN_TRACEDT04 234 -#define CAPRI_PIN_TRACEDT05 235 -#define CAPRI_PIN_TRACEDT06 236 -#define CAPRI_PIN_TRACEDT07 237 -#define CAPRI_PIN_TRACEDT08 238 -#define CAPRI_PIN_TRACEDT09 239 -#define CAPRI_PIN_TRACEDT10 240 -#define CAPRI_PIN_TRACEDT11 241 -#define CAPRI_PIN_TRACEDT12 242 -#define CAPRI_PIN_TRACEDT13 243 -#define CAPRI_PIN_TRACEDT14 244 -#define CAPRI_PIN_TRACEDT15 245 -#define CAPRI_PIN_TXDATA3G0 246 -#define CAPRI_PIN_TXPWRIND 247 -#define CAPRI_PIN_UARTB1_UCTS 248 -#define CAPRI_PIN_UARTB1_URTS 249 -#define CAPRI_PIN_UARTB1_URXD 250 -#define CAPRI_PIN_UARTB1_UTXD 251 -#define CAPRI_PIN_UARTB2_URXD 252 -#define CAPRI_PIN_UARTB2_UTXD 253 -#define CAPRI_PIN_UARTB3_UCTS 254 -#define CAPRI_PIN_UARTB3_URTS 255 -#define CAPRI_PIN_UARTB3_URXD 256 -#define CAPRI_PIN_UARTB3_UTXD 257 -#define CAPRI_PIN_UARTB4_UCTS 258 -#define CAPRI_PIN_UARTB4_URTS 259 -#define CAPRI_PIN_UARTB4_URXD 260 -#define CAPRI_PIN_UARTB4_UTXD 261 -#define CAPRI_PIN_VC_CAM1_SCL 262 -#define CAPRI_PIN_VC_CAM1_SDA 263 -#define CAPRI_PIN_VC_CAM2_SCL 264 -#define CAPRI_PIN_VC_CAM2_SDA 265 -#define CAPRI_PIN_VC_CAM3_SCL 266 -#define CAPRI_PIN_VC_CAM3_SDA 267 - -#define CAPRI_PIN_DESC(a, b, c) \ - { .number = a, .name = b, .drv_data = &c##_pin } - -/* - * Pin description definition. The order here must be the same as defined in - * the PADCTRLREG block in the RDB, since the pin number is used as an index - * into this array. - */ -static const struct pinctrl_pin_desc capri_pinctrl_pins[] = { - CAPRI_PIN_DESC(CAPRI_PIN_ADCSYNC, "adcsync", std), - CAPRI_PIN_DESC(CAPRI_PIN_BAT_RM, "bat_rm", std), - CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SCL, "bsc1_scl", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SDA, "bsc1_sda", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SCL, "bsc2_scl", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SDA, "bsc2_sda", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_CLASSGPWR, "classgpwr", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLK_CX8, "clk_cx8", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_0, "clkout_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_1, "clkout_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_2, "clkout_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_3, "clkout_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_0, "clkreq_in_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_1, "clkreq_in_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ1, "cws_sys_req1", std), - CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ2, "cws_sys_req2", std), - CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ3, "cws_sys_req3", std), - CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_CLK, "digmic1_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_DQ, "digmic1_dq", std), - CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_CLK, "digmic2_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_DQ, "digmic2_dq", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPEN13, "gpen13", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPEN14, "gpen14", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPEN15, "gpen15", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO00, "gpio00", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO01, "gpio01", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO02, "gpio02", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO03, "gpio03", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO04, "gpio04", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO05, "gpio05", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO06, "gpio06", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO07, "gpio07", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO08, "gpio08", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO09, "gpio09", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO10, "gpio10", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO11, "gpio11", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO12, "gpio12", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO13, "gpio13", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPIO14, "gpio14", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPS_PABLANK, "gps_pablank", std), - CAPRI_PIN_DESC(CAPRI_PIN_GPS_TMARK, "gps_tmark", std), - CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SCL, "hdmi_scl", hdmi), - CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SDA, "hdmi_sda", hdmi), - CAPRI_PIN_DESC(CAPRI_PIN_IC_DM, "ic_dm", std), - CAPRI_PIN_DESC(CAPRI_PIN_IC_DP, "ic_dp", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_0, "kp_col_ip_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_1, "kp_col_ip_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_2, "kp_col_ip_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_3, "kp_col_ip_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_0, "kp_row_op_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_1, "kp_row_op_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_2, "kp_row_op_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_3, "kp_row_op_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_0, "lcd_b_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_1, "lcd_b_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_2, "lcd_b_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_3, "lcd_b_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_4, "lcd_b_4", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_5, "lcd_b_5", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_6, "lcd_b_6", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_7, "lcd_b_7", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_0, "lcd_g_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_1, "lcd_g_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_2, "lcd_g_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_3, "lcd_g_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_4, "lcd_g_4", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_5, "lcd_g_5", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_6, "lcd_g_6", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_7, "lcd_g_7", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_HSYNC, "lcd_hsync", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_OE, "lcd_oe", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_PCLK, "lcd_pclk", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_0, "lcd_r_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_1, "lcd_r_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_2, "lcd_r_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_3, "lcd_r_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_4, "lcd_r_4", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_5, "lcd_r_5", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_6, "lcd_r_6", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_7, "lcd_r_7", std), - CAPRI_PIN_DESC(CAPRI_PIN_LCD_VSYNC, "lcd_vsync", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO0, "mdmgpio0", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO1, "mdmgpio1", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO2, "mdmgpio2", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO3, "mdmgpio3", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO4, "mdmgpio4", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO5, "mdmgpio5", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO6, "mdmgpio6", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO7, "mdmgpio7", std), - CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO8, "mdmgpio8", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_0, "mphi_data_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_1, "mphi_data_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_2, "mphi_data_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_3, "mphi_data_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_4, "mphi_data_4", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_5, "mphi_data_5", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_6, "mphi_data_6", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_7, "mphi_data_7", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_8, "mphi_data_8", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_9, "mphi_data_9", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_10, "mphi_data_10", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_11, "mphi_data_11", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_12, "mphi_data_12", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_13, "mphi_data_13", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_14, "mphi_data_14", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_15, "mphi_data_15", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HA0, "mphi_ha0", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT0, "mphi_hat0", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT1, "mphi_hat1", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE0_N, "mphi_hce0_n", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE1_N, "mphi_hce1_n", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HRD_N, "mphi_hrd_n", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HWR_N, "mphi_hwr_n", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN0, "mphi_run0", std), - CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN1, "mphi_run1", std), - CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_DATA, "mtx_scan_data", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_0, "nand_ad_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_1, "nand_ad_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_2, "nand_ad_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_3, "nand_ad_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_4, "nand_ad_4", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_5, "nand_ad_5", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_6, "nand_ad_6", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_7, "nand_ad_7", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_ALE, "nand_ale", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_0, "nand_cen_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_1, "nand_cen_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_CLE, "nand_cle", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_OEN, "nand_oen", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_0, "nand_rdy_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_1, "nand_rdy_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_WEN, "nand_wen", std), - CAPRI_PIN_DESC(CAPRI_PIN_NAND_WP, "nand_wp", std), - CAPRI_PIN_DESC(CAPRI_PIN_PC1, "pc1", std), - CAPRI_PIN_DESC(CAPRI_PIN_PC2, "pc2", std), - CAPRI_PIN_DESC(CAPRI_PIN_PMU_INT, "pmu_int", std), - CAPRI_PIN_DESC(CAPRI_PIN_PMU_SCL, "pmu_scl", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_PMU_SDA, "pmu_sda", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXC, "rgmii_0_rxc", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXC, "rgmii_0_txc", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXC, "rgmii_1_rxc", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXC, "rgmii_1_txc", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_RTXDATA2G_TXDATA3G1, "rtxdata2g_txdata3g1", - std), - CAPRI_PIN_DESC(CAPRI_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2", std), - CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G0, "rxdata3g0", std), - CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G1, "rxdata3g1", std), - CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G2, "rxdata3g2", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CLK, "sdio1_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CMD, "sdio1_cmd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_0, "sdio1_data_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_1, "sdio1_data_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_2, "sdio1_data_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_3, "sdio1_data_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CLK, "sdio4_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CMD, "sdio4_cmd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_0, "sdio4_data_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_1, "sdio4_data_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_2, "sdio4_data_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_3, "sdio4_data_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM_CLK, "sim_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM_DATA, "sim_data", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM_DET, "sim_det", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM_RESETN, "sim_resetn", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM2_CLK, "sim2_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DATA, "sim2_data", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DET, "sim2_det", std), - CAPRI_PIN_DESC(CAPRI_PIN_SIM2_RESETN, "sim2_resetn", std), - CAPRI_PIN_DESC(CAPRI_PIN_SRI_C, "sri_c", std), - CAPRI_PIN_DESC(CAPRI_PIN_SRI_D, "sri_d", std), - CAPRI_PIN_DESC(CAPRI_PIN_SRI_E, "sri_e", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP_EXTCLK, "ssp_extclk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP0_CLK, "ssp0_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP0_FS, "ssp0_fs", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP0_RXD, "ssp0_rxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP0_TXD, "ssp0_txd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_CLK, "ssp2_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_0, "ssp2_fs_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_1, "ssp2_fs_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_2, "ssp2_fs_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_3, "ssp2_fs_3", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_0, "ssp2_rxd_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_1, "ssp2_rxd_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_0, "ssp2_txd_0", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_1, "ssp2_txd_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP3_CLK, "ssp3_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP3_FS, "ssp3_fs", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP3_RXD, "ssp3_rxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP3_TXD, "ssp3_txd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP4_CLK, "ssp4_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP4_FS, "ssp4_fs", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP4_RXD, "ssp4_rxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP4_TXD, "ssp4_txd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP5_CLK, "ssp5_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP5_FS, "ssp5_fs", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP5_RXD, "ssp5_rxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP5_TXD, "ssp5_txd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP6_CLK, "ssp6_clk", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP6_FS, "ssp6_fs", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP6_RXD, "ssp6_rxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_SSP6_TXD, "ssp6_txd", std), - CAPRI_PIN_DESC(CAPRI_PIN_STAT_1, "stat_1", std), - CAPRI_PIN_DESC(CAPRI_PIN_STAT_2, "stat_2", std), - CAPRI_PIN_DESC(CAPRI_PIN_SYSCLKEN, "sysclken", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACECLK, "traceclk", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT00, "tracedt00", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT01, "tracedt01", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT02, "tracedt02", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT03, "tracedt03", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT04, "tracedt04", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT05, "tracedt05", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT06, "tracedt06", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT07, "tracedt07", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT08, "tracedt08", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT09, "tracedt09", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT10, "tracedt10", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT11, "tracedt11", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT12, "tracedt12", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT13, "tracedt13", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT14, "tracedt14", std), - CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT15, "tracedt15", std), - CAPRI_PIN_DESC(CAPRI_PIN_TXDATA3G0, "txdata3g0", std), - CAPRI_PIN_DESC(CAPRI_PIN_TXPWRIND, "txpwrind", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UCTS, "uartb1_ucts", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URTS, "uartb1_urts", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URXD, "uartb1_urxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UTXD, "uartb1_utxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_URXD, "uartb2_urxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_UTXD, "uartb2_utxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UCTS, "uartb3_ucts", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URTS, "uartb3_urts", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URXD, "uartb3_urxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UTXD, "uartb3_utxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UCTS, "uartb4_ucts", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URTS, "uartb4_urts", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URXD, "uartb4_urxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UTXD, "uartb4_utxd", std), - CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c), - CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c), -}; - -static const char * const capri_alt_groups[] = { - "adcsync", - "bat_rm", - "bsc1_scl", - "bsc1_sda", - "bsc2_scl", - "bsc2_sda", - "classgpwr", - "clk_cx8", - "clkout_0", - "clkout_1", - "clkout_2", - "clkout_3", - "clkreq_in_0", - "clkreq_in_1", - "cws_sys_req1", - "cws_sys_req2", - "cws_sys_req3", - "digmic1_clk", - "digmic1_dq", - "digmic2_clk", - "digmic2_dq", - "gpen13", - "gpen14", - "gpen15", - "gpio00", - "gpio01", - "gpio02", - "gpio03", - "gpio04", - "gpio05", - "gpio06", - "gpio07", - "gpio08", - "gpio09", - "gpio10", - "gpio11", - "gpio12", - "gpio13", - "gpio14", - "gps_pablank", - "gps_tmark", - "hdmi_scl", - "hdmi_sda", - "ic_dm", - "ic_dp", - "kp_col_ip_0", - "kp_col_ip_1", - "kp_col_ip_2", - "kp_col_ip_3", - "kp_row_op_0", - "kp_row_op_1", - "kp_row_op_2", - "kp_row_op_3", - "lcd_b_0", - "lcd_b_1", - "lcd_b_2", - "lcd_b_3", - "lcd_b_4", - "lcd_b_5", - "lcd_b_6", - "lcd_b_7", - "lcd_g_0", - "lcd_g_1", - "lcd_g_2", - "lcd_g_3", - "lcd_g_4", - "lcd_g_5", - "lcd_g_6", - "lcd_g_7", - "lcd_hsync", - "lcd_oe", - "lcd_pclk", - "lcd_r_0", - "lcd_r_1", - "lcd_r_2", - "lcd_r_3", - "lcd_r_4", - "lcd_r_5", - "lcd_r_6", - "lcd_r_7", - "lcd_vsync", - "mdmgpio0", - "mdmgpio1", - "mdmgpio2", - "mdmgpio3", - "mdmgpio4", - "mdmgpio5", - "mdmgpio6", - "mdmgpio7", - "mdmgpio8", - "mphi_data_0", - "mphi_data_1", - "mphi_data_2", - "mphi_data_3", - "mphi_data_4", - "mphi_data_5", - "mphi_data_6", - "mphi_data_7", - "mphi_data_8", - "mphi_data_9", - "mphi_data_10", - "mphi_data_11", - "mphi_data_12", - "mphi_data_13", - "mphi_data_14", - "mphi_data_15", - "mphi_ha0", - "mphi_hat0", - "mphi_hat1", - "mphi_hce0_n", - "mphi_hce1_n", - "mphi_hrd_n", - "mphi_hwr_n", - "mphi_run0", - "mphi_run1", - "mtx_scan_clk", - "mtx_scan_data", - "nand_ad_0", - "nand_ad_1", - "nand_ad_2", - "nand_ad_3", - "nand_ad_4", - "nand_ad_5", - "nand_ad_6", - "nand_ad_7", - "nand_ale", - "nand_cen_0", - "nand_cen_1", - "nand_cle", - "nand_oen", - "nand_rdy_0", - "nand_rdy_1", - "nand_wen", - "nand_wp", - "pc1", - "pc2", - "pmu_int", - "pmu_scl", - "pmu_sda", - "rfst2g_mtsloten3g", - "rgmii_0_rx_ctl", - "rgmii_0_rxc", - "rgmii_0_rxd_0", - "rgmii_0_rxd_1", - "rgmii_0_rxd_2", - "rgmii_0_rxd_3", - "rgmii_0_tx_ctl", - "rgmii_0_txc", - "rgmii_0_txd_0", - "rgmii_0_txd_1", - "rgmii_0_txd_2", - "rgmii_0_txd_3", - "rgmii_1_rx_ctl", - "rgmii_1_rxc", - "rgmii_1_rxd_0", - "rgmii_1_rxd_1", - "rgmii_1_rxd_2", - "rgmii_1_rxd_3", - "rgmii_1_tx_ctl", - "rgmii_1_txc", - "rgmii_1_txd_0", - "rgmii_1_txd_1", - "rgmii_1_txd_2", - "rgmii_1_txd_3", - "rgmii_gpio_0", - "rgmii_gpio_1", - "rgmii_gpio_2", - "rgmii_gpio_3", - "rtxdata2g_txdata3g1", - "rtxen2g_txdata3g2", - "rxdata3g0", - "rxdata3g1", - "rxdata3g2", - "sdio1_clk", - "sdio1_cmd", - "sdio1_data_0", - "sdio1_data_1", - "sdio1_data_2", - "sdio1_data_3", - "sdio4_clk", - "sdio4_cmd", - "sdio4_data_0", - "sdio4_data_1", - "sdio4_data_2", - "sdio4_data_3", - "sim_clk", - "sim_data", - "sim_det", - "sim_resetn", - "sim2_clk", - "sim2_data", - "sim2_det", - "sim2_resetn", - "sri_c", - "sri_d", - "sri_e", - "ssp_extclk", - "ssp0_clk", - "ssp0_fs", - "ssp0_rxd", - "ssp0_txd", - "ssp2_clk", - "ssp2_fs_0", - "ssp2_fs_1", - "ssp2_fs_2", - "ssp2_fs_3", - "ssp2_rxd_0", - "ssp2_rxd_1", - "ssp2_txd_0", - "ssp2_txd_1", - "ssp3_clk", - "ssp3_fs", - "ssp3_rxd", - "ssp3_txd", - "ssp4_clk", - "ssp4_fs", - "ssp4_rxd", - "ssp4_txd", - "ssp5_clk", - "ssp5_fs", - "ssp5_rxd", - "ssp5_txd", - "ssp6_clk", - "ssp6_fs", - "ssp6_rxd", - "ssp6_txd", - "stat_1", - "stat_2", - "sysclken", - "traceclk", - "tracedt00", - "tracedt01", - "tracedt02", - "tracedt03", - "tracedt04", - "tracedt05", - "tracedt06", - "tracedt07", - "tracedt08", - "tracedt09", - "tracedt10", - "tracedt11", - "tracedt12", - "tracedt13", - "tracedt14", - "tracedt15", - "txdata3g0", - "txpwrind", - "uartb1_ucts", - "uartb1_urts", - "uartb1_urxd", - "uartb1_utxd", - "uartb2_urxd", - "uartb2_utxd", - "uartb3_ucts", - "uartb3_urts", - "uartb3_urxd", - "uartb3_utxd", - "uartb4_ucts", - "uartb4_urts", - "uartb4_urxd", - "uartb4_utxd", - "vc_cam1_scl", - "vc_cam1_sda", - "vc_cam2_scl", - "vc_cam2_sda", - "vc_cam3_scl", - "vc_cam3_sda", -}; - -/* Every pin can implement all ALT1-ALT4 functions */ -#define CAPRI_PIN_FUNCTION(fcn_name) \ -{ \ - .name = #fcn_name, \ - .groups = capri_alt_groups, \ - .ngroups = ARRAY_SIZE(capri_alt_groups), \ -} - -static const struct capri_pin_function capri_functions[] = { - CAPRI_PIN_FUNCTION(alt1), - CAPRI_PIN_FUNCTION(alt2), - CAPRI_PIN_FUNCTION(alt3), - CAPRI_PIN_FUNCTION(alt4), -}; - -static struct capri_pinctrl_data capri_pinctrl = { - .pins = capri_pinctrl_pins, - .npins = ARRAY_SIZE(capri_pinctrl_pins), - .functions = capri_functions, - .nfunctions = ARRAY_SIZE(capri_functions), -}; - -static inline enum capri_pin_type pin_type_get(struct pinctrl_dev *pctldev, - unsigned pin) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - if (pin >= pdata->npins) - return CAPRI_PIN_TYPE_UNKNOWN; - - return *(enum capri_pin_type *)(pdata->pins[pin].drv_data); -} - -#define CAPRI_PIN_SHIFT(type, param) \ - (CAPRI_ ## type ## _PIN_REG_ ## param ## _SHIFT) - -#define CAPRI_PIN_MASK(type, param) \ - (CAPRI_ ## type ## _PIN_REG_ ## param ## _MASK) - -/* - * This helper function is used to build up the value and mask used to write to - * a pin register, but does not actually write to the register. - */ -static inline void capri_pin_update(u32 *reg_val, u32 *reg_mask, u32 param_val, - u32 param_shift, u32 param_mask) -{ - *reg_val &= ~param_mask; - *reg_val |= (param_val << param_shift) & param_mask; - *reg_mask |= param_mask; -} - -static struct regmap_config capri_pinctrl_regmap_config = { - .reg_bits = 32, - .reg_stride = 4, - .val_bits = 32, - .max_register = CAPRI_PIN_VC_CAM3_SDA, -}; - -static int capri_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - return pdata->npins; -} - -static const char *capri_pinctrl_get_group_name(struct pinctrl_dev *pctldev, - unsigned group) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - return pdata->pins[group].name; -} - -static int capri_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, - unsigned group, - const unsigned **pins, - unsigned *num_pins) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - *pins = &pdata->pins[group].number; - *num_pins = 1; - - return 0; -} - -static void capri_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, - struct seq_file *s, - unsigned offset) -{ - seq_printf(s, " %s", dev_name(pctldev->dev)); -} - -static struct pinctrl_ops capri_pinctrl_ops = { - .get_groups_count = capri_pinctrl_get_groups_count, - .get_group_name = capri_pinctrl_get_group_name, - .get_group_pins = capri_pinctrl_get_group_pins, - .pin_dbg_show = capri_pinctrl_pin_dbg_show, - .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, - .dt_free_map = pinctrl_utils_dt_free_map, -}; - -static int capri_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - return pdata->nfunctions; -} - -static const char *capri_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev, - unsigned function) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - return pdata->functions[function].name; -} - -static int capri_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev, - unsigned function, - const char * const **groups, - unsigned * const num_groups) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - - *groups = pdata->functions[function].groups; - *num_groups = pdata->functions[function].ngroups; - - return 0; -} - -static int capri_pinmux_enable(struct pinctrl_dev *pctldev, - unsigned function, - unsigned group) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - const struct capri_pin_function *f = &pdata->functions[function]; - u32 offset = 4 * pdata->pins[group].number; - int rc = 0; - - dev_dbg(pctldev->dev, - "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n", - __func__, f->name, function, pdata->pins[group].name, - pdata->pins[group].number, offset); - - rc = regmap_update_bits(pdata->regmap, offset, CAPRI_PIN_REG_F_SEL_MASK, - function << CAPRI_PIN_REG_F_SEL_SHIFT); - if (rc) - dev_err(pctldev->dev, - "Error updating register for pin %s (%d).\n", - pdata->pins[group].name, pdata->pins[group].number); - - return rc; -} - -static struct pinmux_ops capri_pinctrl_pinmux_ops = { - .get_functions_count = capri_pinctrl_get_fcns_count, - .get_function_name = capri_pinctrl_get_fcn_name, - .get_function_groups = capri_pinctrl_get_fcn_groups, - .enable = capri_pinmux_enable, -}; - -static int capri_pinctrl_pin_config_get(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *config) -{ - return -ENOTSUPP; -} - - -/* Goes through the configs and update register val/mask */ -static int capri_std_pin_update(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *configs, - unsigned num_configs, - u32 *val, - u32 *mask) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - int i; - enum pin_config_param param; - u16 arg; - - for (i = 0; i < num_configs; i++) { - param = pinconf_to_config_param(configs[i]); - arg = pinconf_to_config_argument(configs[i]); - - switch (param) { - case PIN_CONFIG_INPUT_SCHMITT_ENABLE: - arg = (arg >= 1 ? 1 : 0); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(STD, HYST), - CAPRI_PIN_MASK(STD, HYST)); - break; - /* - * The pin bias can only be one of pull-up, pull-down, or - * disable. The user does not need to specify a value for the - * property, and the default value from pinconf-generic is - * ignored. - */ - case PIN_CONFIG_BIAS_DISABLE: - capri_pin_update(val, mask, 0, - CAPRI_PIN_SHIFT(STD, PULL_UP), - CAPRI_PIN_MASK(STD, PULL_UP)); - capri_pin_update(val, mask, 0, - CAPRI_PIN_SHIFT(STD, PULL_DN), - CAPRI_PIN_MASK(STD, PULL_DN)); - break; - - case PIN_CONFIG_BIAS_PULL_UP: - capri_pin_update(val, mask, 1, - CAPRI_PIN_SHIFT(STD, PULL_UP), - CAPRI_PIN_MASK(STD, PULL_UP)); - capri_pin_update(val, mask, 0, - CAPRI_PIN_SHIFT(STD, PULL_DN), - CAPRI_PIN_MASK(STD, PULL_DN)); - break; - - case PIN_CONFIG_BIAS_PULL_DOWN: - capri_pin_update(val, mask, 0, - CAPRI_PIN_SHIFT(STD, PULL_UP), - CAPRI_PIN_MASK(STD, PULL_UP)); - capri_pin_update(val, mask, 1, - CAPRI_PIN_SHIFT(STD, PULL_DN), - CAPRI_PIN_MASK(STD, PULL_DN)); - break; - - case PIN_CONFIG_SLEW_RATE: - arg = (arg >= 1 ? 1 : 0); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(STD, SLEW), - CAPRI_PIN_MASK(STD, SLEW)); - break; - - case PIN_CONFIG_INPUT_ENABLE: - /* inversed since register is for input _disable_ */ - arg = (arg >= 1 ? 0 : 1); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(STD, INPUT_DIS), - CAPRI_PIN_MASK(STD, INPUT_DIS)); - break; - - case PIN_CONFIG_DRIVE_STRENGTH: - /* Valid range is 2-16 mA, even numbers only */ - if ((arg < 2) || (arg > 16) || (arg % 2)) { - dev_err(pctldev->dev, - "Invalid Drive Strength value (%d) for " - "pin %s (%d). Valid values are " - "(2..16) mA, even numbers only.\n", - arg, pdata->pins[pin].name, pin); - return -EINVAL; - } - capri_pin_update(val, mask, (arg/2)-1, - CAPRI_PIN_SHIFT(STD, DRV_STR), - CAPRI_PIN_MASK(STD, DRV_STR)); - break; - - default: - dev_err(pctldev->dev, - "Unrecognized pin config %d for pin %s (%d).\n", - param, pdata->pins[pin].name, pin); - return -EINVAL; - - } /* switch config */ - } /* for each config */ - - return 0; -} - -/* - * The pull-up strength for an I2C pin is represented by bits 4-6 in the - * register with the following mapping: - * 0b000: No pull-up - * 0b001: 1200 Ohm - * 0b010: 1800 Ohm - * 0b011: 720 Ohm - * 0b100: 2700 Ohm - * 0b101: 831 Ohm - * 0b110: 1080 Ohm - * 0b111: 568 Ohm - * This array maps pull-up strength in Ohms to register values (1+index). - */ -static const u16 capri_pullup_map[] = {1200, 1800, 720, 2700, 831, 1080, 568}; - -/* Goes through the configs and update register val/mask */ -static int capri_i2c_pin_update(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *configs, - unsigned num_configs, - u32 *val, - u32 *mask) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - int i, j; - enum pin_config_param param; - u16 arg; - - for (i = 0; i < num_configs; i++) { - param = pinconf_to_config_param(configs[i]); - arg = pinconf_to_config_argument(configs[i]); - - switch (param) { - case PIN_CONFIG_BIAS_PULL_UP: - for (j = 0; j < ARRAY_SIZE(capri_pullup_map); j++) - if (capri_pullup_map[j] == arg) - break; - - if (j == ARRAY_SIZE(capri_pullup_map)) { - dev_err(pctldev->dev, - "Invalid pull-up value (%d) for pin %s " - "(%d). Valid values are 568, 720, 831, " - "1080, 1200, 1800, 2700 Ohms.\n", - arg, pdata->pins[pin].name, pin); - return -EINVAL; - } - - capri_pin_update(val, mask, j+1, - CAPRI_PIN_SHIFT(I2C, PULL_UP_STR), - CAPRI_PIN_MASK(I2C, PULL_UP_STR)); - break; - - case PIN_CONFIG_BIAS_DISABLE: - capri_pin_update(val, mask, 0, - CAPRI_PIN_SHIFT(I2C, PULL_UP_STR), - CAPRI_PIN_MASK(I2C, PULL_UP_STR)); - break; - - case PIN_CONFIG_SLEW_RATE: - arg = (arg >= 1 ? 1 : 0); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(I2C, SLEW), - CAPRI_PIN_MASK(I2C, SLEW)); - break; - - case PIN_CONFIG_INPUT_ENABLE: - /* inversed since register is for input _disable_ */ - arg = (arg >= 1 ? 0 : 1); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(I2C, INPUT_DIS), - CAPRI_PIN_MASK(I2C, INPUT_DIS)); - break; - - default: - dev_err(pctldev->dev, - "Unrecognized pin config %d for pin %s (%d).\n", - param, pdata->pins[pin].name, pin); - return -EINVAL; - - } /* switch config */ - } /* for each config */ - - return 0; -} - -/* Goes through the configs and update register val/mask */ -static int capri_hdmi_pin_update(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *configs, - unsigned num_configs, - u32 *val, - u32 *mask) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - int i; - enum pin_config_param param; - u16 arg; - - for (i = 0; i < num_configs; i++) { - param = pinconf_to_config_param(configs[i]); - arg = pinconf_to_config_argument(configs[i]); - - switch (param) { - case PIN_CONFIG_SLEW_RATE: - arg = (arg >= 1 ? 1 : 0); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(HDMI, MODE), - CAPRI_PIN_MASK(HDMI, MODE)); - break; - - case PIN_CONFIG_INPUT_ENABLE: - /* inversed since register is for input _disable_ */ - arg = (arg >= 1 ? 0 : 1); - capri_pin_update(val, mask, arg, - CAPRI_PIN_SHIFT(HDMI, INPUT_DIS), - CAPRI_PIN_MASK(HDMI, INPUT_DIS)); - break; - - default: - dev_err(pctldev->dev, - "Unrecognized pin config %d for pin %s (%d).\n", - param, pdata->pins[pin].name, pin); - return -EINVAL; - - } /* switch config */ - } /* for each config */ - - return 0; -} - -static int capri_pinctrl_pin_config_set(struct pinctrl_dev *pctldev, - unsigned pin, - unsigned long *configs, - unsigned num_configs) -{ - struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); - enum capri_pin_type pin_type; - u32 offset = 4 * pin; - u32 cfg_val, cfg_mask; - int rc; - - cfg_val = 0; - cfg_mask = 0; - pin_type = pin_type_get(pctldev, pin); - - /* Different pins have different configuration options */ - switch (pin_type) { - case CAPRI_PIN_TYPE_STD: - rc = capri_std_pin_update(pctldev, pin, configs, num_configs, - &cfg_val, &cfg_mask); - break; - - case CAPRI_PIN_TYPE_I2C: - rc = capri_i2c_pin_update(pctldev, pin, configs, num_configs, - &cfg_val, &cfg_mask); - break; - - case CAPRI_PIN_TYPE_HDMI: - rc = capri_hdmi_pin_update(pctldev, pin, configs, num_configs, - &cfg_val, &cfg_mask); - break; - - default: - dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n", - pdata->pins[pin].name, pin); - return -EINVAL; - - } /* switch pin type */ - - if (rc) - return rc; - - dev_dbg(pctldev->dev, - "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n", - __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask); - - rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val); - if (rc) { - dev_err(pctldev->dev, - "Error updating register for pin %s (%d).\n", - pdata->pins[pin].name, pin); - return rc; - } - - return 0; -} - -static struct pinconf_ops capri_pinctrl_pinconf_ops = { - .pin_config_get = capri_pinctrl_pin_config_get, - .pin_config_set = capri_pinctrl_pin_config_set, -}; - -static struct pinctrl_desc capri_pinctrl_desc = { - /* name, pins, npins members initialized in probe function */ - .pctlops = &capri_pinctrl_ops, - .pmxops = &capri_pinctrl_pinmux_ops, - .confops = &capri_pinctrl_pinconf_ops, - .owner = THIS_MODULE, -}; - -int __init capri_pinctrl_probe(struct platform_device *pdev) -{ - struct capri_pinctrl_data *pdata = &capri_pinctrl; - struct resource *res; - struct pinctrl_dev *pctl; - - /* So far We can assume there is only 1 bank of registers */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Missing MEM resource\n"); - return -ENODEV; - } - - pdata->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pdata->reg_base)) { - dev_err(&pdev->dev, "Failed to ioremap MEM resource\n"); - return -ENODEV; - } - - /* Initialize the dynamic part of pinctrl_desc */ - pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base, - &capri_pinctrl_regmap_config); - if (IS_ERR(pdata->regmap)) { - dev_err(&pdev->dev, "Regmap MMIO init failed.\n"); - return -ENODEV; - } - - capri_pinctrl_desc.name = dev_name(&pdev->dev); - capri_pinctrl_desc.pins = capri_pinctrl.pins; - capri_pinctrl_desc.npins = capri_pinctrl.npins; - - pctl = pinctrl_register(&capri_pinctrl_desc, - &pdev->dev, - pdata); - if (!pctl) { - dev_err(&pdev->dev, "Failed to register pinctrl\n"); - return -ENODEV; - } - - platform_set_drvdata(pdev, pdata); - - return 0; -} - -static struct of_device_id capri_pinctrl_of_match[] = { - { .compatible = "brcm,bcm11351-pinctrl", }, - { }, -}; - -static struct platform_driver capri_pinctrl_driver = { - .driver = { - .name = "bcm-capri-pinctrl", - .owner = THIS_MODULE, - .of_match_table = capri_pinctrl_of_match, - }, -}; - -module_platform_driver_probe(capri_pinctrl_driver, capri_pinctrl_probe); - -MODULE_AUTHOR("Sherman Yin "); -MODULE_DESCRIPTION("Broadcom Capri pinctrl driver"); -MODULE_LICENSE("GPL v2"); -- GitLab From 74805e01f8f12aa2d1ba866fa471ff89d5363636 Mon Sep 17 00:00:00 2001 From: Sherman Yin Date: Wed, 2 Apr 2014 15:40:38 -0700 Subject: [PATCH 157/797] Update bcm_defconfig with new pinctrl CONFIG To be consistent with other Broadcom drivers, the Broadcom Capri pinctrl driver and its related CONFIG option are renamed to bcm281xx. This commit updates the defconfig that enables the pinctrl driver. Signed-off-by: Sherman Yin Reviewed-by: Matt Porter Acked-by: Linus Walleij Signed-off-by: Linus Walleij --- arch/arm/configs/bcm_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig index 01004640ee4d..3df3f3a79ef4 100644 --- a/arch/arm/configs/bcm_defconfig +++ b/arch/arm/configs/bcm_defconfig @@ -132,7 +132,7 @@ CONFIG_CRC_ITU_T=y CONFIG_CRC7=y CONFIG_XZ_DEC=y CONFIG_AVERAGE=y -CONFIG_PINCTRL_CAPRI=y +CONFIG_PINCTRL_BCM281XX=y CONFIG_WATCHDOG=y CONFIG_BCM_KONA_WDT=y CONFIG_BCM_KONA_WDT_DEBUG=y -- GitLab From dc4bb474cd1ff39dcda996344114edb47cc8df04 Mon Sep 17 00:00:00 2001 From: Sherman Yin Date: Wed, 2 Apr 2014 15:40:39 -0700 Subject: [PATCH 158/797] pinctrl: fix typo in bindings documentation Fixed the missing comma in DT node example. Signed-off-by: Sherman Yin Signed-off-by: Linus Walleij --- .../devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt index c119debe6bab..67a5db95f189 100644 --- a/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt +++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt @@ -119,7 +119,7 @@ Optional Properties (for HDMI pins): Example: // pin controller node pinctrl@35004800 { - compatible = "brcmbcm11351-pinctrl"; + compatible = "brcm,bcm11351-pinctrl"; reg = <0x35004800 0x430>; // pin configuration node -- GitLab From 4ab9ed578e82851645f3dd69d36d91ae77564d6c Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 14 Apr 2014 18:11:58 +1000 Subject: [PATCH 159/797] xfs: kill buffers over failed write ranges properly When a write fails, if we don't clear the delalloc flags from the buffers over the failed range, they can persist beyond EOF and cause problems. writeback will see the pages in the page cache, see they are dirty and continually retry the write, assuming that the page beyond EOF is just racing with a truncate. The page will eventually be released due to some other operation (e.g. direct IO), and it will not pass through invalidation because it is dirty. Hence it will be released with buffer_delay set on it, and trigger warnings in xfs_vm_releasepage() and assert fail in xfs_file_aio_write_direct because invalidation failed and we didn't write the corect amount. This causes failures on block size < page size filesystems in fsx and fsstress workloads run by xfstests. Fix it by completely trashing any state on the buffer that could be used to imply that it contains valid data when the delalloc range over the buffer is punched out during the failed write handling. Signed-off-by: Dave Chinner Tested-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 75df77d09f75..282c726d04d0 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1566,6 +1566,16 @@ xfs_vm_write_failed( xfs_vm_kill_delalloc_range(inode, block_offset, block_offset + bh->b_size); + + /* + * This buffer does not contain data anymore. make sure anyone + * who finds it knows that for certain. + */ + clear_buffer_delay(bh); + clear_buffer_uptodate(bh); + clear_buffer_mapped(bh); + clear_buffer_new(bh); + clear_buffer_dirty(bh); } } -- GitLab From 72ab70a19b4ebb19dbe2a79faaa6a4ccead58e70 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 14 Apr 2014 18:13:29 +1000 Subject: [PATCH 160/797] xfs: write failure beyond EOF truncates too much data If we fail a write beyond EOF and have to handle it in xfs_vm_write_begin(), we truncate the inode back to the current inode size. This doesn't take into account the fact that we may have already made successful writes to the same page (in the case of block size < page size) and hence we can truncate the page cache away from blocks with valid data in them. If these blocks are delayed allocation blocks, we now have a mismatch between the page cache and the extent tree, and this will trigger - at minimum - a delayed block count mismatch assert when the inode is evicted from the cache. We can also trip over it when block mapping for direct IO - this is the most common symptom seen from fsx and fsstress when run from xfstests. Fix it by only truncating away the exact range we are updating state for in this write_begin call. Signed-off-by: Dave Chinner Tested-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 282c726d04d0..5f296934879f 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1609,12 +1609,21 @@ xfs_vm_write_begin( status = __block_write_begin(page, pos, len, xfs_get_blocks); if (unlikely(status)) { struct inode *inode = mapping->host; + size_t isize = i_size_read(inode); xfs_vm_write_failed(inode, page, pos, len); unlock_page(page); - if (pos + len > i_size_read(inode)) - truncate_pagecache(inode, i_size_read(inode)); + /* + * If the write is beyond EOF, we only want to kill blocks + * allocated in this write, not blocks that were previously + * written successfully. + */ + if (pos + len > isize) { + ssize_t start = max_t(ssize_t, pos, isize); + + truncate_pagecache_range(inode, start, pos + len); + } page_cache_release(page); page = NULL; -- GitLab From aad3f3755e7f043789b772856d1a2935f2b41a4b Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 14 Apr 2014 18:14:11 +1000 Subject: [PATCH 161/797] xfs: xfs_vm_write_end truncates too much on failure Similar to the write_begin problem, xfs-vm_write_end will truncate back to the old EOF, potentially removing page cache from over the top of delalloc blocks with valid data in them. Fix this by truncating back to just the start of the failed write. Signed-off-by: Dave Chinner Tested-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 5f296934879f..e0a793113ea9 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1634,9 +1634,12 @@ xfs_vm_write_begin( } /* - * On failure, we only need to kill delalloc blocks beyond EOF because they - * will never be written. For blocks within EOF, generic_write_end() zeros them - * so they are safe to leave alone and be written with all the other valid data. + * On failure, we only need to kill delalloc blocks beyond EOF in the range of + * this specific write because they will never be written. Previous writes + * beyond EOF where block allocation succeeded do not need to be trashed, so + * only new blocks from this write should be trashed. For blocks within + * EOF, generic_write_end() zeros them so they are safe to leave alone and be + * written with all the other valid data. */ STATIC int xfs_vm_write_end( @@ -1659,8 +1662,11 @@ xfs_vm_write_end( loff_t to = pos + len; if (to > isize) { - truncate_pagecache(inode, isize); + /* only kill blocks in this write beyond EOF */ + if (pos > isize) + isize = pos; xfs_vm_kill_delalloc_range(inode, isize, to); + truncate_pagecache_range(inode, isize, to); } } return ret; -- GitLab From 897b73b6a2ee5d3c06648b601beb1724f7fbd678 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 14 Apr 2014 18:15:11 +1000 Subject: [PATCH 162/797] xfs: zeroing space needs to punch delalloc blocks When we are zeroing space andit is covered by a delalloc range, we need to punch the delalloc range out before we truncate the page cache. Failing to do so leaves and inconsistency between the page cache and the extent tree, which we later trip over when doing direct IO over the same range. Signed-off-by: Dave Chinner Tested-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_bmap_util.c | 13 ++++++++++++- fs/xfs/xfs_trace.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 01f6a646caa1..296160b8e78c 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1418,6 +1418,8 @@ xfs_zero_file_space( xfs_off_t end_boundary; int error; + trace_xfs_zero_file_space(ip); + granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE); /* @@ -1432,9 +1434,18 @@ xfs_zero_file_space( ASSERT(end_boundary <= offset + len); if (start_boundary < end_boundary - 1) { - /* punch out the page cache over the conversion range */ + /* + * punch out delayed allocation blocks and the page cache over + * the conversion range + */ + xfs_ilock(ip, XFS_ILOCK_EXCL); + error = xfs_bmap_punch_delalloc_range(ip, + XFS_B_TO_FSBT(mp, start_boundary), + XFS_B_TO_FSB(mp, end_boundary - start_boundary)); + xfs_iunlock(ip, XFS_ILOCK_EXCL); truncate_pagecache_range(VFS_I(ip), start_boundary, end_boundary - 1); + /* convert the blocks */ error = xfs_alloc_file_space(ip, start_boundary, end_boundary - start_boundary - 1, diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index a4ae41c179a8..65d8c793a25c 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -603,6 +603,7 @@ DEFINE_INODE_EVENT(xfs_readlink); DEFINE_INODE_EVENT(xfs_inactive_symlink); DEFINE_INODE_EVENT(xfs_alloc_file_space); DEFINE_INODE_EVENT(xfs_free_file_space); +DEFINE_INODE_EVENT(xfs_zero_file_space); DEFINE_INODE_EVENT(xfs_collapse_file_space); DEFINE_INODE_EVENT(xfs_readdir); #ifdef CONFIG_XFS_POSIX_ACL -- GitLab From 7633fb959b711a8d91548911eb087fb931c7b8e4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 9 Apr 2014 13:20:38 +0200 Subject: [PATCH 163/797] gpio: set data first, then chip and handler During irq mapping, in irq_set_chip_and_handler() the process of setting this up may incur calls to lock the irqchip, which in turn may need to dereference and use the chip data. So set the data first, then set the chip and handler. Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 761013f8b82f..f48817d97480 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1387,8 +1387,8 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, { struct gpio_chip *chip = d->host_data; - irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); irq_set_chip_data(irq, chip); + irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); #ifdef CONFIG_ARM set_irq_flags(irq, IRQF_VALID); #else -- GitLab From e9595f84a6273dffc5b75564d9b12a77630c529e Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Mon, 31 Mar 2014 15:16:49 +0300 Subject: [PATCH 164/797] gpio / ACPI: Don't crash on NULL chip->dev Commit aa92b6f689ac (gpio / ACPI: Allocate ACPI specific data directly in acpi_gpiochip_add()) moved ACPI handle checking to acpi_gpiochip_add() but forgot to check whether chip->dev is NULL before dereferencing it. Since chip->dev pointer is optional we can end up with crash like following: BUG: unable to handle kernel NULL pointer dereference at 00000138 IP: [] acpi_gpiochip_add+0x13/0x190 *pde = 00000000 Oops: 0000 [#1] PREEMPT SMP Modules linked in: ssb(+) ... CPU: 0 PID: 512 Comm: modprobe Tainted: G W 3.14.0-rc7-next-20140324-t1 #24 Hardware name: Dell Inc. Latitude D830 /0UY141, BIOS A02 06/07/2007 task: f5799900 ti: f543e000 task.ti: f543e000 EIP: 0060:[] EFLAGS: 00010282 CPU: 0 EIP is at acpi_gpiochip_add+0x13/0x190 EAX: 00000000 EBX: f57824c4 ECX: 00000000 EDX: 00000000 ESI: f57824c4 EDI: 00000010 EBP: f543fc54 ESP: f543fc40 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 CR0: 8005003b CR2: 00000138 CR3: 355f8000 CR4: 000007d0 Stack: f543fc5c fd1f7790 f57824c4 000000be 00000010 f543fc84 c1269f4e f543fc74 fd1f78bd 00008002 f57822b0 f5782090 fd1f8400 00000286 fd1f9994 00000000 f5782000 f543fc8c fd1f7e39 f543fcc8 fd1f0bd8 000000c0 00000000 00000000 Call Trace: [] ? ssb_pcie_mdio_write+0xa0/0xd0 [ssb] [] gpiochip_add+0xee/0x300 [] ? ssb_pcicore_serdes_workaround+0xfd/0x140 [ssb] [] ssb_gpio_init+0x89/0xa0 [ssb] [] ssb_attach_queued_buses+0xc8/0x2d0 [ssb] [] ssb_bus_register+0x185/0x1f0 [ssb] [] ? ssb_pci_xtal+0x220/0x220 [ssb] [] ssb_bus_pcibus_register+0x2c/0x80 [ssb] [] ssb_pcihost_probe+0x9c/0x110 [ssb] [] pci_device_probe+0x6f/0xc0 [] ? sysfs_create_link+0x25/0x40 [] driver_probe_device+0x79/0x360 [] ? pci_match_device+0xb2/0xc0 [] __driver_attach+0x71/0x80 [] ? __device_attach+0x40/0x40 [] bus_for_each_dev+0x47/0x80 [] driver_attach+0x1e/0x20 [] ? __device_attach+0x40/0x40 [] bus_add_driver+0x157/0x230 [] driver_register+0x59/0xe0 ... Fix this by checking chip->dev pointer against NULL first. Also we can now remove redundant check in acpi_gpiochip_request/free_interrupts(). Reported-by: Sabrina Dubroca Signed-off-by: Mika Westerberg Tested-by: Sabrina Dubroca Acked-by: Alexandre Courbot Tested-by: Josh Boyer Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index bf0f8b476696..d5be56fe689e 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -233,7 +233,7 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio) { struct gpio_chip *chip = acpi_gpio->chip; - if (!chip->dev || !chip->to_irq) + if (!chip->to_irq) return; INIT_LIST_HEAD(&acpi_gpio->events); @@ -253,7 +253,7 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio) struct acpi_gpio_event *event, *ep; struct gpio_chip *chip = acpi_gpio->chip; - if (!chip->dev || !chip->to_irq) + if (!chip->to_irq) return; list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) { @@ -501,6 +501,9 @@ void acpi_gpiochip_add(struct gpio_chip *chip) acpi_handle handle; acpi_status status; + if (!chip || !chip->dev) + return; + handle = ACPI_HANDLE(chip->dev); if (!handle) return; @@ -531,6 +534,9 @@ void acpi_gpiochip_remove(struct gpio_chip *chip) acpi_handle handle; acpi_status status; + if (!chip || !chip->dev) + return; + handle = ACPI_HANDLE(chip->dev); if (!handle) return; -- GitLab From b5539fa2d59d697b7b8e28b4d08da844ff60f7cf Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Tue, 1 Apr 2014 13:03:00 +0300 Subject: [PATCH 165/797] gpio / ACPI: Prevent potential wrap of GPIO value on OpRegion read Dan Carpenter's static code checker reports: The patch 473ed7be0da0: "gpio / ACPI: Add support for ACPI GPIO operation regions" from Mar 14, 2014, leads to the following static checker warning: drivers/gpio/gpiolib-acpi.c:454 acpi_gpio_adr_space_handler() warn: should 'gpiod_get_raw_value(desc) << i' be a 64 bit type? This is due the fact that *value is of type u64 and gpiod_get_raw_value() returns int. Since i can be larger than 31, it is possible that the value returned gets wrapped. Fix this by casting the return of gpiod_get_raw_value() to u64 first before shift. Reported-by: Dan Carpenter Signed-off-by: Mika Westerberg Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index d5be56fe689e..401add28933f 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -451,7 +451,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, if (function == ACPI_WRITE) gpiod_set_raw_value(desc, !!((1 << i) & *value)); else - *value |= gpiod_get_raw_value(desc) << i; + *value |= (u64)gpiod_get_raw_value(desc) << i; } out: -- GitLab From ee214d54bf3d51259adf8917e26dc84df1cab05a Mon Sep 17 00:00:00 2001 From: Andrey Vagin Date: Fri, 11 Apr 2014 21:34:20 +0400 Subject: [PATCH 166/797] netfilter: nf_conntrack: initialize net.ct.generation [ 251.920788] INFO: trying to register non-static key. [ 251.921386] the code is fine but needs lockdep annotation. [ 251.921386] turning off the locking correctness validator. [ 251.921386] CPU: 2 PID: 15715 Comm: socket_listen Not tainted 3.14.0+ #294 [ 251.921386] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 251.921386] 0000000000000000 000000009d18c210 ffff880075f039b8 ffffffff816b7ecd [ 251.921386] ffffffff822c3b10 ffff880075f039c8 ffffffff816b36f4 ffff880075f03aa0 [ 251.921386] ffffffff810c65ff ffffffff810c4a85 00000000fffffe01 ffffffffa0075172 [ 251.921386] Call Trace: [ 251.921386] [] dump_stack+0x45/0x56 [ 251.921386] [] register_lock_class.part.24+0x38/0x3c [ 251.921386] [] __lock_acquire+0x168f/0x1b40 [ 251.921386] [] ? trace_hardirqs_on_caller+0x105/0x1d0 [ 251.921386] [] ? nf_nat_setup_info+0x252/0x3a0 [nf_nat] [ 251.921386] [] ? _raw_spin_unlock_bh+0x35/0x40 [ 251.921386] [] ? nf_nat_setup_info+0x252/0x3a0 [nf_nat] [ 251.921386] [] lock_acquire+0xa2/0x120 [ 251.921386] [] ? ipv4_confirm+0x90/0xf0 [nf_conntrack_ipv4] [ 251.921386] [] __nf_conntrack_confirm+0x129/0x410 [nf_conntrack] [ 251.921386] [] ? ipv4_confirm+0x90/0xf0 [nf_conntrack_ipv4] [ 251.921386] [] ipv4_confirm+0x90/0xf0 [nf_conntrack_ipv4] [ 251.921386] [] ? ip_fragment+0x9f0/0x9f0 [ 251.921386] [] nf_iterate+0xaa/0xc0 [ 251.921386] [] ? ip_fragment+0x9f0/0x9f0 [ 251.921386] [] nf_hook_slow+0xa4/0x190 [ 251.921386] [] ? ip_fragment+0x9f0/0x9f0 [ 251.921386] [] ip_output+0x92/0x100 [ 251.921386] [] ip_local_out+0x29/0x90 [ 251.921386] [] ip_queue_xmit+0x170/0x4c0 [ 251.921386] [] ? ip_queue_xmit+0x5/0x4c0 [ 251.921386] [] tcp_transmit_skb+0x498/0x960 [ 251.921386] [] tcp_connect+0x812/0x960 [ 251.921386] [] ? ktime_get_real+0x25/0x70 [ 251.921386] [] ? secure_tcp_sequence_number+0x6a/0xc0 [ 251.921386] [] tcp_v4_connect+0x317/0x470 [ 251.921386] [] __inet_stream_connect+0xb5/0x330 [ 251.921386] [] ? lock_sock_nested+0x33/0xa0 [ 251.921386] [] ? trace_hardirqs_on+0xd/0x10 [ 251.921386] [] ? __local_bh_enable_ip+0x75/0xe0 [ 251.921386] [] inet_stream_connect+0x38/0x50 [ 251.921386] [] SYSC_connect+0xe7/0x120 [ 251.921386] [] ? current_kernel_time+0x69/0xd0 [ 251.921386] [] ? trace_hardirqs_on_caller+0x105/0x1d0 [ 251.921386] [] ? trace_hardirqs_on+0xd/0x10 [ 251.921386] [] SyS_connect+0xe/0x10 [ 251.921386] [] system_call_fastpath+0x16/0x1b [ 312.014104] INFO: rcu_sched detected stalls on CPUs/tasks: {} (detected by 0, t=60003 jiffies, g=42359, c=42358, q=333) [ 312.015097] INFO: Stall ended before state dump start Fixes: 93bb0ceb75be ("netfilter: conntrack: remove central spinlock nf_conntrack_lock") Cc: Jesper Dangaard Brouer Cc: Pablo Neira Ayuso Cc: Patrick McHardy Cc: Jozsef Kadlecsik Cc: "David S. Miller" Signed-off-by: Andrey Vagin Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 6dba48efe01e..75421f2ba8be 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1795,6 +1795,7 @@ int nf_conntrack_init_net(struct net *net) int cpu; atomic_set(&net->ct.count, 0); + seqcount_init(&net->ct.generation); net->ct.pcpu_lists = alloc_percpu(struct ct_pcpu); if (!net->ct.pcpu_lists) -- GitLab From b855d416dc17061ebb271ea7ef1201d100531770 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sat, 12 Apr 2014 13:17:57 +0200 Subject: [PATCH 167/797] netfilter: nf_tables: fix nft_cmp_fast failure on big endian for size < 4 nft_cmp_fast is used for equality comparisions of size <= 4. For comparisions of size < 4 byte a mask is calculated that is applied to both the data from userspace (during initialization) and the register value (during runtime). Both values are stored using (in effect) memcpy to a memory area that is then interpreted as u32 by nft_cmp_fast. This works fine on little endian since smaller types have the same base address, however on big endian this is not true and the smaller types are interpreted as a big number with trailing zero bytes. The mask therefore must not include the lower bytes, but the higher bytes on big endian. Add a helper function that does a cpu_to_le32 to switch the bytes on big endian. Since we're dealing with a mask of just consequitive bits, this works out fine. Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- include/net/netfilter/nf_tables_core.h | 10 ++++++++++ net/netfilter/nf_tables_core.c | 3 +-- net/netfilter/nft_cmp.c | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h index cf2b7ae2b9d8..a75fc8e27cd6 100644 --- a/include/net/netfilter/nf_tables_core.h +++ b/include/net/netfilter/nf_tables_core.h @@ -13,6 +13,16 @@ struct nft_cmp_fast_expr { u8 len; }; +/* Calculate the mask for the nft_cmp_fast expression. On big endian the + * mask needs to include the *upper* bytes when interpreting that data as + * something smaller than the full u32, therefore a cpu_to_le32 is done. + */ +static inline u32 nft_cmp_fast_mask(unsigned int len) +{ + return cpu_to_le32(~0U >> (FIELD_SIZEOF(struct nft_cmp_fast_expr, + data) * BITS_PER_BYTE - len)); +} + extern const struct nft_expr_ops nft_cmp_fast_ops; int nft_cmp_module_init(void); diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 90998a6ff8b9..804105391b9a 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -25,9 +25,8 @@ static void nft_cmp_fast_eval(const struct nft_expr *expr, struct nft_data data[NFT_REG_MAX + 1]) { const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); - u32 mask; + u32 mask = nft_cmp_fast_mask(priv->len); - mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - priv->len); if ((data[priv->sreg].data[0] & mask) == priv->data) return; data[NFT_REG_VERDICT].verdict = NFT_BREAK; diff --git a/net/netfilter/nft_cmp.c b/net/netfilter/nft_cmp.c index 954925db414d..e2b3f51c81f1 100644 --- a/net/netfilter/nft_cmp.c +++ b/net/netfilter/nft_cmp.c @@ -128,7 +128,7 @@ static int nft_cmp_fast_init(const struct nft_ctx *ctx, BUG_ON(err < 0); desc.len *= BITS_PER_BYTE; - mask = ~0U >> (sizeof(priv->data) * BITS_PER_BYTE - desc.len); + mask = nft_cmp_fast_mask(desc.len); priv->data = data.data[0] & mask; priv->len = desc.len; return 0; -- GitLab From 7c66593286bcd153e4868383e675673a27071bd5 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Mon, 14 Apr 2014 15:09:44 +0800 Subject: [PATCH 168/797] ALSA: hda/realtek - Add support of ALC288 codec Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 14ae979a92ea..f7766febaebe 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4912,6 +4912,7 @@ static int patch_alc269(struct hda_codec *codec) spec->codec_variant = ALC269_TYPE_ALC285; break; case 0x10ec0286: + case 0x10ec0288: spec->codec_variant = ALC269_TYPE_ALC286; break; case 0x10ec0255: @@ -5781,6 +5782,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, + { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, -- GitLab From 1fb4e407b520a2344b92a680c75672c7900aedf8 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Apr 2014 11:08:26 +0200 Subject: [PATCH 169/797] ARM: ux500: configure for CW1200 WLAN chip The CW1200 WLAN chip driver had been in the kernel for a while, we only need to activate it for the Ux500 properly. The latter require some elaborative work, but in the meantime, let's make sure we atleast compile it in. Signed-off-by: Linus Walleij --- arch/arm/configs/u8500_defconfig | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig index 726b1fa786f7..d219d6a43238 100644 --- a/arch/arm/configs/u8500_defconfig +++ b/arch/arm/configs/u8500_defconfig @@ -34,7 +34,10 @@ CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_NETFILTER=y CONFIG_PHONET=y -# CONFIG_WIRELESS is not set +CONFIG_CFG80211=y +CONFIG_CFG80211_DEBUGFS=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y CONFIG_CAIF=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y @@ -45,7 +48,8 @@ CONFIG_SENSORS_BH1780=y CONFIG_NETDEVICES=y CONFIG_SMSC911X=y CONFIG_SMSC_PHY=y -# CONFIG_WLAN is not set +CONFIG_CW1200=y +CONFIG_CW1200_WLAN_SDIO=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_EVDEV=y # CONFIG_KEYBOARD_ATKBD is not set @@ -93,7 +97,6 @@ CONFIG_LEDS_CLASS=y CONFIG_LEDS_LM3530=y CONFIG_LEDS_GPIO=y CONFIG_LEDS_LP5521=y -CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AB8500=y -- GitLab From 2ec8e3787ae6957f738bb133e755213b9d7c066e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 2 Apr 2014 11:37:06 +0300 Subject: [PATCH 170/797] drm/omap: fix output enable/disable sequence At the moment it's quite easy to get the following errors when the HDMI output is enabled or disabled: [drm:omap_crtc_error_irq] *ERROR* tv: errors: 00008000 The reason for the errors is that the omapdrm driver doesn't properly handle the sync-lost irqs that happen when enabling the DIGIT crtc, which is used for HDMI and analog TV. The driver does disable the sync-lost irq properly, but it fails to wait until the output has been fully enabled (i.e. the first vsync), so the sync-lost errors are still seen occasionally. This patch makes the omapdrm act the same way as the omapfb does: - When enabling a display, we'll wait for the first vsync. - When disabling a display, we'll wait for framedone if available, or odd and even vsyncs. These changes make sure the output is fully enabled or disabled at the end of the function. Signed-off-by: Tomi Valkeinen Reported-by: Sanjay Singh Rawat Reviewed-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_crtc.c | 46 +++++++++++++++++------------ 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 355157e4f78d..0acbe62901d9 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -528,38 +528,46 @@ static void set_enabled(struct drm_crtc *crtc, bool enable) struct drm_device *dev = crtc->dev; struct omap_crtc *omap_crtc = to_omap_crtc(crtc); enum omap_channel channel = omap_crtc->channel; - struct omap_irq_wait *wait = NULL; + struct omap_irq_wait *wait; + u32 framedone_irq, vsync_irq; + int ret; if (dispc_mgr_is_enabled(channel) == enable) return; - /* ignore sync-lost irqs during enable/disable */ + /* + * Digit output produces some sync lost interrupts during the first + * frame when enabling, so we need to ignore those. + */ omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); - if (dispc_mgr_get_framedone_irq(channel)) { - if (!enable) { - wait = omap_irq_wait_init(dev, - dispc_mgr_get_framedone_irq(channel), 1); - } + framedone_irq = dispc_mgr_get_framedone_irq(channel); + vsync_irq = dispc_mgr_get_vsync_irq(channel); + + if (enable) { + wait = omap_irq_wait_init(dev, vsync_irq, 1); } else { /* - * When we disable digit output, we need to wait until fields - * are done. Otherwise the DSS is still working, and turning - * off the clocks prevents DSS from going to OFF mode. And when - * enabling, we need to wait for the extra sync losts + * When we disable the digit output, we need to wait for + * FRAMEDONE to know that DISPC has finished with the output. + * + * OMAP2/3 does not have FRAMEDONE irq for digit output, and in + * that case we need to use vsync interrupt, and wait for both + * even and odd frames. */ - wait = omap_irq_wait_init(dev, - dispc_mgr_get_vsync_irq(channel), 2); + + if (framedone_irq) + wait = omap_irq_wait_init(dev, framedone_irq, 1); + else + wait = omap_irq_wait_init(dev, vsync_irq, 2); } dispc_mgr_enable(channel, enable); - if (wait) { - int ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); - if (ret) { - dev_err(dev->dev, "%s: timeout waiting for %s\n", - omap_crtc->name, enable ? "enable" : "disable"); - } + ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100)); + if (ret) { + dev_err(dev->dev, "%s: timeout waiting for %s\n", + omap_crtc->name, enable ? "enable" : "disable"); } omap_irq_register(crtc->dev, &omap_crtc->error_irq); -- GitLab From 707cf58a0a847f60f849b44bfb9b85dcc17c599d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 2 Apr 2014 13:47:43 +0300 Subject: [PATCH 171/797] drm/omap: fix uninit order in pdev_remove() When unloading omapdrm driver, the omapdrm platform device is uninitialized last, after the displays have been disconnected omap_crtc callbacks have been removed. As the omapdrm pdev uninitialization needs the features uninitialized in earlier steps, a crash is guaranteed. This patch fixes the uninitialize order so that the omapdrm pdev is removed first. Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index bf39fcc49e0f..df3e66416a30 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -696,10 +696,11 @@ static int pdev_remove(struct platform_device *device) { DBG(""); + drm_put_dev(platform_get_drvdata(device)); + omap_disconnect_dssdevs(); omap_crtc_pre_uninit(); - drm_put_dev(platform_get_drvdata(device)); return 0; } -- GitLab From ea7e3a662814447cd329390feddd04b9ec0a4b82 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 2 Apr 2014 14:31:50 +0300 Subject: [PATCH 172/797] drm/omap: fix DMM driver (un)registration At the moment the DMM driver is never unregistered, even if it's registered in the omapdrm module's init function. This means we'll get errors when reloading the omapdrm module. Fix this by unregistering the DMM driver properly, and also change the module init to fail if DMM driver cannot be registered, simplifying the unregister path as we don't need to keep the state whether we registered the DMM driver or not. Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_drv.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index df3e66416a30..f16a07d1668d 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -727,18 +727,33 @@ static struct platform_driver pdev = { static int __init omap_drm_init(void) { + int r; + DBG("init"); - if (platform_driver_register(&omap_dmm_driver)) { - /* we can continue on without DMM.. so not fatal */ - dev_err(NULL, "DMM registration failed\n"); + + r = platform_driver_register(&omap_dmm_driver); + if (r) { + pr_err("DMM driver registration failed\n"); + return r; } - return platform_driver_register(&pdev); + + r = platform_driver_register(&pdev); + if (r) { + pr_err("omapdrm driver registration failed\n"); + platform_driver_unregister(&omap_dmm_driver); + return r; + } + + return 0; } static void __exit omap_drm_fini(void) { DBG("fini"); + platform_driver_unregister(&pdev); + + platform_driver_unregister(&omap_dmm_driver); } /* need late_initcall() so we load after dss_driver's are loaded */ -- GitLab From e2f8fd74ec1bf15cb2abc1b11f7d9fa09581024e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 2 Apr 2014 14:31:57 +0300 Subject: [PATCH 173/797] drm/omap: fix race issue when unloading omapdrm At module unload, omap_fbdev_free() gets called which releases the framebuffers. However, the framebuffers are still used by crtcs, and will be released only later at vsync. The driver doesn't wait for this, and goes on to release the rest of the resources, which often causes a crash. This patchs adds a omap_crtc_flush() function which waits until the crtc has finished with its apply queue and page flips. The function utilizes a simple polling while-loop, as the performance is not an issue here. Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_crtc.c | 19 +++++++++++++++++++ drivers/gpu/drm/omapdrm/omap_drv.c | 6 ++++++ drivers/gpu/drm/omapdrm/omap_drv.h | 1 + 3 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 0acbe62901d9..161a74a3ac5e 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -621,6 +621,25 @@ static void omap_crtc_post_apply(struct omap_drm_apply *apply) /* nothing needed for post-apply */ } +void omap_crtc_flush(struct drm_crtc *crtc) +{ + struct omap_crtc *omap_crtc = to_omap_crtc(crtc); + int loops = 0; + + while (!list_empty(&omap_crtc->pending_applies) || + !list_empty(&omap_crtc->queued_applies) || + omap_crtc->event || omap_crtc->old_fb) { + + if (++loops > 10) { + dev_err(crtc->dev->dev, + "omap_crtc_flush() timeout\n"); + break; + } + + schedule_timeout_uninterruptible(msecs_to_jiffies(20)); + } +} + static const char *channel_names[] = { [OMAP_DSS_CHANNEL_LCD] = "lcd", [OMAP_DSS_CHANNEL_DIGIT] = "tv", diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index f16a07d1668d..c8270e4b26f3 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -513,12 +513,18 @@ static int dev_load(struct drm_device *dev, unsigned long flags) static int dev_unload(struct drm_device *dev) { struct omap_drm_private *priv = dev->dev_private; + int i; DBG("unload: dev=%p", dev); drm_kms_helper_poll_fini(dev); omap_fbdev_free(dev); + + /* flush crtcs so the fbs get released */ + for (i = 0; i < priv->num_crtcs; i++) + omap_crtc_flush(priv->crtcs[i]); + omap_modeset_free(dev); omap_gem_deinit(dev); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 428b2981fd68..284b80fc3c54 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -163,6 +163,7 @@ void omap_crtc_pre_init(void); void omap_crtc_pre_uninit(void); struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_plane *plane, enum omap_channel channel, int id); +void omap_crtc_flush(struct drm_crtc *crtc); struct drm_plane *omap_plane_init(struct drm_device *dev, int plane_id, bool private_plane); -- GitLab From c7aef12f344459961eb1e0ba10d184816ed42d99 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Apr 2014 16:30:03 +0300 Subject: [PATCH 174/797] drm/omap: fix missing disable for unused encoder When an encoder is no longer connected to a crtc, the driver will leave the encoder enabled. This patch adds code to track the encoder used for a crtc, and when the encoder changes, the old one is disabled. Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_crtc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 161a74a3ac5e..61d1c4897a45 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -33,6 +33,7 @@ struct omap_crtc { int pipe; enum omap_channel channel; struct omap_overlay_manager_info info; + struct drm_encoder *current_encoder; /* * Temporary: eventually this will go away, but it is needed @@ -594,6 +595,11 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply) } } + if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder) + omap_encoder_set_enabled(omap_crtc->current_encoder, false); + + omap_crtc->current_encoder = encoder; + if (!omap_crtc->enabled) { set_enabled(&omap_crtc->base, false); if (encoder) -- GitLab From 506096a113832239ce763d20fab8e94f76d56266 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 3 Apr 2014 13:11:54 +0300 Subject: [PATCH 175/797] drm/omap: fix enabling/disabling of video pipeline At the moment the omap_crtc_pre_apply() handles the enabling, disabling and configuring of encoders and panels separately from the CRTC (i.e. the overlay manager). However, this doesn't work correctly. The encoder driver has to be in control of its video input (i.e. the crtc) for correct operation. This problem causes bugs with (at least) HDMI: the HDMI encoder supplies pixel clock for DISPC, and DISPC supplies video stream for HDMI. The current code first enables the HDMI encoder, and CRTC after that. However, the encoder expects the video stream to start during the encoder's enable, and if it doesn't, there will be sync lost errors. The encoder enables its video source by calling src->enable(), and this call goes to omapdrm (omap_crtc_enable), but omapdrm doesn't do anything in that function. Similarly for disable, which goes to omap_crtc_disable(). This patch moves the code to setup and enable/disable the crtc to omap_crtc_enable. and omap_crtc_disable(). Signed-off-by: Tomi Valkeinen Reviewed-by: Rob Clark --- drivers/gpu/drm/omapdrm/omap_crtc.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 61d1c4897a45..f59ef9359e66 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -121,13 +121,25 @@ static void omap_crtc_start_update(struct omap_overlay_manager *mgr) { } +static void set_enabled(struct drm_crtc *crtc, bool enable); + static int omap_crtc_enable(struct omap_overlay_manager *mgr) { + struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; + + dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info); + dispc_mgr_set_timings(omap_crtc->channel, + &omap_crtc->timings); + set_enabled(&omap_crtc->base, true); + return 0; } static void omap_crtc_disable(struct omap_overlay_manager *mgr) { + struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; + + set_enabled(&omap_crtc->base, false); } static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, @@ -601,7 +613,6 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply) omap_crtc->current_encoder = encoder; if (!omap_crtc->enabled) { - set_enabled(&omap_crtc->base, false); if (encoder) omap_encoder_set_enabled(encoder, false); } else { @@ -610,13 +621,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply) omap_encoder_update(encoder, omap_crtc->mgr, &omap_crtc->timings); omap_encoder_set_enabled(encoder, true); - omap_crtc->full_update = false; } - - dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info); - dispc_mgr_set_timings(omap_crtc->channel, - &omap_crtc->timings); - set_enabled(&omap_crtc->base, true); } omap_crtc->full_update = false; -- GitLab From d4586604acbd2e58921e0363533b9797b0235275 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 5 Apr 2014 21:33:51 +0300 Subject: [PATCH 176/797] drm/omap: fix plane rotation Plane rotation with omapdrm is currently broken. It seems omap_plane_mode_set() expects width and height in screen coordinates, so pass it like that. Signed-off-by: Grazvydas Ignotas Reviewed-by: Rob Clark Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_plane.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 046d5e660c04..df1725247cca 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -246,6 +246,14 @@ static int omap_plane_update(struct drm_plane *plane, drm_framebuffer_reference(fb); + /* omap_plane_mode_set() takes adjusted src */ + switch (omap_plane->win.rotation & 0xf) { + case BIT(DRM_ROTATE_90): + case BIT(DRM_ROTATE_270): + swap(src_w, src_h); + break; + } + return omap_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h, -- GitLab From 5e19c06d0e570a347669acc2b850c2f730090b60 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Apr 2014 15:25:34 +0300 Subject: [PATCH 177/797] drm/omap: fix missing unref to fb's buf object omap_fbdev_create() takes a reference to the fb's gem object with omap_gem_get_paddr(). However, it never releases it with omap_gem_put_paddr(). This patch adds the missing omap_gem_put_paddr() to omap_fbdev_free(). Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_fbdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c index 002988d09021..1388ca7f87e8 100644 --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c @@ -371,6 +371,9 @@ void omap_fbdev_free(struct drm_device *dev) fbdev = to_omap_fbdev(priv->fbdev); + /* release the ref taken in omap_fbdev_create() */ + omap_gem_put_paddr(fbdev->bo); + /* this will free the backing object */ if (fbdev->fb) { drm_framebuffer_unregister_private(fbdev->fb); -- GitLab From e6bcd1a8974fab74e9fd679fb64462b2a8deff41 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Thu, 10 Apr 2014 10:35:42 +0900 Subject: [PATCH 178/797] x86/build: Supress "Nothing to be done for ..." messages When we build an already built kernel again, arch/x86/syscalls/Makefile and arch/x86/tools/Makefile emits "Nothing to be done for ..." messages. Here is the command log: $ make defconfig [ snip ] $ make [ snip ] $ make make[1]: Nothing to be done for `all'. <----- make[1]: Nothing to be done for `relocs'. <----- CHK include/config/kernel.release CHK include/generated/uapi/linux/version.h Besides not emitting those, "all" and "relocs" should be added to PHONY as well. Signed-off-by: Masahiro Yamada Acked-by: Peter Foley Acked-by: Michal Marek Link: http://lkml.kernel.org/r/1397093742-11144-1-git-send-email-yamada.m@jp.panasonic.com Signed-off-by: Ingo Molnar --- arch/x86/syscalls/Makefile | 2 ++ arch/x86/tools/Makefile | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile index f325af26107c..3323c2745248 100644 --- a/arch/x86/syscalls/Makefile +++ b/arch/x86/syscalls/Makefile @@ -54,5 +54,7 @@ syshdr-$(CONFIG_X86_64) += syscalls_64.h targets += $(uapisyshdr-y) $(syshdr-y) +PHONY += all all: $(addprefix $(uapi)/,$(uapisyshdr-y)) all: $(addprefix $(out)/,$(syshdr-y)) + @: diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile index e8120346903b..604a37efd4d5 100644 --- a/arch/x86/tools/Makefile +++ b/arch/x86/tools/Makefile @@ -40,4 +40,6 @@ $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/ina HOST_EXTRACFLAGS += -I$(srctree)/tools/include hostprogs-y += relocs relocs-objs := relocs_32.o relocs_64.o relocs_common.o +PHONY += relocs relocs: $(obj)/relocs + @: -- GitLab From 5e09714b0e877d5d062530aae4061074d864243f Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 19 Mar 2014 10:46:18 +0900 Subject: [PATCH 179/797] perf top: Fix documentation of invalid -s option On perf top, the -s option is used for --sort, but the man page contains invalid documentation of -s option for --sym-annotate. Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1395193578-27098-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/perf/Documentation/perf-top.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index cdd8d4946dba..976b00c6cdb1 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -87,7 +87,6 @@ Default is to monitor all CPUS. --realtime=:: Collect data with this RT SCHED_FIFO priority. --s :: --sym-annotate=:: Annotate this symbol. -- GitLab From 3388cc3eb848154d0f2a0cd01542201d0d0fdad7 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 19 Mar 2014 10:22:53 +0900 Subject: [PATCH 180/797] tools lib traceevent: Print event name when show warning if possible It's sometimes useful to know where the parse failure was occurred. Add do_warning_event() macro to see the failing event. It now shows the messages like below: $ perf test 5 5: parse events tests : Warning: [kvmmmu:kvm_mmu_get_page] bad op token { Warning: [kvmmmu:kvm_mmu_sync_page] bad op token { Warning: [kvmmmu:kvm_mmu_unsync_page] bad op token { Warning: [kvmmmu:kvm_mmu_prepare_zap_page] bad op token { Warning: [kvmmmu:fast_page_fault] function is_writable_pte not defined Warning: [xen:xen_mmu_ptep_modify_prot_commit] function sizeof not defined Warning: [xen:xen_mmu_ptep_modify_prot_start] function sizeof not defined Warning: [xen:xen_mmu_set_pgd] function sizeof not defined Warning: [xen:xen_mmu_set_pud] function sizeof not defined Warning: [xen:xen_mmu_set_pmd] function sizeof not defined ... Signed-off-by: Namhyung Kim Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Ramkumar Ramachandra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1395192174-26273-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/lib/traceevent/event-parse.c | 103 +++++++++++++++++------------ 1 file changed, 62 insertions(+), 41 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 1587ea392ad6..33803c0b94d6 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -50,6 +50,18 @@ static int show_warning = 1; warning(fmt, ##__VA_ARGS__); \ } while (0) +#define do_warning_event(event, fmt, ...) \ + do { \ + if (!show_warning) \ + continue; \ + \ + if (event) \ + warning("[%s:%s] " fmt, event->system, \ + event->name, ##__VA_ARGS__); \ + else \ + warning(fmt, ##__VA_ARGS__); \ + } while (0) + static void init_input_buf(const char *buf, unsigned long long size) { input_buf = buf; @@ -1355,7 +1367,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f } if (!field->type) { - do_warning("%s: no type found", __func__); + do_warning_event(event, "%s: no type found", __func__); goto fail; } field->name = last_token; @@ -1402,7 +1414,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f free_token(token); type = read_token(&token); if (type == EVENT_NONE) { - do_warning("failed to find token"); + do_warning_event(event, "failed to find token"); goto fail; } } @@ -1636,7 +1648,7 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok) right = alloc_arg(); if (!arg || !left || !right) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); /* arg will be freed at out_free */ free_arg(left); free_arg(right); @@ -1686,7 +1698,7 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) arg = alloc_arg(); if (!arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); /* '*tok' is set to top->op.op. No need to free. */ *tok = NULL; return EVENT_ERROR; @@ -1792,7 +1804,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) if (arg->type == PRINT_OP && !arg->op.left) { /* handle single op */ if (token[1]) { - do_warning("bad op token %s", token); + do_warning_event(event, "bad op token %s", token); goto out_free; } switch (token[0]) { @@ -1802,7 +1814,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) case '-': break; default: - do_warning("bad op token %s", token); + do_warning_event(event, "bad op token %s", token); goto out_free; } @@ -1888,7 +1900,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) char *new_atom; if (left->type != PRINT_ATOM) { - do_warning("bad pointer type"); + do_warning_event(event, "bad pointer type"); goto out_free; } new_atom = realloc(left->atom.atom, @@ -1930,7 +1942,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) type = process_array(event, arg, tok); } else { - do_warning("unknown op '%s'", token); + do_warning_event(event, "unknown op '%s'", token); event->flags |= EVENT_FL_FAILED; /* the arg is now the left side */ goto out_free; @@ -1951,7 +1963,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) return type; out_warn_free: - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); out_free: free_token(token); *tok = NULL; @@ -2385,7 +2397,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } @@ -2438,7 +2450,7 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } @@ -2477,7 +2489,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); goto out_free; } @@ -2492,7 +2504,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) field = alloc_arg(); if (!field) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); *tok = NULL; return EVENT_ERROR; } @@ -2555,7 +2567,7 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** free_token(token); arg = alloc_arg(); if (!arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", __func__); *tok = NULL; return EVENT_ERROR; } @@ -2614,13 +2626,14 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) /* prevous must be an atom */ if (arg->type != PRINT_ATOM) { - do_warning("previous needed to be PRINT_ATOM"); + do_warning_event(event, "previous needed to be PRINT_ATOM"); goto out_free; } item_arg = alloc_arg(); if (!item_arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); goto out_free; } @@ -2721,7 +2734,8 @@ process_func_handler(struct event_format *event, struct pevent_function_handler for (i = 0; i < func->nr_args; i++) { farg = alloc_arg(); if (!farg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); return EVENT_ERROR; } @@ -2792,7 +2806,7 @@ process_function(struct event_format *event, struct print_arg *arg, return process_func_handler(event, func, arg, tok); } - do_warning("function %s not defined", token); + do_warning_event(event, "function %s not defined", token); free_token(token); return EVENT_ERROR; } @@ -2878,7 +2892,7 @@ process_arg_token(struct event_format *event, struct print_arg *arg, case EVENT_ERROR ... EVENT_NEWLINE: default: - do_warning("unexpected type %d", type); + do_warning_event(event, "unexpected type %d", type); return EVENT_ERROR; } *tok = token; @@ -2901,7 +2915,8 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** arg = alloc_arg(); if (!arg) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); return -1; } @@ -3481,11 +3496,12 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg return val; out_warning_op: - do_warning("%s: unknown op '%s'", __func__, arg->op.op); + do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op); return 0; out_warning_field: - do_warning("%s: field %s not found", __func__, arg->field.name); + do_warning_event(event, "%s: field %s not found", + __func__, arg->field.name); return 0; } @@ -3591,7 +3607,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, } str = malloc(len + 1); if (!str) { - do_warning("%s: not enough memory!", __func__); + do_warning_event(event, "%s: not enough memory!", + __func__); return; } memcpy(str, data + field->offset, len); @@ -3697,7 +3714,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, return; out_warning_field: - do_warning("%s: field %s not found", __func__, arg->field.name); + do_warning_event(event, "%s: field %s not found", + __func__, arg->field.name); } static unsigned long long @@ -3742,14 +3760,16 @@ process_defined_func(struct trace_seq *s, void *data, int size, trace_seq_terminate(&str); string = malloc(sizeof(*string)); if (!string) { - do_warning("%s(%d): malloc str", __func__, __LINE__); + do_warning_event(event, "%s(%d): malloc str", + __func__, __LINE__); goto out_free; } string->next = strings; string->str = strdup(str.buffer); if (!string->str) { free(string); - do_warning("%s(%d): malloc str", __func__, __LINE__); + do_warning_event(event, "%s(%d): malloc str", + __func__, __LINE__); goto out_free; } args[i] = (uintptr_t)string->str; @@ -3761,7 +3781,7 @@ process_defined_func(struct trace_seq *s, void *data, int size, * Something went totally wrong, this is not * an input error, something in this code broke. */ - do_warning("Unexpected end of arguments\n"); + do_warning_event(event, "Unexpected end of arguments\n"); goto out_free; } farg = farg->next; @@ -3811,12 +3831,12 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc if (!field) { field = pevent_find_field(event, "buf"); if (!field) { - do_warning("can't find buffer field for binary printk"); + do_warning_event(event, "can't find buffer field for binary printk"); return NULL; } ip_field = pevent_find_field(event, "ip"); if (!ip_field) { - do_warning("can't find ip field for binary printk"); + do_warning_event(event, "can't find ip field for binary printk"); return NULL; } pevent->bprint_buf_field = field; @@ -3830,7 +3850,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc */ args = alloc_arg(); if (!args) { - do_warning("%s(%d): not enough memory!", __func__, __LINE__); + do_warning_event(event, "%s(%d): not enough memory!", + __func__, __LINE__); return NULL; } arg = args; @@ -3896,7 +3917,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc bptr += vsize; arg = alloc_arg(); if (!arg) { - do_warning("%s(%d): not enough memory!", + do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); goto out_free; } @@ -3919,7 +3940,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc case 's': arg = alloc_arg(); if (!arg) { - do_warning("%s(%d): not enough memory!", + do_warning_event(event, "%s(%d): not enough memory!", __func__, __LINE__); goto out_free; } @@ -3959,7 +3980,7 @@ get_bprint_format(void *data, int size __maybe_unused, if (!field) { field = pevent_find_field(event, "fmt"); if (!field) { - do_warning("can't find format field for binary printk"); + do_warning_event(event, "can't find format field for binary printk"); return NULL; } pevent->bprint_fmt_field = field; @@ -4003,8 +4024,8 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, arg->field.field = pevent_find_any_field(event, arg->field.name); if (!arg->field.field) { - do_warning("%s: field %s not found", - __func__, arg->field.name); + do_warning_event(event, "%s: field %s not found", + __func__, arg->field.name); return; } } @@ -4176,7 +4197,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event case '*': /* The argument is the length. */ if (!arg) { - do_warning("no argument match"); + do_warning_event(event, "no argument match"); event->flags |= EVENT_FL_FAILED; goto out_failed; } @@ -4213,7 +4234,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event case 'X': case 'u': if (!arg) { - do_warning("no argument match"); + do_warning_event(event, "no argument match"); event->flags |= EVENT_FL_FAILED; goto out_failed; } @@ -4223,7 +4244,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event /* should never happen */ if (len > 31) { - do_warning("bad format!"); + do_warning_event(event, "bad format!"); event->flags |= EVENT_FL_FAILED; len = 31; } @@ -4290,13 +4311,13 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event trace_seq_printf(s, format, (long long)val); break; default: - do_warning("bad count (%d)", ls); + do_warning_event(event, "bad count (%d)", ls); event->flags |= EVENT_FL_FAILED; } break; case 's': if (!arg) { - do_warning("no matching argument"); + do_warning_event(event, "no matching argument"); event->flags |= EVENT_FL_FAILED; goto out_failed; } @@ -4306,7 +4327,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event /* should never happen */ if (len > 31) { - do_warning("bad format!"); + do_warning_event(event, "bad format!"); event->flags |= EVENT_FL_FAILED; len = 31; } -- GitLab From 9e9e5dfd86b9fdea8c75bae42cba052901b94f78 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 19 Mar 2014 10:22:54 +0900 Subject: [PATCH 181/797] tools lib traceevent: Do not call warning() directly The patch 3a3ffa2e82205 ("tools lib traceevent: Report better error message on bad function args") added the error message but it seems there's no reason to call warning() directly. So change it to do_warning_event() to provide event information too. Signed-off-by: Namhyung Kim Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1395192174-26273-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/lib/traceevent/event-parse.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 33803c0b94d6..baec7d887da4 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -2742,14 +2742,16 @@ process_func_handler(struct event_format *event, struct pevent_function_handler type = process_arg(event, farg, &token); if (i < (func->nr_args - 1)) { if (type != EVENT_DELIM || strcmp(token, ",") != 0) { - warning("Error: function '%s()' expects %d arguments but event %s only uses %d", + do_warning_event(event, + "Error: function '%s()' expects %d arguments but event %s only uses %d", func->name, func->nr_args, event->name, i + 1); goto err; } } else { if (type != EVENT_DELIM || strcmp(token, ")") != 0) { - warning("Error: function '%s()' only expects %d arguments but event %s has more", + do_warning_event(event, + "Error: function '%s()' only expects %d arguments but event %s has more", func->name, func->nr_args, event->name); goto err; } -- GitLab From 945895574873101c72a2d90a8cf1e09922378968 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 25 Mar 2014 09:35:11 -0300 Subject: [PATCH 182/797] perf callchains: Disable unwind libraries when libelf isn't found I.e. do the same as when NO_LIBELF is explicitely passed in the 'make' command line, fixing this: Auto-detecting system features: ... dwarf: [ OFF ] ... glibc: [ on ] ... gtk2: [ OFF ] ... libaudit: [ OFF ] ... libbfd: [ OFF ] ... libelf: [ OFF ] ... libunwind: [ OFF ] ... libdw-dwarf-unwind: [ OFF ] ... DWARF post unwind library: libdw CC /tmp/build/perf/util/symbol-minimal.o CC /tmp/build/perf/util/unwind-libdw.o arch/x86/util/unwind-libdw.c:1:30: fatal error: elfutils/libdwfl.h: No such file or directory compilation terminated. CC /tmp/build/perf/tests/keep-tracking.o util/unwind-libdw.c:2:28: fatal error: elfutils/libdw.h: No such file or directory compilation terminated. Cc: Adrian Hunter Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-e39j1yxanltjx4t0msse63ax@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- tools/perf/config/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index c23418225c2c..5a3c452e8e77 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -278,6 +278,8 @@ else NO_LIBELF := 1 NO_DWARF := 1 NO_DEMANGLE := 1 + NO_LIBUNWIND := 1 + NO_LIBDW_DWARF_UNWIND := 1 else msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); endif -- GitLab From f80c539323984257d62f7683b1262ce24c52ce26 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Thu, 27 Mar 2014 17:36:14 -0300 Subject: [PATCH 183/797] MAINTAINERS: Change e-mail to kernel.org one Leaving ghostprotocols.net for old networking stuff. Cc: Adrian Hunter Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-jott6d40nkjjc3vvh3vw53lp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Jiri Olsa --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1ecfde109667..b06a9a8fed88 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6678,7 +6678,7 @@ PERFORMANCE EVENTS SUBSYSTEM M: Peter Zijlstra M: Paul Mackerras M: Ingo Molnar -M: Arnaldo Carvalho de Melo +M: Arnaldo Carvalho de Melo L: linux-kernel@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core S: Supported -- GitLab From 2c529e4e6aab405aa52e8627cbd691ed28b56a0b Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Wed, 26 Mar 2014 18:44:05 -0400 Subject: [PATCH 184/797] perf tools: Pick up libdw without explicit LIBDW_DIR The Makefile logic sets FEATURE_CHECKS_CFLAGS-libdw-dwarf-unwind and FEATURE_CHECKS_LDFLAGS-libdw-dwarf-unwind only if LIBDW_DIR is defined. This means that under a normal setup, $ make NO_LIBUNWIND=1 won't automatically pick up libdw. Fix this. Signed-off-by: Ramkumar Ramachandra Acked-by: Jean Pihet Cc: Arnaldo Carvalho de Melo Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1395873845-466-1-git-send-email-artagnon@gmail.com Signed-off-by: Jiri Olsa --- tools/perf/config/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 5a3c452e8e77..ee21fa95ebcf 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -65,10 +65,9 @@ ifndef NO_LIBELF ifdef LIBDW_DIR LIBDW_CFLAGS := -I$(LIBDW_DIR)/include LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib - - FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) - FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw endif + FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) + FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw endif # include ARCH specific config -- GitLab From 202c7c123c96a1c193149b7fa2718d7fb143efb2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 1 Apr 2014 13:47:57 +0900 Subject: [PATCH 185/797] perf probe: Fix --line option behavior The commit 5a62257a3ddd1 ("perf probe: Replace line_list with intlist") replaced line_list to intlist but it has a problem that if a same line was added again, it'd return -EEXIST rather than 1. Since line_range_walk_cb() only checks the result being negative, it resulted in failure or segfault sometimes. Signed-off-by: Namhyung Kim Acked-by: Masami Hiramatsu Cc: Masami Hiramatsu Link: http://lkml.kernel.org/r/1396327677-3657-1-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/probe-finder.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index df0238654698..3bf0c8cdccb7 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1441,13 +1441,15 @@ static int line_range_walk_cb(const char *fname, int lineno, void *data) { struct line_finder *lf = data; + int err; if ((strtailcmp(fname, lf->fname) != 0) || (lf->lno_s > lineno || lf->lno_e < lineno)) return 0; - if (line_range_add_line(fname, lineno, lf->lr) < 0) - return -EINVAL; + err = line_range_add_line(fname, lineno, lf->lr); + if (err < 0 && err != -EEXIST) + return err; return 0; } -- GitLab From 182c228ebcf1ac67a44e62236d8f7a8a9a3c5699 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 2 Apr 2014 14:48:31 +0900 Subject: [PATCH 186/797] perf probe: Fix to handle errors in line_range searching As Namhyung reported(https://lkml.org/lkml/2014/4/1/89), current perf-probe -L option doesn't handle errors in line-range searching correctly. It causes a SEGV if an error occured in the line-range searching. ---- $ perf probe -x ./perf -v -L map__load Open Debuginfo file: /home/namhyung/project/linux/tools/perf/perf fname: util/map.c, lineno:153 New line range: 153 to 2147483647 path: (null) Segmentation fault (core dumped) ---- This is because line_range_inline_cb() ignores errors from find_line_range_by_line() which means that lr->path is already freed on the error path in find_line_range_by_line(). As a result, get_real_path() accesses the lr->path and it causes a NULL pointer exception. This fixes line_range_inline_cb() to handle the error correctly, and report it to the caller. Anyway, this just fixes a possible SEGV bug, Namhyung's patch is also required. Reported-by: Namhyung Kim Signed-off-by: Masami Hiramatsu Acked-by: Namhyung Kim Cc: Arnaldo Carvalho de Melo Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140402054831.19080.27006.stgit@ltc230.yrl.intra.hitachi.co.jp Signed-off-by: Jiri Olsa --- tools/perf/util/probe-finder.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 3bf0c8cdccb7..fae274e72fe6 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1475,14 +1475,15 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf) static int line_range_inline_cb(Dwarf_Die *in_die, void *data) { - find_line_range_by_line(in_die, data); + int ret = find_line_range_by_line(in_die, data); /* * We have to check all instances of inlined function, because * some execution paths can be optimized out depends on the - * function argument of instances + * function argument of instances. However, if an error occurs, + * it should be handled by the caller. */ - return 0; + return ret < 0 ? ret : 0; } /* Search function definition from function name */ -- GitLab From 03d89412981a7681971bc77edba1669595763030 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 7 Apr 2014 16:05:48 +0900 Subject: [PATCH 187/797] perf probe: Use dwarf_getcfi_elf() instead of dwarf_getcfi() The dwarf_getcfi() only checks .debug_frame section for CFI, but as most binaries only have .eh_frame it'd return NULL and it makes some variables inaccessible. Using dwarf_getcfi_elf (along with dwarf_getelf()) allows to show and add probe to more variables. Signed-off-by: Namhyung Kim Acked-by: Masami Hiramatsu Cc: Masami Hiramatsu Link: http://lkml.kernel.org/r/1396854348-9296-1-git-send-email-namhyung@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/util/probe-finder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index fae274e72fe6..562762117639 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -985,7 +985,7 @@ static int debuginfo__find_probes(struct debuginfo *dbg, #if _ELFUTILS_PREREQ(0, 142) /* Get the call frame information from this dwarf */ - pf->cfi = dwarf_getcfi(dbg->dbg); + pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg)); #endif off = 0; -- GitLab From 95a2b3c0a9e2a8038edbf3f9776d5a3d76146459 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 27 Mar 2014 19:50:18 -0400 Subject: [PATCH 188/797] perf bench: Update manpage to mention numa and futex Signed-off-by: Ramkumar Ramachandra Cc: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1395964219-22173-3-git-send-email-artagnon@gmail.com Signed-off-by: Jiri Olsa --- tools/perf/Documentation/perf-bench.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt index 7065cd6fbdfc..4464ad770d51 100644 --- a/tools/perf/Documentation/perf-bench.txt +++ b/tools/perf/Documentation/perf-bench.txt @@ -48,6 +48,12 @@ SUBSYSTEM 'mem':: Memory access performance. +'numa':: + NUMA scheduling and MM benchmarks. + +'futex':: + Futex stressing benchmarks. + 'all':: All benchmark subsystems. @@ -187,6 +193,22 @@ Show only the result with page faults before memset. --no-prefault:: Show only the result without page faults before memset. +SUITES FOR 'numa' +~~~~~~~~~~~~~~~~~ +*mem*:: +Suite for evaluating NUMA workloads. + +SUITES FOR 'futex' +~~~~~~~~~~~~~~~~~~ +*hash*:: +Suite for evaluating hash tables. + +*wake*:: +Suite for evaluating wake calls. + +*requeue*:: +Suite for evaluating requeue calls. + SEE ALSO -------- linkperf:perf[1] -- GitLab From 5673872d4afd2584e075cf2b1adb2cccec46a0f3 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 27 Mar 2014 19:50:19 -0400 Subject: [PATCH 189/797] perf bench: Fix segfault at the end of an 'all' execution At the end of $ perf bench all the program segfaults because it attempts to dereference a NULL pointer. Fix this fault. Signed-off-by: Ramkumar Ramachandra Cc: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1395964219-22173-4-git-send-email-artagnon@gmail.com Signed-off-by: Jiri Olsa --- tools/perf/builtin-bench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-bench.c b/tools/perf/builtin-bench.c index f600b74216da..1e6e77710545 100644 --- a/tools/perf/builtin-bench.c +++ b/tools/perf/builtin-bench.c @@ -86,7 +86,7 @@ static struct collection collections[] = { /* Iterate over all benchmarks within a collection: */ #define for_each_bench(coll, bench) \ - for (bench = coll->benchmarks; bench->name; bench++) + for (bench = coll->benchmarks; bench && bench->name; bench++) static void dump_benchmarks(struct collection *coll) { -- GitLab From 40ba93e3aa001246110320edbe8cf2eb488c1fe7 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 27 Mar 2014 19:50:17 -0400 Subject: [PATCH 190/797] perf bench: Set more defaults in the 'numa' suite Currently, $ perf bench numa mem errors out with usage information. To make this more user-friendly, let us provide a minimum set of default values required for a test run. As an added bonus, $ perf bench all now goes all the way to completion. Signed-off-by: Ramkumar Ramachandra Cc: Arnaldo Carvalho de Melo Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Link: http://lkml.kernel.org/r/1395964219-22173-2-git-send-email-artagnon@gmail.com Signed-off-by: Jiri Olsa --- tools/perf/bench/numa.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c index d4c83c60b9b2..20697fbf2c98 100644 --- a/tools/perf/bench/numa.c +++ b/tools/perf/bench/numa.c @@ -1593,6 +1593,10 @@ static void init_params(struct params *p, const char *name, int argc, const char p->data_rand_walk = true; p->nr_loops = -1; p->init_random = true; + p->mb_global_str = "1"; + p->nr_proc = 1; + p->nr_threads = 1; + p->nr_secs = 5; } static int run_bench_numa(const char *name, const char **argv) -- GitLab From 90f6bb6c98ffef42125d7be6d4612505f561fbce Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 25 Mar 2014 10:31:38 -0700 Subject: [PATCH 191/797] perf stat: Initialize statistics correctly perf stat did initialize the stats structure used to compute stddev etc. incorrectly. It merely zeroes it. But one member (min) needs to be set to a non zero value. This causes min to be not computed at all. Call init_stats() correctly. It doesn't matter for stat currently because it doesn't use min, but it's still better to do it correctly. The other users of statistics are already correct. Signed-off-by: Andi Kleen Acked-by: Namhyung Kim Link: http://lkml.kernel.org/r/1395768699-16060-1-git-send-email-andi@firstfloor.org Signed-off-by: Jiri Olsa --- tools/perf/builtin-stat.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 8b0e1c9234d9..65a151e36067 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -174,13 +174,20 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel) static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel) { - memset(evsel->priv, 0, sizeof(struct perf_stat)); + int i; + struct perf_stat *ps = evsel->priv; + + for (i = 0; i < 3; i++) + init_stats(&ps->res_stats[i]); } static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel) { evsel->priv = zalloc(sizeof(struct perf_stat)); - return evsel->priv == NULL ? -ENOMEM : 0; + if (evsel == NULL) + return -ENOMEM; + perf_evsel__reset_stat_priv(evsel); + return 0; } static void perf_evsel__free_stat_priv(struct perf_evsel *evsel) -- GitLab From 8d018647e00876e0c0e8dba13c52c882be4e1678 Mon Sep 17 00:00:00 2001 From: Jon Ringle Date: Tue, 1 Apr 2014 08:39:34 -0400 Subject: [PATCH 192/797] video: da8xx-fb: Fix casting of info->pseudo_palette The casting to (u16 *) on info->pseudo_palette is wrong and causes the display to show a blue (garbage) vertical line on every other pixel column Signed-off-by: Jon Ringle Signed-off-by: Tomi Valkeinen --- drivers/video/da8xx-fb.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 0c0ba920ea48..6b23508ff0a5 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -663,15 +663,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, (green << info->var.green.offset) | (blue << info->var.blue.offset); - switch (info->var.bits_per_pixel) { - case 16: - ((u16 *) (info->pseudo_palette))[regno] = v; - break; - case 24: - case 32: - ((u32 *) (info->pseudo_palette))[regno] = v; - break; - } + ((u32 *) (info->pseudo_palette))[regno] = v; if (palette[0] != 0x4000) { update_hw = 1; palette[0] = 0x4000; -- GitLab From d0e224f9963b79610850b2a10622182176658022 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Feb 2014 11:36:22 +0200 Subject: [PATCH 193/797] OMAPDSS: fix rounding when calculating fclk rate "clk: divider: fix rate calculation for fractional rates" patch (and similar for TI specific divider) fixes the clk-divider's rounding. This patch updates the DSS driver to round the rates accordingly. This fixes the DSS's warnings about clock rate mismatch, and also fixes the wrong fclk rate being set. Signed-off-by: Tomi Valkeinen Tested-by: Christoph Fritz Tested-by: Marek Belisko --- drivers/video/omap2/dss/dss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 825c019ddee7..d55266c0e029 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -457,7 +457,7 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min, fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul); for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { - fck = prate / fckd * m; + fck = DIV_ROUND_UP(prate, fckd) * m; if (func(fck, data)) return true; @@ -506,7 +506,7 @@ static int dss_setup_default_clock(void) fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, max_dss_fck); - fck = prate / fck_div * dss.feat->dss_fck_multiplier; + fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier; } r = dss_set_fck_rate(fck); -- GitLab From 25e475e11d8acff1b7c2febbf1d170e95033ba2e Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 20 Mar 2014 10:58:31 +0400 Subject: [PATCH 194/797] video: imxfb: Select LCD_CLASS_DEVICE unconditionally FB driver uses lowlevel controls for LCD powering and contrast changing. Since LCD class cannot be used as an optional feature and should be compiled for using in the driver, this patch selects LCD_CLASS_DEVICE symbol for the driver. Signed-off-by: Alexander Shiyan Signed-off-by: Tomi Valkeinen --- drivers/video/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6c793bc683d9..3ad7ebe2a96d 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -359,6 +359,8 @@ config FB_SA1100 config FB_IMX tristate "Freescale i.MX1/21/25/27 LCD support" depends on FB && ARCH_MXC + select BACKLIGHT_LCD_SUPPORT + select LCD_CLASS_DEVICE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT -- GitLab From 0925afc9a4851c2592f1d45a17aeb7e1ffe188b7 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 11 Apr 2014 13:49:55 +0300 Subject: [PATCH 195/797] OMAPDSS: fix shared irq handlers DSS uses shared irq handlers for DISPC and DSI, because on OMAP3, the DISPC and DSI share the same irq line. However, the irq handlers presume that the hardware is enabled, which, in theory, may not be the case with shared irq handlers. So if an interrupt happens while the DISPC/DSI is off, the kernel will halt as the irq handler tries to access the DISPC/DSI registers. In practice that should never happen, as both DSI and DISPC are in the same power domain. So if there's an IRQ for one of them, the other is also enabled. However, if CONFIG_DEBUG_SHIRQ is enabled, the kernel will generate a spurious IRQ, which then causes the problem. This patch adds an is_enabled field for both DISPC and DSI, which is used to track if the HW is enabled. For DISPC the code is slightly more complex, as the users of DISPC can register the interrupt handler, and we want to hide the is_enabled handling from the users of DISPC. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 55 ++++++++++++++++++++++++++++----- drivers/video/omap2/dss/dsi.c | 20 ++++++++++++ 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 2bbdb7ff7daf..b37e3fbf60cc 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -101,6 +101,8 @@ static struct { void __iomem *base; int irq; + irq_handler_t user_handler; + void *user_data; unsigned long core_clk_rate; unsigned long tv_pclk_rate; @@ -113,6 +115,8 @@ static struct { u32 ctx[DISPC_SZ_REGS / sizeof(u32)]; const struct dispc_features *feat; + + bool is_enabled; } dispc; enum omap_color_component { @@ -3669,16 +3673,44 @@ static int __init dispc_init_features(struct platform_device *pdev) return 0; } +static irqreturn_t dispc_irq_handler(int irq, void *arg) +{ + if (!dispc.is_enabled) + return IRQ_NONE; + + return dispc.user_handler(irq, dispc.user_data); +} + int dispc_request_irq(irq_handler_t handler, void *dev_id) { - return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler, - IRQF_SHARED, "OMAP DISPC", dev_id); + int r; + + if (dispc.user_handler != NULL) + return -EBUSY; + + dispc.user_handler = handler; + dispc.user_data = dev_id; + + /* ensure the dispc_irq_handler sees the values above */ + smp_wmb(); + + r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler, + IRQF_SHARED, "OMAP DISPC", &dispc); + if (r) { + dispc.user_handler = NULL; + dispc.user_data = NULL; + } + + return r; } EXPORT_SYMBOL(dispc_request_irq); void dispc_free_irq(void *dev_id) { - devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id); + devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc); + + dispc.user_handler = NULL; + dispc.user_data = NULL; } EXPORT_SYMBOL(dispc_free_irq); @@ -3750,6 +3782,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev) static int dispc_runtime_suspend(struct device *dev) { + dispc.is_enabled = false; + /* ensure the dispc_irq_handler sees the is_enabled value */ + smp_wmb(); + /* wait for current handler to finish before turning the DISPC off */ + synchronize_irq(dispc.irq); + dispc_save_context(); return 0; @@ -3763,12 +3801,15 @@ static int dispc_runtime_resume(struct device *dev) * _omap_dispc_initial_config(). We can thus use it to detect if * we have lost register context. */ - if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY) - return 0; + if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) { + _omap_dispc_initial_config(); - _omap_dispc_initial_config(); + dispc_restore_context(); + } - dispc_restore_context(); + dispc.is_enabled = true; + /* ensure the dispc_irq_handler sees the is_enabled value */ + smp_wmb(); return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 121d1049d0bc..8be9b04d8849 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -297,6 +297,8 @@ struct dsi_data { int irq; + bool is_enabled; + struct clk *dss_clk; struct clk *sys_clk; @@ -795,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg) dsidev = (struct platform_device *) arg; dsi = dsi_get_dsidrv_data(dsidev); + if (!dsi->is_enabled) + return IRQ_NONE; + spin_lock(&dsi->irq_lock); irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); @@ -5671,6 +5676,15 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) static int dsi_runtime_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); + struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); + + dsi->is_enabled = false; + /* ensure the irq handler sees the is_enabled value */ + smp_wmb(); + /* wait for current handler to finish before turning the DSI off */ + synchronize_irq(dsi->irq); + dispc_runtime_put(); return 0; @@ -5678,12 +5692,18 @@ static int dsi_runtime_suspend(struct device *dev) static int dsi_runtime_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); + struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); int r; r = dispc_runtime_get(); if (r) return r; + dsi->is_enabled = true; + /* ensure the irq handler sees the is_enabled value */ + smp_wmb(); + return 0; } -- GitLab From 5e0c1879919195b79a0b19feda9aafcb7a3e77e7 Mon Sep 17 00:00:00 2001 From: "Li, Zhen-Hua" Date: Mon, 14 Apr 2014 17:41:32 +0800 Subject: [PATCH 196/797] ALSA: es18xx driver should use udelay error udelay with more than 20000 may cause __bad_udelay. Use mdelay for instead. [fixed a typo spotted by Clemens -- tiwai] Signed-off-by: Li, Zhen-Hua Signed-off-by: Takashi Iwai --- sound/isa/es18xx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 1c16830af3d8..6faaac60161a 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c @@ -520,7 +520,7 @@ static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, snd_es18xx_mixer_write(chip, 0x78, 0x93); #ifdef AVOID_POPS /* Avoid pops */ - udelay(100000); + mdelay(100); if (chip->caps & ES18XX_PCM2) /* Restore Audio 2 volume */ snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol); @@ -537,7 +537,7 @@ static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip, /* Stop DMA */ snd_es18xx_mixer_write(chip, 0x78, 0x00); #ifdef AVOID_POPS - udelay(25000); + mdelay(25); if (chip->caps & ES18XX_PCM2) /* Set Audio 2 volume to 0 */ snd_es18xx_mixer_write(chip, 0x7C, 0); @@ -596,7 +596,7 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream) snd_es18xx_write(chip, 0xA5, count >> 8); #ifdef AVOID_POPS - udelay(100000); + mdelay(100); #endif /* Set format */ @@ -691,7 +691,7 @@ static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, snd_es18xx_write(chip, 0xB8, 0x05); #ifdef AVOID_POPS /* Avoid pops */ - udelay(100000); + mdelay(100); /* Enable Audio 1 */ snd_es18xx_dsp_command(chip, 0xD1); #endif @@ -705,7 +705,7 @@ static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip, snd_es18xx_write(chip, 0xB8, 0x00); #ifdef AVOID_POPS /* Avoid pops */ - udelay(25000); + mdelay(25); /* Disable Audio 1 */ snd_es18xx_dsp_command(chip, 0xD3); #endif -- GitLab From a57a22c817fbcb69d41ae517e02933618482f42d Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 11 Apr 2014 16:25:07 +0300 Subject: [PATCH 197/797] OMAPDSS: Take pixelclock unit change into account in hdmi_compute_acr() Pixelclock unit change from kHz to Hz should be taken into account in CTS value calculations in hdmi_compute_acr(). Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi_common.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/omap2/dss/hdmi_common.c index b11afac8e068..0b12a3f62fe1 100644 --- a/drivers/video/omap2/dss/hdmi_common.c +++ b/drivers/video/omap2/dss/hdmi_common.c @@ -347,17 +347,17 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) case 96000: case 192000: if (deep_color == 125) - if (pclk == 27027 || pclk == 74250) + if (pclk == 27027000 || pclk == 74250000) deep_color_correct = true; if (deep_color == 150) - if (pclk == 27027) + if (pclk == 27027000) deep_color_correct = true; break; case 44100: case 88200: case 176400: if (deep_color == 125) - if (pclk == 27027) + if (pclk == 27027000) deep_color_correct = true; break; default: @@ -418,7 +418,7 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) } } /* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ - *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); + *cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10); return 0; } -- GitLab From 5c348ba96cdfd2db6a254de259b54cc20fa7d78a Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Fri, 11 Apr 2014 16:25:06 +0300 Subject: [PATCH 198/797] OMAPDSS: Change struct reg_field to dispc_reg_field Avoid colision with regmap's struct reg_field definition by renaming omapdss's struct reg_field to dispc_reg_field, and moving it inside dispc.c as that's the only place it is used. Signed-off-by: Jyri Sarha Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 12 +++++++++--- drivers/video/omap2/dss/dss.h | 6 ------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b37e3fbf60cc..f18397c33e8f 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -145,12 +145,18 @@ enum mgr_reg_fields { DISPC_MGR_FLD_NUM, }; +struct dispc_reg_field { + u16 reg; + u8 high; + u8 low; +}; + static const struct { const char *name; u32 vsync_irq; u32 framedone_irq; u32 sync_lost_irq; - struct reg_field reg_desc[DISPC_MGR_FLD_NUM]; + struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM]; } mgr_desc[] = { [OMAP_DSS_CHANNEL_LCD] = { .name = "LCD", @@ -242,13 +248,13 @@ static inline u32 dispc_read_reg(const u16 idx) static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld) { - const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; + const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld]; return REG_GET(rfld.reg, rfld.high, rfld.low); } static void mgr_fld_write(enum omap_channel channel, enum mgr_reg_fields regfld, int val) { - const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; + const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld]; REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low); } diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 918fec182424..560078fcb198 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -131,12 +131,6 @@ struct dsi_clock_info { u16 lp_clk_div; }; -struct reg_field { - u16 reg; - u8 high; - u8 low; -}; - struct dss_lcd_mgr_config { enum dss_io_pad_mode io_pad_mode; -- GitLab From 30f78d8ebf7f514801e71b88a10c948275168518 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Thu, 10 Apr 2014 21:23:36 -0700 Subject: [PATCH 199/797] ipv6: Limit mtu to 65575 bytes Francois reported that setting big mtu on loopback device could prevent tcp sessions making progress. We do not support (yet ?) IPv6 Jumbograms and cook corrupted packets. We must limit the IPv6 MTU to (65535 + 40) bytes in theory. Tested: ifconfig lo mtu 70000 netperf -H ::1 Before patch : Throughput : 0.05 Mbits After patch : Throughput : 35484 Mbits Reported-by: Francois WELLENREITER Signed-off-by: Eric Dumazet Acked-by: YOSHIFUJI Hideaki Acked-by: Hannes Frederic Sowa Signed-off-by: David S. Miller --- include/net/ip6_route.h | 5 +++++ net/ipv6/route.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 3c3bb184eb8f..6c4f5eac98e7 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -32,6 +32,11 @@ struct route_info { #define RT6_LOOKUP_F_SRCPREF_PUBLIC 0x00000010 #define RT6_LOOKUP_F_SRCPREF_COA 0x00000020 +/* We do not (yet ?) support IPv6 jumbograms (RFC 2675) + * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header + */ +#define IP6_MAX_MTU (0xFFFF + sizeof(struct ipv6hdr)) + /* * rt6_srcprefs2flags() and rt6_flags2srcprefs() translate * between IPV6_ADDR_PREFERENCES socket option values diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5015c50a5ba7..5ea462eacd9f 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1338,7 +1338,7 @@ static unsigned int ip6_mtu(const struct dst_entry *dst) unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); if (mtu) - return mtu; + goto out; mtu = IPV6_MIN_MTU; @@ -1348,7 +1348,8 @@ static unsigned int ip6_mtu(const struct dst_entry *dst) mtu = idev->cnf.mtu6; rcu_read_unlock(); - return mtu; +out: + return min_t(unsigned int, mtu, IP6_MAX_MTU); } static struct dst_entry *icmp6_dst_gc_list; -- GitLab From 77d149c4eb8964b6bd4a929b102a867505add612 Mon Sep 17 00:00:00 2001 From: Daniel J Blueman Date: Fri, 11 Apr 2014 16:14:26 +0800 Subject: [PATCH 200/797] bnx2: Don't build unused suspend/resume functions not enabled When CONFIG_PM_SLEEP isn't enabled, bnx2_suspend/resume are unused; don't build them when they aren't used. Signed-off-by: Daniel J Blueman Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index a8efb18e42fa..0ab83708b6a1 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -8627,6 +8627,7 @@ bnx2_remove_one(struct pci_dev *pdev) pci_disable_device(pdev); } +#ifdef CONFIG_PM_SLEEP static int bnx2_suspend(struct device *device) { @@ -8665,7 +8666,6 @@ bnx2_resume(struct device *device) return 0; } -#ifdef CONFIG_PM_SLEEP static SIMPLE_DEV_PM_OPS(bnx2_pm_ops, bnx2_suspend, bnx2_resume); #define BNX2_PM_OPS (&bnx2_pm_ops) -- GitLab From cc253d7cebb9a1b43f47409acd8b7942e125ea61 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 24 Oct 2013 22:40:19 +0200 Subject: [PATCH 201/797] of: add vendor prefix for ISEE 2007 S.L. This trivial patch adds ISEE 2007 S.L. to the list of devicetree vendor prefixes. Acked-by: Kumar Gala Signed-off-by: Javier Martinez Canillas 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 0f01c9bf19c8..04eed97e45c5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -58,6 +58,7 @@ idt Integrated Device Technologies, Inc. img Imagination Technologies Ltd. intel Intel Corporation intercontrol Inter Control Group +isee ISEE 2007 S.L. isl Intersil karo Ka-Ro electronics GmbH lacie LaCie -- GitLab From a438311b715b76d9683a6d0dfccea6603b08083f Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Thu, 3 Apr 2014 10:33:49 +0200 Subject: [PATCH 202/797] of: add vendor prefix for I2SE GmbH Add i2se to the list of DT vendor prefixes. 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 04eed97e45c5..233a4957fd18 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -53,6 +53,7 @@ haoyu Haoyu Microelectronic Co. Ltd. hisilicon Hisilicon Limited. honeywell Honeywell hp Hewlett Packard +i2se I2SE GmbH ibm International Business Machines (IBM) idt Integrated Device Technologies, Inc. img Imagination Technologies Ltd. -- GitLab From e7d2e3af864cf1ac2548b8f3deb2956395a8abd3 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Wed, 2 Apr 2014 21:52:07 -0500 Subject: [PATCH 203/797] dt-bindings: add vendor-prefix for Newhaven Display Newhaven Display provides the worldwide marketplace with cost effective high quality display devices ranging from OLED and LCD Displays to VFD Displays. Signed-off-by: Dinh Nguyen Reviewed-by: Pavel Machek 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 233a4957fd18..5cfb6c102fcc 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -75,6 +75,7 @@ moxa Moxa national National Semiconductor neonode Neonode Inc. netgear NETGEAR +newhaven Newhaven Display International nintendo Nintendo nokia Nokia nvidia NVIDIA -- GitLab From 401a97d2c0f20a0b6cfe6d035b638fe2b6e8e97c Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:45:57 +0100 Subject: [PATCH 204/797] DT: bindings: add missing Marvell Kirkwood SoC documentation Marvell Kirkwood SoC binding have not yet been documented. Add the documentation including the supported SoCs and boards. Signed-off-by: Andrew Lunn Acked-by: Jason Cooper Signed-off-by: Rob Herring --- .../bindings/arm/marvell,kirkwood.txt | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Documentation/devicetree/bindings/arm/marvell,kirkwood.txt diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt new file mode 100644 index 000000000000..925ecbf6e7b7 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt @@ -0,0 +1,97 @@ +Marvell Kirkwood SoC Family Device Tree Bindings +------------------------------------------------ + +Boards with a SoC of the Marvell Kirkwook family, eg 88f6281 + +* Required root node properties: +compatible: must contain "marvell,kirkwood" + +In addition, the above compatible shall be extended with the specific +SoC. Currently known SoC compatibles are: + +"marvell,kirkwood-88f6192" +"marvell,kirkwood-88f6281" +"marvell,kirkwood-88f6282" +"marvell,kirkwood-88f6283" +"marvell,kirkwood-88f6702" +"marvell,kirkwood-98DX4122" + +And in addition, the compatible shall be extended with the specific +board. Currently known boards are: + +"buffalo,lschlv2" +"buffalo,lsxhl" +"buffalo,lsxl" +"dlink,dns-320" +"dlink,dns-320-a1" +"dlink,dns-325" +"dlink,dns-325-a1" +"dlink,dns-kirkwood" +"excito,b3" +"globalscale,dreamplug-003-ds2001" +"globalscale,guruplug" +"globalscale,guruplug-server-plus" +"globalscale,sheevaplug" +"globalscale,sheevaplug" +"globalscale,sheevaplug-esata" +"globalscale,sheevaplug-esata-rev13" +"iom,iconnect" +"iom,iconnect-1.1" +"iom,ix2-200" +"keymile,km_kirkwood" +"lacie,cloudbox" +"lacie,inetspace_v2" +"lacie,laplug" +"lacie,netspace_lite_v2" +"lacie,netspace_max_v2" +"lacie,netspace_mini_v2" +"lacie,netspace_v2" +"marvell,db-88f6281-bp" +"marvell,db-88f6282-bp" +"marvell,mv88f6281gtw-ge" +"marvell,rd88f6281" +"marvell,rd88f6281" +"marvell,rd88f6281-a0" +"marvell,rd88f6281-a1" +"mpl,cec4" +"mpl,cec4-10" +"netgear,readynas" +"netgear,readynas" +"netgear,readynas-duo-v2" +"netgear,readynas-nv+-v2" +"plathome,openblocks-a6" +"plathome,openblocks-a7" +"raidsonic,ib-nas6210" +"raidsonic,ib-nas6210-b" +"raidsonic,ib-nas6220" +"raidsonic,ib-nas6220-b" +"raidsonic,ib-nas62x0" +"seagate,dockstar" +"seagate,goflexnet" +"synology,ds109" +"synology,ds110jv10" +"synology,ds110jv20" +"synology,ds110jv30" +"synology,ds111" +"synology,ds209" +"synology,ds210jv10" +"synology,ds210jv20" +"synology,ds212" +"synology,ds212jv10" +"synology,ds212jv20" +"synology,ds212pv10" +"synology,ds409" +"synology,ds409slim" +"synology,ds410j" +"synology,ds411" +"synology,ds411j" +"synology,ds411slim" +"synology,ds413jv10" +"synology,rs212" +"synology,rs409" +"synology,rs411" +"synology,rs812" +"usi,topkick" +"usi,topkick-1281P2" +"zyxel,nsa310" +"zyxel,nsa310a" -- GitLab From e1a5ddc5069a0c7589a139e0422200672d965581 Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Mon, 14 Apr 2014 11:17:22 +0300 Subject: [PATCH 205/797] net/mlx4_core: Defer VF initialization till PF is fully initialized Fix in commit [1] is not sufficient since a deferred VF initialization could happen after pci_enable_sriov() is finished, but before the PF is fully initialized. Need to prevent VFs from initializing till the PF is fully ready and comm channel is operational. [1] - 9798935 "net/mlx4_core: mlx4_init_slave() shouldn't access comm channel before PF is ready" CC: Stuart Hayes Signed-off-by: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 4b86c7af2a7a..cef267e24f9c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -2369,10 +2369,10 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) } else { atomic_inc(&pf_loading); err = pci_enable_sriov(pdev, total_vfs); - atomic_dec(&pf_loading); if (err) { mlx4_err(dev, "Failed to enable SR-IOV, continuing without SR-IOV (err = %d).\n", err); + atomic_dec(&pf_loading); err = 0; } else { mlx4_warn(dev, "Running in master mode\n"); @@ -2532,6 +2532,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) priv->removed = 0; + if (mlx4_is_master(dev) && dev->num_vfs) + atomic_dec(&pf_loading); + return 0; err_port: @@ -2582,6 +2585,9 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data) if (!mlx4_is_slave(dev)) mlx4_free_ownership(dev); + if (mlx4_is_master(dev) && dev->num_vfs) + atomic_dec(&pf_loading); + kfree(priv->dev.dev_vfs); err_free_dev: @@ -2675,6 +2681,7 @@ static void __mlx4_remove_one(struct pci_dev *pdev) if (dev->flags & MLX4_FLAG_SRIOV) { mlx4_warn(dev, "Disabling SR-IOV\n"); pci_disable_sriov(pdev); + dev->num_vfs = 0; } if (!mlx4_is_slave(dev)) -- GitLab From 552481aace37a3698a2389bba04ae43fc969803b Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:45:56 +0100 Subject: [PATCH 206/797] DT: Vendor: Add prefixes used by Kirkwood devices Add a number of vendor prefixes by kirkwood devices. These are not all stock tickers, but have been in use for a while so changing would not be easy. Signed-off-by: Andrew Lunn Acked-by: Jason Cooper Signed-off-by: Rob Herring --- .../devicetree/bindings/vendor-prefixes.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 5cfb6c102fcc..36b8530718db 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -22,6 +22,7 @@ auo AU Optronics Corporation avago Avago Technologies bosch Bosch Sensortec GmbH brcm Broadcom Corporation +buffalo Buffalo, Inc. calxeda Calxeda capella Capella Microsystems, Inc cavium Cavium, Inc. @@ -33,8 +34,8 @@ cortina Cortina Systems, Inc. crystalfontz Crystalfontz America, Inc. dallas Maxim Integrated Products (formerly Dallas Semiconductor) davicom DAVICOM Semiconductor, Inc. -dlink D-Link Systems, Inc. denx Denx Software Engineering +dlink D-Link Corporation dmo Data Modul AG edt Emerging Display Technologies emmicro EM Microelectronic @@ -42,6 +43,7 @@ epfl Ecole Polytechnique Fédérale de Lausanne epson Seiko Epson Corp. est ESTeem Wireless Modems eukrea Eukréa Electromatique +excito Excito fsl Freescale Semiconductor GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. @@ -56,12 +58,14 @@ hp Hewlett Packard i2se I2SE GmbH ibm International Business Machines (IBM) idt Integrated Device Technologies, Inc. +iom Iomega Corporation img Imagination Technologies Ltd. intel Intel Corporation intercontrol Inter Control Group isee ISEE 2007 S.L. isl Intersil karo Ka-Ro electronics GmbH +keymile Keymile GmbH lacie LaCie lantiq Lantiq Semiconductor lg LG Corporation @@ -72,6 +76,8 @@ maxim Maxim Integrated Products microchip Microchip Technology Inc. mosaixtech Mosaix Technologies, Inc. moxa Moxa +mpl MPL AG +mxicy Macronix International Co., Ltd. national National Semiconductor neonode Neonode Inc. netgear NETGEAR @@ -85,10 +91,12 @@ opencores OpenCores.org panasonic Panasonic Corporation phytec PHYTEC Messtechnik GmbH picochip Picochip Ltd +plathome Plat'Home Co., Ltd. powervr PowerVR (deprecated, use img) qca Qualcomm Atheros, Inc. qcom Qualcomm Technologies, Inc qnap QNAP Systems, Inc. +raidsonic RaidSonic Technology GmbH ralink Mediatek/Ralink Technology Corp. ramtron Ramtron International realtek Realtek Semiconductor Corp. @@ -98,6 +106,7 @@ rockchip Fuzhou Rockchip Electronics Co., Ltd samsung Samsung Semiconductor sbs Smart Battery System schindler Schindler +seagate Seagate Technology PLC sil Silicon Image silabs Silicon Laboratories simtek @@ -114,6 +123,7 @@ ti Texas Instruments tlm Trusted Logic Mobility toshiba Toshiba Corporation toumaz Toumaz +usi Universal Scientifc Industrial Co., Ltd. v3 V3 Semiconductor via VIA Technologies, Inc. voipac Voipac Technologies s.r.o. @@ -122,3 +132,4 @@ wlf Wolfson Microelectronics wm Wondermedia Technologies, Inc. xes Extreme Engineering Solutions (X-ES) xlnx Xilinx +zyxel ZyXEL Communications Corp. -- GitLab From 3443dd19da985da337cd0be20435cc98aa8c7915 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sat, 22 Mar 2014 13:45:59 +0100 Subject: [PATCH 207/797] DT: I2C: Add trivial bindings used by kirkwood boards Add a number of eeproms and temperature sensors/fan controllers used by kirkwood boards. Signed-off-by: Andrew Lunn Acked-by: Jason Cooper Signed-off-by: Rob Herring --- .../devicetree/bindings/i2c/trivial-devices.txt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt index 71724d026ffa..bef86e57c388 100644 --- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt +++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt @@ -13,8 +13,22 @@ ad,ad7414 SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert an ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems adi,adt7461 +/-1C TDM Extended Temp Range I.C adt7461 +/-1C TDM Extended Temp Range I.C +adi,adt7473 +/-1C TDM Extended Temp Range I.C +adi,adt7475 +/-1C TDM Extended Temp Range I.C +adi,adt7476 +/-1C TDM Extended Temp Range I.C +adi,adt7490 +/-1C TDM Extended Temp Range I.C 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 catalyst,24c32 i2c serial eeprom @@ -46,8 +60,10 @@ maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface mc,rv3029c2 Real Time Clock Module with I2C-Bus +national,lm63 Temperature sensor with integrated fan control national,lm75 I2C TEMP SENSOR national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor +national,lm85 Temperature sensor with integrated fan control national,lm92 ±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface nuvoton,npct501 i2c trusted platform module (TPM) nxp,pca9556 Octal SMBus and I2C registered interface -- GitLab From 42dc102dc3c026267dc2100c27f9e4d5283c3644 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 3 Apr 2014 19:01:35 +0400 Subject: [PATCH 208/797] of: Add vendor prefix for Digi International Inc. Using "digi" for Digi International Inc. Additionally, this patch keep "dlink" entry sorted alphabetically. Signed-off-by: Alexander Shiyan 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 36b8530718db..fad44cab68b8 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -35,6 +35,7 @@ crystalfontz Crystalfontz America, Inc. dallas Maxim Integrated Products (formerly Dallas Semiconductor) davicom DAVICOM Semiconductor, Inc. denx Denx Software Engineering +digi Digi International Inc. dlink D-Link Corporation dmo Data Modul AG edt Emerging Display Technologies -- GitLab From 5b6241185e2cded07ca3f5f646b55c641928ba4e Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Tue, 8 Apr 2014 13:48:07 +0800 Subject: [PATCH 209/797] of: Fix the section mismatch warnings. In tag next-20140407, building with CONFIG_DEBUG_SECTION_MISMATCH enabled, the following WARNING is occured: WARNING: drivers/built-in.o(.text.unlikely+0x2220): Section mismatch in reference from the function __reserved_mem_check_root() to the function .init.text:of_get_flat_dt_prop() The function __reserved_mem_check_root() references the function __init of_get_flat_dt_prop(). This is often because __reserved_mem_check_root lacks a __init annotation or the annotation of of_get_flat_dt_prop is wrong. WARNING: vmlinux.o(.text.unlikely+0xb9d0): Section mismatch in reference from the function __reserved_mem_check_root() to the (unknown reference) .init.data:(unknown) The function __reserved_mem_check_root() references the (unknown reference) __initdata (unknown). This is often because __reserved_mem_check_root lacks a __initdata annotation or the annotation of (unknown) is wrong. This is cause by : 'drivers: of: add initialization code for dynamic reserved memory'. Signed-off-by: Xiubo Li Signed-off-by: Rob Herring --- drivers/of/fdt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index fa16a912a927..7a2ef7bb8022 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -491,7 +491,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, * in /reserved-memory matches the values supported by the current implementation, * also check if ranges property has been provided */ -static int __reserved_mem_check_root(unsigned long node) +static int __init __reserved_mem_check_root(unsigned long node) { __be32 *prop; -- GitLab From f3afa2259457e46bbb6285bcc1032ecc0f76fdd7 Mon Sep 17 00:00:00 2001 From: Steffen Trumtrar Date: Mon, 31 Mar 2014 17:36:53 +0200 Subject: [PATCH 210/797] DT: add vendor prefix for EBV Elektronik Add vendor prefix for EBV Elektronik. Signed-off-by: Steffen Trumtrar 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 fad44cab68b8..abc308083acb 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -38,6 +38,7 @@ denx Denx Software Engineering digi Digi International Inc. dlink D-Link Corporation dmo Data Modul AG +ebv EBV Elektronik edt Emerging Display Technologies emmicro EM Microelectronic epfl Ecole Polytechnique Fédérale de Lausanne -- GitLab From 1a3d0717f68345730ae939b74b952200fb165f45 Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Mon, 14 Apr 2014 16:12:40 +0530 Subject: [PATCH 211/797] be2net: Fix to reap TX compls till HW doesn't respond for some time be_close() currently waits for a max of 200ms to receive all pending TX compls. This timeout value was roughly calculated based on 10G transmission speeds and the TX queue depth. This timeout may not be enough when the link is operating at lower speeds or in multi-channel/SR-IOV configs with TX-rate limiting setting. It is hard to calculate a "proper timeout value" that works in all configurations. This patch solves this problem by continuing to reap TX completions till the HW is completely silent for a period of 10ms or a HW error is detected. v2: implements the new scheme (as suggested by David Laight) instead of just waiting longer than 200ms for reaping all completions. Signed-off-by: Vasundhara Volam Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 3e6df47b6973..80f754d7cf65 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2033,11 +2033,13 @@ static void be_tx_compl_clean(struct be_adapter *adapter) bool dummy_wrb; int i, pending_txqs; - /* Wait for a max of 200ms for all the tx-completions to arrive. */ + /* Stop polling for compls when HW has been silent for 10ms */ do { pending_txqs = adapter->num_tx_qs; for_all_tx_queues(adapter, txo, i) { + cmpl = 0; + num_wrbs = 0; txq = &txo->q; while ((txcp = be_tx_compl_get(&txo->cq))) { end_idx = @@ -2050,14 +2052,13 @@ static void be_tx_compl_clean(struct be_adapter *adapter) if (cmpl) { be_cq_notify(adapter, txo->cq.id, false, cmpl); atomic_sub(num_wrbs, &txq->used); - cmpl = 0; - num_wrbs = 0; + timeo = 0; } if (atomic_read(&txq->used) == 0) pending_txqs--; } - if (pending_txqs == 0 || ++timeo > 200) + if (pending_txqs == 0 || ++timeo > 10 || be_hw_error(adapter)) break; mdelay(1); -- GitLab From e1ad8e33d2e57ca64d9862b63d986fc296a7b876 Mon Sep 17 00:00:00 2001 From: Kalesh AP Date: Mon, 14 Apr 2014 16:12:41 +0530 Subject: [PATCH 212/797] be2net: Fix invocation of be_close() after be_clear() In the EEH error recovery path, when a permanent failure occurs, we clean up adapter structure (i.e. destroy queues etc) by calling be_clear() and return PCI_ERS_RESULT_DISCONNECT. After this the stack tries to remove device from bus and calls be_remove() which invokes netdev_unregister()->be_close(). be_close() operating on destroyed queues results in a NULL dereference. This patch fixes this problem by introducing a flag to keep track of the setup state. Signed-off-by: Kalesh AP Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 1 + drivers/net/ethernet/emulex/benet/be_main.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 8ccaa2520dc3..97db5a7179df 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -374,6 +374,7 @@ enum vf_state { #define BE_FLAGS_NAPI_ENABLED (1 << 9) #define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11) #define BE_FLAGS_VXLAN_OFFLOADS (1 << 12) +#define BE_FLAGS_SETUP_DONE (1 << 13) #define BE_UC_PMAC_COUNT 30 #define BE_VF_UC_PMAC_COUNT 2 diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 80f754d7cf65..a18645407d21 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -2726,6 +2726,12 @@ static int be_close(struct net_device *netdev) struct be_eq_obj *eqo; int i; + /* This protection is needed as be_close() may be called even when the + * adapter is in cleared state (after eeh perm failure) + */ + if (!(adapter->flags & BE_FLAGS_SETUP_DONE)) + return 0; + be_roce_dev_close(adapter); if (adapter->flags & BE_FLAGS_NAPI_ENABLED) { @@ -3056,6 +3062,7 @@ static int be_clear(struct be_adapter *adapter) be_clear_queues(adapter); be_msix_disable(adapter); + adapter->flags &= ~BE_FLAGS_SETUP_DONE; return 0; } @@ -3560,6 +3567,7 @@ static int be_setup(struct be_adapter *adapter) adapter->phy.fc_autoneg = 1; be_schedule_worker(adapter); + adapter->flags |= BE_FLAGS_SETUP_DONE; return 0; err: be_clear(adapter); -- GitLab From 463518a0cbd396aac83ee3d196897d585e173796 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 14 Apr 2014 10:02:18 -0400 Subject: [PATCH 213/797] qlcnic: Fix panic due to uninitialzed delayed_work struct in use. o AEN event was being received before initializing delayed_work struct and handlers for it. This was resulting in crash. This patch fixes it. Signed-off-by: Sucheta Chakraborty Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index b48737dcd3c5..d211af70c7ec 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -2348,14 +2348,13 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) goto disable_intr; } + INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); + err = qlcnic_83xx_setup_mbx_intr(adapter); if (err) goto disable_mbx_intr; qlcnic_83xx_clear_function_resources(adapter); - - INIT_DELAYED_WORK(&adapter->idc_aen_work, qlcnic_83xx_idc_aen_work); - qlcnic_83xx_initialize_nic(adapter, 1); /* Configure default, SR-IOV or Virtual NIC mode of operation */ -- GitLab From 4d52e1e8d1e198962dcbfabf9c06425c38eb23d0 Mon Sep 17 00:00:00 2001 From: Sucheta Chakraborty Date: Mon, 14 Apr 2014 10:02:19 -0400 Subject: [PATCH 214/797] qlcnic: Fix to send INIT_NIC_FUNC as first mailbox. o INIT_NIC_FUNC should be first mailbox sent. Sending DCB capability and parameter query commands after that command. Signed-off-by: Sucheta Chakraborty Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 2 ++ drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c | 2 -- drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index d211af70c7ec..3ca3118efb3a 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -2355,7 +2355,9 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac) goto disable_mbx_intr; qlcnic_83xx_clear_function_resources(adapter); + qlcnic_dcb_enable(adapter->dcb); qlcnic_83xx_initialize_nic(adapter, 1); + qlcnic_dcb_get_info(adapter->dcb); /* Configure default, SR-IOV or Virtual NIC mode of operation */ err = qlcnic_83xx_configure_opmode(adapter); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 7d4f54912bad..a51fe18f09a8 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c @@ -330,8 +330,6 @@ static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb) goto out_free_cfg; } - qlcnic_dcb_get_info(dcb); - return 0; out_free_cfg: kfree(dcb->cfg); diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 309d05640883..84d011ed7ec2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -2528,8 +2528,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_out_free_hw; } - qlcnic_dcb_enable(adapter->dcb); - if (qlcnic_read_mac_addr(adapter)) dev_warn(&pdev->dev, "failed to read mac addr\n"); @@ -2549,7 +2547,10 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) "Device does not support MSI interrupts\n"); if (qlcnic_82xx_check(adapter)) { + qlcnic_dcb_enable(adapter->dcb); + qlcnic_dcb_get_info(adapter->dcb); err = qlcnic_setup_intr(adapter); + if (err) { dev_err(&pdev->dev, "Failed to setup interrupt\n"); goto err_out_disable_msi; -- GitLab From 7b546842b1e87f5b7929cf15e9cd1ac861b14de3 Mon Sep 17 00:00:00 2001 From: Shahed Shaikh Date: Mon, 14 Apr 2014 10:02:20 -0400 Subject: [PATCH 215/797] qlcnic: Fix max ring count calculation Do not read max rings count from qlcnic_get_nic_info(). Use driver defined values for 82xx adapters. In case of 83xx adapters, use minimum of firmware provided and driver defined values. Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 14 ++++++++------ drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 2 -- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 3ca3118efb3a..ba20c721ee97 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -2139,8 +2139,6 @@ static int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter) ahw->max_mac_filters = nic_info.max_mac_filters; ahw->max_mtu = nic_info.max_mtu; - adapter->max_tx_rings = ahw->max_tx_ques; - adapter->max_sds_rings = ahw->max_rx_ques; /* eSwitch capability indicates vNIC mode. * vNIC and SRIOV are mutually exclusive operational modes. * If SR-IOV capability is detected, SR-IOV physical function @@ -2161,6 +2159,7 @@ static int qlcnic_83xx_get_nic_configuration(struct qlcnic_adapter *adapter) int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) { struct qlcnic_hardware_context *ahw = adapter->ahw; + u16 max_sds_rings, max_tx_rings; int ret; ret = qlcnic_83xx_get_nic_configuration(adapter); @@ -2173,18 +2172,21 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter) if (qlcnic_83xx_config_vnic_opmode(adapter)) return -EIO; - adapter->max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; - adapter->max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS; + max_sds_rings = QLCNIC_MAX_VNIC_SDS_RINGS; + max_tx_rings = QLCNIC_MAX_VNIC_TX_RINGS; } else if (ret == QLC_83XX_DEFAULT_OPMODE) { ahw->nic_mode = QLCNIC_DEFAULT_MODE; adapter->nic_ops->init_driver = qlcnic_83xx_init_default_driver; ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry; - adapter->max_sds_rings = QLCNIC_MAX_SDS_RINGS; - adapter->max_tx_rings = QLCNIC_MAX_TX_RINGS; + max_sds_rings = QLCNIC_MAX_SDS_RINGS; + max_tx_rings = QLCNIC_MAX_TX_RINGS; } else { return -EIO; } + adapter->max_sds_rings = min(ahw->max_rx_ques, max_sds_rings); + adapter->max_tx_rings = min(ahw->max_tx_ques, max_tx_rings); + return 0; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index 64dcbf33d8f0..a81ad5088b07 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -883,8 +883,6 @@ int qlcnic_82xx_get_nic_info(struct qlcnic_adapter *adapter, npar_info->max_rx_ques = le16_to_cpu(nic_info->max_rx_ques); npar_info->capabilities = le32_to_cpu(nic_info->capabilities); npar_info->max_mtu = le16_to_cpu(nic_info->max_mtu); - adapter->max_tx_rings = npar_info->max_tx_ques; - adapter->max_sds_rings = npar_info->max_rx_ques; } qlcnic_free_mbx_args(&cmd); -- GitLab From a78b6da89f52d03997619f5a78a5325bec865977 Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Mon, 14 Apr 2014 10:02:21 -0400 Subject: [PATCH 216/797] qlcnic: Fix PVID configuration on eSwitch port. Clear older PVID before adding a newer PVID to the eSwicth port Signed-off-by: Jitendra Kalsaria Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c index a81ad5088b07..c1e11f5715b0 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c @@ -1354,6 +1354,7 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter, arg2 &= ~BIT_3; break; case QLCNIC_ADD_VLAN: + arg1 &= ~(0x0ffff << 16); arg1 |= (BIT_2 | BIT_5); arg1 |= (esw_cfg->vlan_id << 16); break; -- GitLab From 4f0302277718810494f8c618f28d1edb33af859a Mon Sep 17 00:00:00 2001 From: Jitendra Kalsaria Date: Mon, 14 Apr 2014 10:02:22 -0400 Subject: [PATCH 217/797] qlcnic: Fix QLogic application/driver interface for virtual NIC configuration o Application expect vNIC number as the array index but driver interface return configuration in array index form. o Pack the vNIC information array in the buffer such that application can access it using vNIC number as the array index. Signed-off-by: Jitendra Kalsaria Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 448d156c3d08..cd346e27f2e1 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -354,7 +354,7 @@ int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func) { int i; - for (i = 0; i < adapter->ahw->max_vnic_func; i++) { + for (i = 0; i < adapter->ahw->total_nic_func; i++) { if (adapter->npars[i].pci_func == pci_func) return i; } @@ -720,6 +720,7 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, struct qlcnic_adapter *adapter = dev_get_drvdata(dev); struct qlcnic_npar_func_cfg *np_cfg; struct qlcnic_info nic_info; + u8 pci_func; int i, ret; u32 count; @@ -729,26 +730,28 @@ static ssize_t qlcnic_sysfs_read_npar_config(struct file *file, count = size / sizeof(struct qlcnic_npar_func_cfg); for (i = 0; i < adapter->ahw->total_nic_func; i++) { - if (qlcnic_is_valid_nic_func(adapter, i) < 0) - continue; if (adapter->npars[i].pci_func >= count) { dev_dbg(dev, "%s: Total nic functions[%d], App sent function count[%d]\n", __func__, adapter->ahw->total_nic_func, count); continue; } - ret = qlcnic_get_nic_info(adapter, &nic_info, i); - if (ret) - return ret; if (!adapter->npars[i].eswitch_status) continue; - np_cfg[i].pci_func = i; - np_cfg[i].op_mode = (u8)nic_info.op_mode; - np_cfg[i].port_num = nic_info.phys_port; - np_cfg[i].fw_capab = nic_info.capabilities; - np_cfg[i].min_bw = nic_info.min_tx_bw; - np_cfg[i].max_bw = nic_info.max_tx_bw; - np_cfg[i].max_tx_queues = nic_info.max_tx_ques; - np_cfg[i].max_rx_queues = nic_info.max_rx_ques; + pci_func = adapter->npars[i].pci_func; + if (qlcnic_is_valid_nic_func(adapter, pci_func) < 0) + continue; + ret = qlcnic_get_nic_info(adapter, &nic_info, pci_func); + if (ret) + return ret; + + np_cfg[pci_func].pci_func = pci_func; + np_cfg[pci_func].op_mode = (u8)nic_info.op_mode; + np_cfg[pci_func].port_num = nic_info.phys_port; + np_cfg[pci_func].fw_capab = nic_info.capabilities; + np_cfg[pci_func].min_bw = nic_info.min_tx_bw; + np_cfg[pci_func].max_bw = nic_info.max_tx_bw; + np_cfg[pci_func].max_tx_queues = nic_info.max_tx_ques; + np_cfg[pci_func].max_rx_queues = nic_info.max_rx_ques; } return size; } -- GitLab From 696f1943a1538bb448c5bf55a18793ad410da00b Mon Sep 17 00:00:00 2001 From: Manish Chopra Date: Mon, 14 Apr 2014 10:02:23 -0400 Subject: [PATCH 218/797] qlcnic: Do not disable SR-IOV when VFs are assigned to VMs o While disabling SR-IOV when VFs are assigned to VMs causes host crash so return -EPERM when user request to disable SR-IOV using pci sysfs in case of VFs are assigned to VMs. Signed-off-by: Manish Chopra Signed-off-by: Shahed Shaikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 14f748cbf0de..280137991544 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -461,6 +461,16 @@ static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter) { struct net_device *netdev = adapter->netdev; + if (pci_vfs_assigned(adapter->pdev)) { + netdev_err(adapter->netdev, + "SR-IOV VFs belonging to port %d are assigned to VMs. SR-IOV can not be disabled on this port\n", + adapter->portnum); + netdev_info(adapter->netdev, + "Please detach SR-IOV VFs belonging to port %d from VMs, and then try to disable SR-IOV on this port\n", + adapter->portnum); + return -EPERM; + } + rtnl_lock(); if (netif_running(netdev)) __qlcnic_down(adapter, netdev); -- GitLab From 151eea367c720db8a0768caf47894c32991aa02a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 14 Apr 2014 18:01:47 +0200 Subject: [PATCH 219/797] pata_arasan_cf: fix ata_host_activate() failure handling Add missing cf_exit() and clk_put() calls to ata_host_activate() failure path. Cc: Viresh Kumar Cc: Shiraz Hashim Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Viresh Kumar Signed-off-by: Tejun Heo --- drivers/ata/pata_arasan_cf.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 6fac524c2f50..4edb1a81f63f 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -898,9 +898,12 @@ static int arasan_cf_probe(struct platform_device *pdev) cf_card_detect(acdev, 0); - return ata_host_activate(host, acdev->irq, irq_handler, 0, - &arasan_cf_sht); + ret = ata_host_activate(host, acdev->irq, irq_handler, 0, + &arasan_cf_sht); + if (!ret) + return 0; + cf_exit(acdev); free_clk: clk_put(acdev->clk); return ret; -- GitLab From 0040e606e35a0db80fc3fac04ccc7c7176a8e2b1 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Sat, 12 Apr 2014 13:33:13 +0200 Subject: [PATCH 220/797] btrfs: fix use-after-free in mount_subvol() Pointer 'newargs' is used after the memory that it points to has already been freed. Picked up by Coverity - CID 1201425. Fixes: 0723a0473f ("btrfs: allow mounting btrfs subvolumes with different ro/rw options") Signed-off-by: Christoph Jaeger Signed-off-by: Chris Mason --- fs/btrfs/super.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 994c40955315..53bc3733d483 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1186,7 +1186,6 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags, return ERR_PTR(-ENOMEM); mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, newargs); - kfree(newargs); if (PTR_RET(mnt) == -EBUSY) { if (flags & MS_RDONLY) { @@ -1196,17 +1195,22 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags, int r; mnt = vfs_kern_mount(&btrfs_fs_type, flags | MS_RDONLY, device_name, newargs); - if (IS_ERR(mnt)) + if (IS_ERR(mnt)) { + kfree(newargs); return ERR_CAST(mnt); + } r = btrfs_remount(mnt->mnt_sb, &flags, NULL); if (r < 0) { /* FIXME: release vfsmount mnt ??*/ + kfree(newargs); return ERR_PTR(r); } } } + kfree(newargs); + if (IS_ERR(mnt)) return ERR_CAST(mnt); -- GitLab From af64dc7474a43fb653255ecf8ae879c8227feab2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 6 Apr 2014 15:30:39 +0200 Subject: [PATCH 221/797] rsi: Add missing initialization of ii MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/net/wireless/rsi/rsi_91x_core.c: In function ‘rsi_core_determine_hal_queue’: drivers/net/wireless/rsi/rsi_91x_core.c:91: warning: ‘ii’ may be used uninitialized in this function Signed-off-by: Geert Uytterhoeven Signed-off-by: John W. Linville --- drivers/net/wireless/rsi/rsi_91x_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c index 1a8d32138593..cf61d6e3eaa7 100644 --- a/drivers/net/wireless/rsi/rsi_91x_core.c +++ b/drivers/net/wireless/rsi/rsi_91x_core.c @@ -88,7 +88,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common) bool recontend_queue = false; u32 q_len = 0; u8 q_num = INVALID_QUEUE; - u8 ii, min = 0; + u8 ii = 0, min = 0; if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) { if (!common->mgmt_q_block) -- GitLab From 98ddcbe03366c19b6da9b75a00f9c8d0a7c2dc6d Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Wed, 9 Apr 2014 21:28:54 +0200 Subject: [PATCH 222/797] rsi: Fix a potential memory leak in rsi_set_channel() Fix a potential memory leak in function rsi_set_channel() that is used to program channel changes. The channel check block for the frequency bands directly exits the function in case of an error, thus leaving an already allocated skb unreferenced. Move the checks above allocating the skb. Detected by Coverity: CID 1195576. Signed-off-by: Christian Engelmayer Signed-off-by: John W. Linville --- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index 73694295648f..3a030b9d0fe6 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -841,16 +841,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) rsi_dbg(MGMT_TX_ZONE, "%s: Sending scan req frame\n", __func__); - skb = dev_alloc_skb(FRAME_DESC_SZ); - if (!skb) { - rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", - __func__); - return -ENOMEM; - } - - memset(skb->data, 0, FRAME_DESC_SZ); - mgmt_frame = (struct rsi_mac_frame *)skb->data; - if (common->band == IEEE80211_BAND_5GHZ) { if ((channel >= 36) && (channel <= 64)) channel = ((channel - 32) / 4); @@ -868,6 +858,16 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) } } + skb = dev_alloc_skb(FRAME_DESC_SZ); + if (!skb) { + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", + __func__); + return -ENOMEM; + } + + memset(skb->data, 0, FRAME_DESC_SZ); + mgmt_frame = (struct rsi_mac_frame *)skb->data; + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST); mgmt_frame->desc_word[4] = cpu_to_le16(channel); -- GitLab From 69aa167583a9e6d36ac1957c0bc51136c7a770fa Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Thu, 10 Apr 2014 10:01:37 +0300 Subject: [PATCH 223/797] wlcore: ignore dummy packet events in PLT mode Sometimes the firmware sends a dummy packet event while we are in PLT mode. This doesn't make sense, it's a firmware bug. Fix this by ignoring dummy packet events when we're PLT mode. Reported-by: Yegor Yefremov Reported-by: Arik Nemtsov Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wlcore/event.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 1f9a36031b06..16d10281798d 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -158,6 +158,11 @@ EXPORT_SYMBOL_GPL(wlcore_event_channel_switch); void wlcore_event_dummy_packet(struct wl1271 *wl) { + if (wl->plt) { + wl1271_info("Got DUMMY_PACKET event in PLT mode. FW bug, ignoring."); + return; + } + wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); wl1271_tx_dummy_packet(wl); } -- GitLab From 2004dabaac4104e9aa067e3fe9326d3958b27ca1 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 10 Apr 2014 11:36:38 +0200 Subject: [PATCH 224/797] cw1200: Fix cw1200_debug_link_id This array is used in debug string to display cw1200_link_status defined in drivers/net/wireless/cw1200/cw1200.h. Add missing strings for CW1200_LINK_RESET and CW1200_LINK_RESET_REMAP. Signed-off-by: Frederic Danis Signed-off-by: John W. Linville --- drivers/net/wireless/cw1200/debug.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c index e323b4d54338..34f97c31eecf 100644 --- a/drivers/net/wireless/cw1200/debug.c +++ b/drivers/net/wireless/cw1200/debug.c @@ -41,6 +41,8 @@ static const char * const cw1200_debug_link_id[] = { "REQ", "SOFT", "HARD", + "RESET", + "RESET_REMAP", }; static const char *cw1200_debug_mode(int mode) -- GitLab From 61698b7e222c33e1d38996519b38dd34cbcb8634 Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Thu, 10 Apr 2014 20:37:53 +0200 Subject: [PATCH 225/797] rsi: Fix a potential memory leak in rsi_send_auto_rate_request() Fix a potential memory leak in the error path of function rsi_send_auto_rate_request(). In case memory allocation for array 'selected_rates' fails, the error path exits and leaves the previously allocated skb in place. Detected by Coverity: CID 1195575. Signed-off-by: Christian Engelmayer Signed-off-by: John W. Linville --- drivers/net/wireless/rsi/rsi_91x_mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index 3a030b9d0fe6..1b28cda6ca88 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -966,6 +966,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common) if (!selected_rates) { rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n", __func__); + dev_kfree_skb(skb); return -ENOMEM; } -- GitLab From c0da71ff4d2cbf113465bff9a7c413154be25a89 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Sun, 13 Apr 2014 16:33:51 +0300 Subject: [PATCH 226/797] wl18xx: align event mailbox with current fw Some fields are missing from the event mailbox struct definitions, which cause issues when trying to handle some events. Add the missing fields in order to align the struct size (without adding actual support for the new fields). Reported-and-tested-by: Imre Kaloz Cc: stable@vger.kernel.org # 3.14+ Fixes: 028e724 ("wl18xx: move to new firmware (wl18xx-fw-3.bin)") Signed-off-by: Eliad Peller Signed-off-by: John W. Linville --- drivers/net/wireless/ti/wl18xx/event.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h index 398f3d2c0a6c..a76e98eb8372 100644 --- a/drivers/net/wireless/ti/wl18xx/event.h +++ b/drivers/net/wireless/ti/wl18xx/event.h @@ -68,6 +68,26 @@ struct wl18xx_event_mailbox { /* bitmap of inactive stations (by HLID) */ __le32 inactive_sta_bitmap; + + /* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */ + u8 rx_ba_role_id; + u8 rx_ba_link_id; + u8 rx_ba_win_size; + u8 padding; + + /* smart config */ + u8 sc_ssid_len; + u8 sc_pwd_len; + u8 sc_token_len; + u8 padding1; + u8 sc_ssid[32]; + u8 sc_pwd[32]; + u8 sc_token[32]; + + /* smart config sync channel */ + u8 sc_sync_channel; + u8 sc_sync_band; + u8 padding2[2]; } __packed; int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event, -- GitLab From e8304d04ac88c21b2a68d189f01678d71479a803 Mon Sep 17 00:00:00 2001 From: Steven Miao Date: Sat, 12 Apr 2014 09:23:24 +0800 Subject: [PATCH 227/797] spi: bfin5xx: fix build error should include linux/gpio.h Signed-off-by: Steven Miao Signed-off-by: Mark Brown --- drivers/spi/spi-bfin5xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/spi-bfin5xx.c b/drivers/spi/spi-bfin5xx.c index 55e57c3eb9bd..ebf720b88a2a 100644 --- a/drivers/spi/spi-bfin5xx.c +++ b/drivers/spi/spi-bfin5xx.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include -- GitLab From 818e91625aa17161cd6b39a4d08b77c984f0f485 Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 14 Apr 2014 14:29:57 +0800 Subject: [PATCH 228/797] spi: sirf: correct TXFIFO empty interrupt status bit the old code uses wrong marco - SIRFSOC_SPI_FIFO_FULL is not for FIFO interrupt status, it is for FIFO status. here in the ISR, SIRFSOC_SPI_TXFIFO_EMPTY is the right bit for SPI TXFIFO interrupt status. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 1a77ad52812f..51d7c988d3ae 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -287,8 +287,8 @@ static irqreturn_t spi_sirfsoc_irq(int irq, void *dev_id) sspi->left_rx_word) sspi->rx_word(sspi); - if (spi_stat & (SIRFSOC_SPI_FIFO_EMPTY - | SIRFSOC_SPI_TXFIFO_THD_REACH)) + if (spi_stat & (SIRFSOC_SPI_TXFIFO_EMPTY | + SIRFSOC_SPI_TXFIFO_THD_REACH)) while (!((readl(sspi->base + SIRFSOC_SPI_TXFIFO_STATUS) & SIRFSOC_SPI_FIFO_FULL)) && sspi->left_tx_word) -- GitLab From 625227a4e916fa87f1dd84bde518ef403c3f708a Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 14 Apr 2014 14:29:58 +0800 Subject: [PATCH 229/797] spi: sirf: set SPI controller in RISC IO chipselect mode SPI bitbang supply "chipselect" interface for change chip-select line , in the SiRFSoC SPI controller, we need to enable "SPI_CS_IO_MODE", otherwise, spi_sirfsoc_chipselect() has no effect. now the driver is working is because SPI controller will control CS automatically without SPI_CS_IO_MODE. this patch makes the CS controller really controlled by software. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 51d7c988d3ae..9b30743d816a 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -559,6 +559,11 @@ spi_sirfsoc_setup_transfer(struct spi_device *spi, struct spi_transfer *t) regval &= ~SIRFSOC_SPI_CMD_MODE; sspi->tx_by_cmd = false; } + /* + * set spi controller in RISC chipselect mode, we are controlling CS by + * software BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE. + */ + regval |= SIRFSOC_SPI_CS_IO_MODE; writel(regval, sspi->base + SIRFSOC_SPI_CTRL); if (IS_DMA_VALID(t)) { -- GitLab From 6ee8a2f7d5e78700b6e64799b5e9976b21cfad79 Mon Sep 17 00:00:00 2001 From: Qipan Li Date: Mon, 14 Apr 2014 14:29:59 +0800 Subject: [PATCH 230/797] spi: sirf: make GPIO chipselect function work well orignal GPIO chipslect is not standard because it don't take care to the chipselect signal: BITBANG_CS_ACTIVE and BITBANG_CS_INACTIVE. Signed-off-by: Qipan Li Signed-off-by: Barry Song Signed-off-by: Mark Brown --- drivers/spi/spi-sirf.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-sirf.c b/drivers/spi/spi-sirf.c index 9b30743d816a..67d8909dcf39 100644 --- a/drivers/spi/spi-sirf.c +++ b/drivers/spi/spi-sirf.c @@ -470,7 +470,16 @@ static void spi_sirfsoc_chipselect(struct spi_device *spi, int value) writel(regval, sspi->base + SIRFSOC_SPI_CTRL); } else { int gpio = sspi->chipselect[spi->chip_select]; - gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); + switch (value) { + case BITBANG_CS_ACTIVE: + gpio_direction_output(gpio, + spi->mode & SPI_CS_HIGH ? 1 : 0); + break; + case BITBANG_CS_INACTIVE: + gpio_direction_output(gpio, + spi->mode & SPI_CS_HIGH ? 0 : 1); + break; + } } } -- GitLab From 3dedc5f5b11c567dbe2f31adb5119d1dfb8f51c9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 14 Apr 2014 10:41:36 +0900 Subject: [PATCH 231/797] ARM: shmobile: r8a7778: Use clks as MSTP007 parent According to the documentation the parent clock of MSTP007 should be clks not clkp. Signed-off-by: Simon Horman Acked-by: Laurent Pinchart Signed-off-by: Mark Brown --- arch/arm/mach-shmobile/clock-r8a7778.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index 2009a9bc6356..9989b1b06ffd 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c @@ -170,7 +170,7 @@ static struct clk mstp_clks[MSTP_NR] = { [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */ [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */ [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */ - [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */ + [MSTP007] = SH_CLK_MSTP32(&s_clk, MSTPCR0, 7, 0), /* HSPI */ }; static struct clk_lookup lookups[] = { -- GitLab From 4a4dd7d80e11f62cacf49bd90d9448a218188af7 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 14 Apr 2014 10:41:38 +0900 Subject: [PATCH 232/797] spi: sh-hspi: Do not specifically request shyway_clk clock Rather than requesting the shyway_clk call clk_get with the device and a NULL con_id. This is in keeping with the way that clk_get() is called on other drivers used by Renesas Gen 1 SoCs. And I believe it is compatible with supplying clocks via DT, unlike the current code. It appears to me that the two uses of this driver are the r8a7778 and r8a7779 SoCs. The r8a7779 already has clocks setup to allow this driver to continue to work with this change applied. The r8a7778 has clocks incorrectly setup to allow this driver to continue to work with this change applied. This problem is addressed in "ARM: shmobile: r8a7778: Use clks as MSTP007 parent" which is thus a pre-requisite of this patch. Signed-off-by: Simon Horman Signed-off-by: Mark Brown --- drivers/spi/spi-sh-hspi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 9009456bdf4d..c8e795ef2e13 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c @@ -244,9 +244,9 @@ static int hspi_probe(struct platform_device *pdev) return -ENOMEM; } - clk = clk_get(NULL, "shyway_clk"); + clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { - dev_err(&pdev->dev, "shyway_clk is required\n"); + dev_err(&pdev->dev, "couldn't get clock\n"); ret = -EINVAL; goto error0; } -- GitLab From 2eac7648321f4a08aa4078504d7727af0af7173b Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 14 Apr 2014 21:02:59 +0200 Subject: [PATCH 233/797] seccomp: fix populating a0-a5 syscall args in 32-bit x86 BPF Linus reports that on 32-bit x86 Chromium throws the following seccomp resp. audit log messages: audit: type=1326 audit(1397359304.356:28108): auid=500 uid=500 gid=500 ses=2 subj=unconfined_u:unconfined_r:chrome_sandbox_t:s0-s0:c0.c1023 pid=3677 comm="chrome" exe="/opt/google/chrome/chrome" sig=0 syscall=172 compat=0 ip=0xb2dd9852 code=0x30000 audit: type=1326 audit(1397359304.356:28109): auid=500 uid=500 gid=500 ses=2 subj=unconfined_u:unconfined_r:chrome_sandbox_t:s0-s0:c0.c1023 pid=3677 comm="chrome" exe="/opt/google/chrome/chrome" sig=0 syscall=5 compat=0 ip=0xb2dd9852 code=0x50000 These audit messages are being triggered via audit_seccomp() through __secure_computing() in seccomp mode (BPF) filter with seccomp return codes 0x30000 (== SECCOMP_RET_TRAP) and 0x50000 (== SECCOMP_RET_ERRNO) during filter runtime. Moreover, Linus reports that x86_64 Chromium seems fine. The underlying issue that explains this is that the implementation of populate_seccomp_data() is wrong. Our seccomp data structure sd that is being shared with user ABI is: struct seccomp_data { int nr; __u32 arch; __u64 instruction_pointer; __u64 args[6]; }; Therefore, a simple cast to 'unsigned long *' for storing the value of the syscall argument via syscall_get_arguments() is just wrong as on 32-bit x86 (or any other 32bit arch), it would result in storing a0-a5 at wrong offsets in args[] member, and thus i) could leak stack memory to user space and ii) tampers with the logic of seccomp BPF programs that read out and check for syscall arguments: syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]); Tested on 32-bit x86 with Google Chrome, unfortunately only via remote test machine through slow ssh X forwarding, but it fixes the issue on my side. So fix it up by storing args in type correct variables, gcc is clever and optimizes the copy away in other cases, e.g. x86_64. Fixes: bd4cf0ed331a ("net: filter: rework/optimize internal BPF interpreter's instruction set") Reported-and-bisected-by: Linus Torvalds Signed-off-by: Daniel Borkmann Signed-off-by: Alexei Starovoitov Cc: Linus Torvalds Cc: Eric Paris Cc: James Morris Cc: Kees Cook Signed-off-by: David S. Miller --- kernel/seccomp.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/kernel/seccomp.c b/kernel/seccomp.c index d8d046c0726a..590c37925084 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -69,18 +69,17 @@ static void populate_seccomp_data(struct seccomp_data *sd) { struct task_struct *task = current; struct pt_regs *regs = task_pt_regs(task); + unsigned long args[6]; sd->nr = syscall_get_nr(task, regs); sd->arch = syscall_get_arch(); - - /* Unroll syscall_get_args to help gcc on arm. */ - syscall_get_arguments(task, regs, 0, 1, (unsigned long *) &sd->args[0]); - syscall_get_arguments(task, regs, 1, 1, (unsigned long *) &sd->args[1]); - syscall_get_arguments(task, regs, 2, 1, (unsigned long *) &sd->args[2]); - syscall_get_arguments(task, regs, 3, 1, (unsigned long *) &sd->args[3]); - syscall_get_arguments(task, regs, 4, 1, (unsigned long *) &sd->args[4]); - syscall_get_arguments(task, regs, 5, 1, (unsigned long *) &sd->args[5]); - + syscall_get_arguments(task, regs, 0, 6, args); + sd->args[0] = args[0]; + sd->args[1] = args[1]; + sd->args[2] = args[2]; + sd->args[3] = args[3]; + sd->args[4] = args[4]; + sd->args[5] = args[5]; sd->instruction_pointer = KSTK_EIP(task); } -- GitLab From 8c482cdc358ef931ee02262e0a4ef0f29946aa0c Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 14 Apr 2014 21:20:12 +0200 Subject: [PATCH 234/797] net: filter: seccomp: fix wrong decoding of BPF_S_ANC_SECCOMP_LD_W While reviewing seccomp code, we found that BPF_S_ANC_SECCOMP_LD_W has been wrongly decoded by commit a8fc927780 ("sk-filter: Add ability to get socket filter program (v2)") into the opcode BPF_LD|BPF_B|BPF_ABS although it should have been decoded as BPF_LD|BPF_W|BPF_ABS. In practice, this should not have much side-effect though, as such conversion is/was being done through prctl(2) PR_SET_SECCOMP. Reverse operation PR_GET_SECCOMP will only return the current seccomp mode, but not the filter itself. Since the transition to the new BPF infrastructure, it's also not used anymore, so we can simply remove this as it's unreachable. Fixes: a8fc927780 ("sk-filter: Add ability to get socket filter program (v2)") Signed-off-by: Daniel Borkmann Signed-off-by: Alexei Starovoitov Cc: Pavel Emelyanov Signed-off-by: David S. Miller --- include/linux/filter.h | 1 - net/core/filter.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 262dcbb75ffe..024fd03e5d18 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -220,7 +220,6 @@ enum { BPF_S_ANC_RXHASH, BPF_S_ANC_CPU, BPF_S_ANC_ALU_XOR_X, - BPF_S_ANC_SECCOMP_LD_W, BPF_S_ANC_VLAN_TAG, BPF_S_ANC_VLAN_TAG_PRESENT, BPF_S_ANC_PAY_OFFSET, diff --git a/net/core/filter.c b/net/core/filter.c index 0e0856f5d708..cd58614660cf 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -1743,7 +1743,6 @@ void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) [BPF_S_ANC_RXHASH] = BPF_LD|BPF_B|BPF_ABS, [BPF_S_ANC_CPU] = BPF_LD|BPF_B|BPF_ABS, [BPF_S_ANC_ALU_XOR_X] = BPF_LD|BPF_B|BPF_ABS, - [BPF_S_ANC_SECCOMP_LD_W] = BPF_LD|BPF_B|BPF_ABS, [BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS, [BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS, [BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS, -- GitLab From bfae23249955819a42aa6c23d93708c818eff5c9 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Mon, 14 Apr 2014 14:22:43 -0500 Subject: [PATCH 235/797] cxgb4: Save the correct mac addr for hw-loopback connections in the L2T Hardware needs the local device mac address to support hw loopback for rdma loopback connections. Signed-off-by: Steve Wise Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/l2t.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c index 81e8402a74b4..8a96572fdde0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c @@ -154,7 +154,7 @@ static int write_l2e(struct adapter *adap, struct l2t_entry *e, int sync) req->params = htons(L2T_W_PORT(e->lport) | L2T_W_NOREPLY(!sync)); req->l2t_idx = htons(e->idx); req->vlan = htons(e->vlan); - if (e->neigh) + if (e->neigh && !(e->neigh->dev->flags & IFF_LOOPBACK)) memcpy(e->dmac, e->neigh->ha, sizeof(e->dmac)); memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac)); @@ -394,6 +394,8 @@ struct l2t_entry *cxgb4_l2t_get(struct l2t_data *d, struct neighbour *neigh, if (e) { spin_lock(&e->lock); /* avoid race with t4_l2t_free */ e->state = L2T_STATE_RESOLVING; + if (neigh->dev->flags & IFF_LOOPBACK) + memcpy(e->dmac, physdev->dev_addr, sizeof(e->dmac)); memcpy(e->addr, addr, addr_len); e->ifindex = ifidx; e->hash = hash; -- GitLab From 362d52040c71f6e8d8158be48c812d7729cb8df1 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Mon, 14 Apr 2014 21:45:17 +0200 Subject: [PATCH 236/797] Revert "net: sctp: Fix a_rwnd/rwnd management to reflect real state of the receiver's buffer" This reverts commit ef2820a735f7 ("net: sctp: Fix a_rwnd/rwnd management to reflect real state of the receiver's buffer") as it introduced a serious performance regression on SCTP over IPv4 and IPv6, though a not as dramatic on the latter. Measurements are on 10Gbit/s with ixgbe NICs. Current state: [root@Lab200slot2 ~]# iperf3 --sctp -4 -c 192.168.241.3 -V -l 1452 -t 60 iperf version 3.0.1 (10 January 2014) Linux Lab200slot2 3.14.0 #1 SMP Thu Apr 3 23:18:29 EDT 2014 x86_64 Time: Fri, 11 Apr 2014 17:56:21 GMT Connecting to host 192.168.241.3, port 5201 Cookie: Lab200slot2.1397238981.812898.548918 [ 4] local 192.168.241.2 port 38616 connected to 192.168.241.3 port 5201 Starting Test: protocol: SCTP, 1 streams, 1452 byte blocks, omitting 0 seconds, 60 second test [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.09 sec 20.8 MBytes 161 Mbits/sec [ 4] 1.09-2.13 sec 10.8 MBytes 86.8 Mbits/sec [ 4] 2.13-3.15 sec 3.57 MBytes 29.5 Mbits/sec [ 4] 3.15-4.16 sec 4.33 MBytes 35.7 Mbits/sec [ 4] 4.16-6.21 sec 10.4 MBytes 42.7 Mbits/sec [ 4] 6.21-6.21 sec 0.00 Bytes 0.00 bits/sec [ 4] 6.21-7.35 sec 34.6 MBytes 253 Mbits/sec [ 4] 7.35-11.45 sec 22.0 MBytes 45.0 Mbits/sec [ 4] 11.45-11.45 sec 0.00 Bytes 0.00 bits/sec [ 4] 11.45-11.45 sec 0.00 Bytes 0.00 bits/sec [ 4] 11.45-11.45 sec 0.00 Bytes 0.00 bits/sec [ 4] 11.45-12.51 sec 16.0 MBytes 126 Mbits/sec [ 4] 12.51-13.59 sec 20.3 MBytes 158 Mbits/sec [ 4] 13.59-14.65 sec 13.4 MBytes 107 Mbits/sec [ 4] 14.65-16.79 sec 33.3 MBytes 130 Mbits/sec [ 4] 16.79-16.79 sec 0.00 Bytes 0.00 bits/sec [ 4] 16.79-17.82 sec 5.94 MBytes 48.7 Mbits/sec (etc) [root@Lab200slot2 ~]# iperf3 --sctp -6 -c 2001:db8:0:f101::1 -V -l 1400 -t 60 iperf version 3.0.1 (10 January 2014) Linux Lab200slot2 3.14.0 #1 SMP Thu Apr 3 23:18:29 EDT 2014 x86_64 Time: Fri, 11 Apr 2014 19:08:41 GMT Connecting to host 2001:db8:0:f101::1, port 5201 Cookie: Lab200slot2.1397243321.714295.2b3f7c [ 4] local 2001:db8:0:f101::2 port 55804 connected to 2001:db8:0:f101::1 port 5201 Starting Test: protocol: SCTP, 1 streams, 1400 byte blocks, omitting 0 seconds, 60 second test [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.00 sec 169 MBytes 1.42 Gbits/sec [ 4] 1.00-2.00 sec 201 MBytes 1.69 Gbits/sec [ 4] 2.00-3.00 sec 188 MBytes 1.58 Gbits/sec [ 4] 3.00-4.00 sec 174 MBytes 1.46 Gbits/sec [ 4] 4.00-5.00 sec 165 MBytes 1.39 Gbits/sec [ 4] 5.00-6.00 sec 199 MBytes 1.67 Gbits/sec [ 4] 6.00-7.00 sec 163 MBytes 1.36 Gbits/sec [ 4] 7.00-8.00 sec 174 MBytes 1.46 Gbits/sec [ 4] 8.00-9.00 sec 193 MBytes 1.62 Gbits/sec [ 4] 9.00-10.00 sec 196 MBytes 1.65 Gbits/sec [ 4] 10.00-11.00 sec 157 MBytes 1.31 Gbits/sec [ 4] 11.00-12.00 sec 175 MBytes 1.47 Gbits/sec [ 4] 12.00-13.00 sec 192 MBytes 1.61 Gbits/sec [ 4] 13.00-14.00 sec 199 MBytes 1.67 Gbits/sec (etc) After patch: [root@Lab200slot2 ~]# iperf3 --sctp -4 -c 192.168.240.3 -V -l 1452 -t 60 iperf version 3.0.1 (10 January 2014) Linux Lab200slot2 3.14.0+ #1 SMP Mon Apr 14 12:06:40 EDT 2014 x86_64 Time: Mon, 14 Apr 2014 16:40:48 GMT Connecting to host 192.168.240.3, port 5201 Cookie: Lab200slot2.1397493648.413274.65e131 [ 4] local 192.168.240.2 port 50548 connected to 192.168.240.3 port 5201 Starting Test: protocol: SCTP, 1 streams, 1452 byte blocks, omitting 0 seconds, 60 second test [ ID] Interval Transfer Bandwidth [ 4] 0.00-1.00 sec 240 MBytes 2.02 Gbits/sec [ 4] 1.00-2.00 sec 239 MBytes 2.01 Gbits/sec [ 4] 2.00-3.00 sec 240 MBytes 2.01 Gbits/sec [ 4] 3.00-4.00 sec 239 MBytes 2.00 Gbits/sec [ 4] 4.00-5.00 sec 245 MBytes 2.05 Gbits/sec [ 4] 5.00-6.00 sec 240 MBytes 2.01 Gbits/sec [ 4] 6.00-7.00 sec 240 MBytes 2.02 Gbits/sec [ 4] 7.00-8.00 sec 239 MBytes 2.01 Gbits/sec With the reverted patch applied, the SCTP/IPv4 performance is back to normal on latest upstream for IPv4 and IPv6 and has same throughput as 3.4.2 test kernel, steady and interval reports are smooth again. Fixes: ef2820a735f7 ("net: sctp: Fix a_rwnd/rwnd management to reflect real state of the receiver's buffer") Reported-by: Peter Butler Reported-by: Dongsheng Song Reported-by: Fengguang Wu Tested-by: Peter Butler Signed-off-by: Daniel Borkmann Cc: Matija Glavinic Pecotic Cc: Alexander Sverdlin Cc: Vlad Yasevich Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 14 ++++++- net/sctp/associola.c | 82 ++++++++++++++++++++++++++++++-------- net/sctp/sm_statefuns.c | 2 +- net/sctp/socket.c | 6 +++ net/sctp/ulpevent.c | 8 +--- 5 files changed, 87 insertions(+), 25 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 6ee76c804893..d992ca3145fe 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1653,6 +1653,17 @@ struct sctp_association { /* This is the last advertised value of rwnd over a SACK chunk. */ __u32 a_rwnd; + /* Number of bytes by which the rwnd has slopped. The rwnd is allowed + * to slop over a maximum of the association's frag_point. + */ + __u32 rwnd_over; + + /* Keeps treack of rwnd pressure. This happens when we have + * a window, but not recevie buffer (i.e small packets). This one + * is releases slowly (1 PMTU at a time ). + */ + __u32 rwnd_press; + /* This is the sndbuf size in use for the association. * This corresponds to the sndbuf size for the association, * as specified in the sk->sndbuf. @@ -1881,7 +1892,8 @@ void sctp_assoc_update(struct sctp_association *old, __u32 sctp_association_get_next_tsn(struct sctp_association *); void sctp_assoc_sync_pmtu(struct sock *, struct sctp_association *); -void sctp_assoc_rwnd_update(struct sctp_association *, bool); +void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int); +void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned int); void sctp_assoc_set_primary(struct sctp_association *, struct sctp_transport *); void sctp_assoc_del_nonprimary_peers(struct sctp_association *, diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 4f6d6f9d1274..39579c3e0d14 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -1395,35 +1395,44 @@ static inline bool sctp_peer_needs_update(struct sctp_association *asoc) return false; } -/* Update asoc's rwnd for the approximated state in the buffer, - * and check whether SACK needs to be sent. - */ -void sctp_assoc_rwnd_update(struct sctp_association *asoc, bool update_peer) +/* Increase asoc's rwnd by len and send any window update SACK if needed. */ +void sctp_assoc_rwnd_increase(struct sctp_association *asoc, unsigned int len) { - int rx_count; struct sctp_chunk *sack; struct timer_list *timer; - if (asoc->ep->rcvbuf_policy) - rx_count = atomic_read(&asoc->rmem_alloc); - else - rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); + if (asoc->rwnd_over) { + if (asoc->rwnd_over >= len) { + asoc->rwnd_over -= len; + } else { + asoc->rwnd += (len - asoc->rwnd_over); + asoc->rwnd_over = 0; + } + } else { + asoc->rwnd += len; + } - if ((asoc->base.sk->sk_rcvbuf - rx_count) > 0) - asoc->rwnd = (asoc->base.sk->sk_rcvbuf - rx_count) >> 1; - else - asoc->rwnd = 0; + /* If we had window pressure, start recovering it + * once our rwnd had reached the accumulated pressure + * threshold. The idea is to recover slowly, but up + * to the initial advertised window. + */ + if (asoc->rwnd_press && asoc->rwnd >= asoc->rwnd_press) { + int change = min(asoc->pathmtu, asoc->rwnd_press); + asoc->rwnd += change; + asoc->rwnd_press -= change; + } - pr_debug("%s: asoc:%p rwnd=%u, rx_count=%d, sk_rcvbuf=%d\n", - __func__, asoc, asoc->rwnd, rx_count, - asoc->base.sk->sk_rcvbuf); + pr_debug("%s: asoc:%p rwnd increased by %d to (%u, %u) - %u\n", + __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, + asoc->a_rwnd); /* Send a window update SACK if the rwnd has increased by at least the * minimum of the association's PMTU and half of the receive buffer. * The algorithm used is similar to the one described in * Section 4.2.3.3 of RFC 1122. */ - if (update_peer && sctp_peer_needs_update(asoc)) { + if (sctp_peer_needs_update(asoc)) { asoc->a_rwnd = asoc->rwnd; pr_debug("%s: sending window update SACK- asoc:%p rwnd:%u " @@ -1445,6 +1454,45 @@ void sctp_assoc_rwnd_update(struct sctp_association *asoc, bool update_peer) } } +/* Decrease asoc's rwnd by len. */ +void sctp_assoc_rwnd_decrease(struct sctp_association *asoc, unsigned int len) +{ + int rx_count; + int over = 0; + + if (unlikely(!asoc->rwnd || asoc->rwnd_over)) + pr_debug("%s: association:%p has asoc->rwnd:%u, " + "asoc->rwnd_over:%u!\n", __func__, asoc, + asoc->rwnd, asoc->rwnd_over); + + if (asoc->ep->rcvbuf_policy) + rx_count = atomic_read(&asoc->rmem_alloc); + else + rx_count = atomic_read(&asoc->base.sk->sk_rmem_alloc); + + /* If we've reached or overflowed our receive buffer, announce + * a 0 rwnd if rwnd would still be positive. Store the + * the potential pressure overflow so that the window can be restored + * back to original value. + */ + if (rx_count >= asoc->base.sk->sk_rcvbuf) + over = 1; + + if (asoc->rwnd >= len) { + asoc->rwnd -= len; + if (over) { + asoc->rwnd_press += asoc->rwnd; + asoc->rwnd = 0; + } + } else { + asoc->rwnd_over = len - asoc->rwnd; + asoc->rwnd = 0; + } + + pr_debug("%s: asoc:%p rwnd decreased by %d to (%u, %u, %u)\n", + __func__, asoc, len, asoc->rwnd, asoc->rwnd_over, + asoc->rwnd_press); +} /* Build the bind address list for the association based on info from the * local endpoint and the remote peer. diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 01e002430c85..ae9fbeba40b0 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -6178,7 +6178,7 @@ static int sctp_eat_data(const struct sctp_association *asoc, * PMTU. In cases, such as loopback, this might be a rather * large spill over. */ - if ((!chunk->data_accepted) && (!asoc->rwnd || + if ((!chunk->data_accepted) && (!asoc->rwnd || asoc->rwnd_over || (datalen > asoc->rwnd + asoc->frag_point))) { /* If this is the next TSN, consider reneging to make diff --git a/net/sctp/socket.c b/net/sctp/socket.c index e13519e9df80..ff20e2dbbbc7 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -2115,6 +2115,12 @@ static int sctp_recvmsg(struct kiocb *iocb, struct sock *sk, sctp_skb_pull(skb, copied); skb_queue_head(&sk->sk_receive_queue, skb); + /* When only partial message is copied to the user, increase + * rwnd by that amount. If all the data in the skb is read, + * rwnd is updated when the event is freed. + */ + if (!sctp_ulpevent_is_notification(event)) + sctp_assoc_rwnd_increase(event->asoc, copied); goto out; } else if ((event->msg_flags & MSG_NOTIFICATION) || (event->msg_flags & MSG_EOR)) diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 8d198ae03606..85c64658bd0b 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -989,7 +989,7 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event, skb = sctp_event2skb(event); /* Set the owner and charge rwnd for bytes received. */ sctp_ulpevent_set_owner(event, asoc); - sctp_assoc_rwnd_update(asoc, false); + sctp_assoc_rwnd_decrease(asoc, skb_headlen(skb)); if (!skb->data_len) return; @@ -1011,7 +1011,6 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) { struct sk_buff *skb, *frag; unsigned int len; - struct sctp_association *asoc; /* Current stack structures assume that the rcv buffer is * per socket. For UDP style sockets this is not true as @@ -1036,11 +1035,8 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event) } done: - asoc = event->asoc; - sctp_association_hold(asoc); + sctp_assoc_rwnd_increase(event->asoc, len); sctp_ulpevent_release_owner(event); - sctp_assoc_rwnd_update(asoc, true); - sctp_association_put(asoc); } static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event) -- GitLab From 56d6efc2de5fcf76d3c7b33a7671bc04c53cb0e5 Mon Sep 17 00:00:00 2001 From: Feng Wu Date: Tue, 1 Apr 2014 17:46:33 +0800 Subject: [PATCH 237/797] KVM: Remove SMAP bit from CR4_RESERVED_BITS This patch removes SMAP bit from CR4_RESERVED_BITS. Signed-off-by: Feng Wu Signed-off-by: Marcelo Tosatti --- arch/x86/include/asm/kvm_host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index fcaf9c961265..7de069afb382 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -60,7 +60,7 @@ | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \ | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \ | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \ - | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) + | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE | X86_CR4_SMAP)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) -- GitLab From 97ec8c067d322d32effdc1701760d3babbc5595f Mon Sep 17 00:00:00 2001 From: Feng Wu Date: Tue, 1 Apr 2014 17:46:34 +0800 Subject: [PATCH 238/797] KVM: Add SMAP support when setting CR4 This patch adds SMAP handling logic when setting CR4 for guests Thanks a lot to Paolo Bonzini for his suggestion to use the branchless way to detect SMAP violation. Signed-off-by: Feng Wu Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/cpuid.h | 8 +++++++ arch/x86/kvm/mmu.c | 34 ++++++++++++++++++++++++++--- arch/x86/kvm/mmu.h | 44 +++++++++++++++++++++++++++++++------- arch/x86/kvm/paging_tmpl.h | 2 +- arch/x86/kvm/x86.c | 9 +++++++- 5 files changed, 84 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h index a2a1bb7ed8c1..eeecbed26ac7 100644 --- a/arch/x86/kvm/cpuid.h +++ b/arch/x86/kvm/cpuid.h @@ -48,6 +48,14 @@ static inline bool guest_cpuid_has_smep(struct kvm_vcpu *vcpu) return best && (best->ebx & bit(X86_FEATURE_SMEP)); } +static inline bool guest_cpuid_has_smap(struct kvm_vcpu *vcpu) +{ + struct kvm_cpuid_entry2 *best; + + best = kvm_find_cpuid_entry(vcpu, 7, 0); + return best && (best->ebx & bit(X86_FEATURE_SMAP)); +} + static inline bool guest_cpuid_has_fsgsbase(struct kvm_vcpu *vcpu) { struct kvm_cpuid_entry2 *best; diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index f5704d9e5ddc..084caf3efaf5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3601,20 +3601,27 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu, } } -static void update_permission_bitmask(struct kvm_vcpu *vcpu, +void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, bool ept) { unsigned bit, byte, pfec; u8 map; - bool fault, x, w, u, wf, uf, ff, smep; + bool fault, x, w, u, wf, uf, ff, smapf, cr4_smap, smep, smap = 0; smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); + cr4_smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP); for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) { pfec = byte << 1; map = 0; wf = pfec & PFERR_WRITE_MASK; uf = pfec & PFERR_USER_MASK; ff = pfec & PFERR_FETCH_MASK; + /* + * PFERR_RSVD_MASK bit is set in PFEC if the access is not + * subject to SMAP restrictions, and cleared otherwise. The + * bit is only meaningful if the SMAP bit is set in CR4. + */ + smapf = !(pfec & PFERR_RSVD_MASK); for (bit = 0; bit < 8; ++bit) { x = bit & ACC_EXEC_MASK; w = bit & ACC_WRITE_MASK; @@ -3627,11 +3634,32 @@ static void update_permission_bitmask(struct kvm_vcpu *vcpu, w |= !is_write_protection(vcpu) && !uf; /* Disallow supervisor fetches of user code if cr4.smep */ x &= !(smep && u && !uf); + + /* + * SMAP:kernel-mode data accesses from user-mode + * mappings should fault. A fault is considered + * as a SMAP violation if all of the following + * conditions are ture: + * - X86_CR4_SMAP is set in CR4 + * - An user page is accessed + * - Page fault in kernel mode + * - if CPL = 3 or X86_EFLAGS_AC is clear + * + * Here, we cover the first three conditions. + * The fourth is computed dynamically in + * permission_fault() and is in smapf. + * + * Also, SMAP does not affect instruction + * fetches, add the !ff check here to make it + * clearer. + */ + smap = cr4_smap && u && !uf && !ff; } else /* Not really needed: no U/S accesses on ept */ u = 1; - fault = (ff && !x) || (uf && !u) || (wf && !w); + fault = (ff && !x) || (uf && !u) || (wf && !w) || + (smapf && smap); map |= fault << bit; } mmu->permissions[byte] = map; diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 292615274358..3842e70bdb7c 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -44,11 +44,17 @@ #define PT_DIRECTORY_LEVEL 2 #define PT_PAGE_TABLE_LEVEL 1 -#define PFERR_PRESENT_MASK (1U << 0) -#define PFERR_WRITE_MASK (1U << 1) -#define PFERR_USER_MASK (1U << 2) -#define PFERR_RSVD_MASK (1U << 3) -#define PFERR_FETCH_MASK (1U << 4) +#define PFERR_PRESENT_BIT 0 +#define PFERR_WRITE_BIT 1 +#define PFERR_USER_BIT 2 +#define PFERR_RSVD_BIT 3 +#define PFERR_FETCH_BIT 4 + +#define PFERR_PRESENT_MASK (1U << PFERR_PRESENT_BIT) +#define PFERR_WRITE_MASK (1U << PFERR_WRITE_BIT) +#define PFERR_USER_MASK (1U << PFERR_USER_BIT) +#define PFERR_RSVD_MASK (1U << PFERR_RSVD_BIT) +#define PFERR_FETCH_MASK (1U << PFERR_FETCH_BIT) int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]); void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask); @@ -73,6 +79,8 @@ int handle_mmio_page_fault_common(struct kvm_vcpu *vcpu, u64 addr, bool direct); void kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context); void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context, bool execonly); +void update_permission_bitmask(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, + bool ept); static inline unsigned int kvm_mmu_available_pages(struct kvm *kvm) { @@ -110,10 +118,30 @@ static inline bool is_write_protection(struct kvm_vcpu *vcpu) * Will a fault with a given page-fault error code (pfec) cause a permission * fault with the given access (in ACC_* format)? */ -static inline bool permission_fault(struct kvm_mmu *mmu, unsigned pte_access, - unsigned pfec) +static inline bool permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu, + unsigned pte_access, unsigned pfec) { - return (mmu->permissions[pfec >> 1] >> pte_access) & 1; + int cpl = kvm_x86_ops->get_cpl(vcpu); + unsigned long rflags = kvm_x86_ops->get_rflags(vcpu); + + /* + * If CPL < 3, SMAP prevention are disabled if EFLAGS.AC = 1. + * + * If CPL = 3, SMAP applies to all supervisor-mode data accesses + * (these are implicit supervisor accesses) regardless of the value + * of EFLAGS.AC. + * + * This computes (cpl < 3) && (rflags & X86_EFLAGS_AC), leaving + * the result in X86_EFLAGS_AC. We then insert it in place of + * the PFERR_RSVD_MASK bit; this bit will always be zero in pfec, + * but it will be one in index if SMAP checks are being overridden. + * It is important to keep this branchless. + */ + unsigned long smap = (cpl - 3) & (rflags & X86_EFLAGS_AC); + int index = (pfec >> 1) + + (smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1)); + + return (mmu->permissions[index] >> pte_access) & 1; } void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm); diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index b1e6c1bf68d3..123efd3ec29f 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -353,7 +353,7 @@ static int FNAME(walk_addr_generic)(struct guest_walker *walker, walker->ptes[walker->level - 1] = pte; } while (!is_last_gpte(mmu, walker->level, pte)); - if (unlikely(permission_fault(mmu, pte_access, access))) { + if (unlikely(permission_fault(vcpu, mmu, pte_access, access))) { errcode |= PFERR_PRESENT_MASK; goto error; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d1c55f8722c6..41693787cd66 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -652,6 +652,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) if (!guest_cpuid_has_smep(vcpu) && (cr4 & X86_CR4_SMEP)) return 1; + if (!guest_cpuid_has_smap(vcpu) && (cr4 & X86_CR4_SMAP)) + return 1; + if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE)) return 1; @@ -680,6 +683,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE))) kvm_mmu_reset_context(vcpu); + if ((cr4 ^ old_cr4) & X86_CR4_SMAP) + update_permission_bitmask(vcpu, vcpu->arch.walk_mmu, false); + if ((cr4 ^ old_cr4) & X86_CR4_OSXSAVE) kvm_update_cpuid(vcpu); @@ -4164,7 +4170,8 @@ static int vcpu_mmio_gva_to_gpa(struct kvm_vcpu *vcpu, unsigned long gva, | (write ? PFERR_WRITE_MASK : 0); if (vcpu_match_mmio_gva(vcpu, gva) - && !permission_fault(vcpu->arch.walk_mmu, vcpu->arch.access, access)) { + && !permission_fault(vcpu, vcpu->arch.walk_mmu, + vcpu->arch.access, access)) { *gpa = vcpu->arch.mmio_gfn << PAGE_SHIFT | (gva & (PAGE_SIZE - 1)); trace_vcpu_match_mmio(gva, *gpa, write, false); -- GitLab From e1e746b3c55d1d1e0841a2e600a154d8f6747232 Mon Sep 17 00:00:00 2001 From: Feng Wu Date: Tue, 1 Apr 2014 17:46:35 +0800 Subject: [PATCH 239/797] KVM: Disable SMAP for guests in EPT realmode and EPT unpaging mode SMAP is disabled if CPU is in non-paging mode in hardware. However KVM always uses paging mode to emulate guest non-paging mode with TDP. To emulate this behavior, SMAP needs to be manually disabled when guest switches to non-paging mode. Signed-off-by: Feng Wu Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/vmx.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1320e0f8e611..1f68c5831924 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3484,13 +3484,14 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) hw_cr4 &= ~X86_CR4_PAE; hw_cr4 |= X86_CR4_PSE; /* - * SMEP is disabled if CPU is in non-paging mode in - * hardware. However KVM always uses paging mode to + * SMEP/SMAP is disabled if CPU is in non-paging mode + * in hardware. However KVM always uses paging mode to * emulate guest non-paging mode with TDP. - * To emulate this behavior, SMEP needs to be manually - * disabled when guest switches to non-paging mode. + * To emulate this behavior, SMEP/SMAP needs to be + * manually disabled when guest switches to non-paging + * mode. */ - hw_cr4 &= ~X86_CR4_SMEP; + hw_cr4 &= ~(X86_CR4_SMEP | X86_CR4_SMAP); } else if (!(cr4 & X86_CR4_PAE)) { hw_cr4 &= ~X86_CR4_PAE; } -- GitLab From de935ae15b0db57f7fb837b37380ee94d4b0fec3 Mon Sep 17 00:00:00 2001 From: Feng Wu Date: Tue, 1 Apr 2014 17:46:36 +0800 Subject: [PATCH 240/797] KVM: expose SMAP feature to guest This patch exposes SMAP feature to guest Signed-off-by: Feng Wu Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/cpuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index bea60671ef8a..f47a104a749c 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -308,7 +308,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, const u32 kvm_supported_word9_x86_features = F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) | F(BMI2) | F(ERMS) | f_invpcid | F(RTM) | f_mpx | F(RDSEED) | - F(ADX); + F(ADX) | F(SMAP); /* all calls to cpuid_count() should be made on the same cpu */ get_cpu(); -- GitLab From 66386ade2aa7f5fcf0dda4171df7b4d4c274d2d6 Mon Sep 17 00:00:00 2001 From: Feng Wu Date: Tue, 1 Apr 2014 17:56:48 +0800 Subject: [PATCH 241/797] KVM: Rename variable smep to cr4_smep Rename variable smep to cr4_smep, which can better reflect the meaning of the variable. Signed-off-by: Feng Wu Signed-off-by: Marcelo Tosatti --- arch/x86/kvm/mmu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 084caf3efaf5..813d31038b93 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3606,9 +3606,9 @@ void update_permission_bitmask(struct kvm_vcpu *vcpu, { unsigned bit, byte, pfec; u8 map; - bool fault, x, w, u, wf, uf, ff, smapf, cr4_smap, smep, smap = 0; + bool fault, x, w, u, wf, uf, ff, smapf, cr4_smap, cr4_smep, smap = 0; - smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); + cr4_smep = kvm_read_cr4_bits(vcpu, X86_CR4_SMEP); cr4_smap = kvm_read_cr4_bits(vcpu, X86_CR4_SMAP); for (byte = 0; byte < ARRAY_SIZE(mmu->permissions); ++byte) { pfec = byte << 1; @@ -3633,7 +3633,7 @@ void update_permission_bitmask(struct kvm_vcpu *vcpu, /* Allow supervisor writes if !cr0.wp */ w |= !is_write_protection(vcpu) && !uf; /* Disallow supervisor fetches of user code if cr4.smep */ - x &= !(smep && u && !uf); + x &= !(cr4_smep && u && !uf); /* * SMAP:kernel-mode data accesses from user-mode -- GitLab From b351c39cc9e0151cee9b8d52a1e714928faabb38 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Thu, 10 Apr 2014 18:19:12 -0300 Subject: [PATCH 242/797] KVM: x86: remove WARN_ON from get_kernel_ns() Function and callers can be preempted. https://bugzilla.kernel.org/show_bug.cgi?id=73721 Signed-off-by: Marcelo Tosatti Reviewed-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 41693787cd66..757d40871b30 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1123,7 +1123,6 @@ static inline u64 get_kernel_ns(void) { struct timespec ts; - WARN_ON(preemptible()); ktime_get_ts(&ts); monotonic_to_bootbased(&ts); return timespec_to_ns(&ts); -- GitLab From 1cb7b43f6796ad0bc62669fa52d1005916911d27 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 8 Mar 2014 11:55:29 +0800 Subject: [PATCH 243/797] regulator: pbias: Fix is_enabled callback implementation The is_enabled implementation is wrong in some cases: e.g. for pbias_mmc_omap5: enable_mask is : BIT(27) | BIT(25) | BIT(26) However, pbias_regulator_enable() only sets BIT(27) | BIT(26) bits. So is_enabled callback will always return false in this case. Fix the logic to compare the register value with info->enable rather than info->enable_mask. Signed-off-by: Axel Lin Acked-by: Balaji T K Signed-off-by: Mark Brown --- drivers/regulator/pbias-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index ded3b3574209..d89a1d8615c7 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -108,7 +108,7 @@ static int pbias_regulator_is_enable(struct regulator_dev *rdev) regmap_read(data->syscon, data->pbias_reg, &value); - return (value & info->enable_mask) == info->enable_mask; + return (value & info->enable_mask) == info->enable; } static struct regulator_ops pbias_regulator_voltage_ops = { -- GitLab From 60e8c1e34d3ab74556fb9b25f26fa34b9879ee30 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 8 Mar 2014 11:56:47 +0800 Subject: [PATCH 244/797] regulator: pbias: Convert to use regmap helper functions This patch converts this driver to use the regmap helper functions provided by regulator core. Signed-off-by: Axel Lin Acked-by: Balaji T K Signed-off-by: Mark Brown --- drivers/regulator/pbias-regulator.c | 74 ++++++++--------------------- 1 file changed, 19 insertions(+), 55 deletions(-) diff --git a/drivers/regulator/pbias-regulator.c b/drivers/regulator/pbias-regulator.c index d89a1d8615c7..6d38be3d970c 100644 --- a/drivers/regulator/pbias-regulator.c +++ b/drivers/regulator/pbias-regulator.c @@ -38,66 +38,24 @@ struct pbias_reg_info { struct pbias_regulator_data { struct regulator_desc desc; void __iomem *pbias_addr; - unsigned int pbias_reg; struct regulator_dev *dev; struct regmap *syscon; const struct pbias_reg_info *info; int voltage; }; -static int pbias_regulator_set_voltage(struct regulator_dev *dev, - int min_uV, int max_uV, unsigned *selector) -{ - struct pbias_regulator_data *data = rdev_get_drvdata(dev); - const struct pbias_reg_info *info = data->info; - int ret, vmode; - - if (min_uV <= 1800000) - vmode = 0; - else if (min_uV > 1800000) - vmode = info->vmode; - - ret = regmap_update_bits(data->syscon, data->pbias_reg, - info->vmode, vmode); - - return ret; -} - -static int pbias_regulator_get_voltage(struct regulator_dev *rdev) -{ - struct pbias_regulator_data *data = rdev_get_drvdata(rdev); - const struct pbias_reg_info *info = data->info; - int value, voltage; - - regmap_read(data->syscon, data->pbias_reg, &value); - value &= info->vmode; - - voltage = value ? 3000000 : 1800000; - - return voltage; -} +static const unsigned int pbias_volt_table[] = { + 1800000, + 3000000 +}; static int pbias_regulator_enable(struct regulator_dev *rdev) { struct pbias_regulator_data *data = rdev_get_drvdata(rdev); const struct pbias_reg_info *info = data->info; - int ret; - - ret = regmap_update_bits(data->syscon, data->pbias_reg, - info->enable_mask, info->enable); - - return ret; -} - -static int pbias_regulator_disable(struct regulator_dev *rdev) -{ - struct pbias_regulator_data *data = rdev_get_drvdata(rdev); - const struct pbias_reg_info *info = data->info; - int ret; - ret = regmap_update_bits(data->syscon, data->pbias_reg, - info->enable_mask, 0); - return ret; + return regmap_update_bits(data->syscon, rdev->desc->enable_reg, + info->enable_mask, info->enable); } static int pbias_regulator_is_enable(struct regulator_dev *rdev) @@ -106,17 +64,18 @@ static int pbias_regulator_is_enable(struct regulator_dev *rdev) const struct pbias_reg_info *info = data->info; int value; - regmap_read(data->syscon, data->pbias_reg, &value); + regmap_read(data->syscon, rdev->desc->enable_reg, &value); return (value & info->enable_mask) == info->enable; } static struct regulator_ops pbias_regulator_voltage_ops = { - .set_voltage = pbias_regulator_set_voltage, - .get_voltage = pbias_regulator_get_voltage, - .enable = pbias_regulator_enable, - .disable = pbias_regulator_disable, - .is_enabled = pbias_regulator_is_enable, + .list_voltage = regulator_list_voltage_table, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = pbias_regulator_enable, + .disable = regulator_disable_regmap, + .is_enabled = pbias_regulator_is_enable, }; static const struct pbias_reg_info pbias_mmc_omap2430 = { @@ -192,6 +151,7 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (IS_ERR(syscon)) return PTR_ERR(syscon); + cfg.regmap = syscon; cfg.dev = &pdev->dev; for (idx = 0; idx < PBIAS_NUM_REGS && data_idx < count; idx++) { @@ -207,15 +167,19 @@ static int pbias_regulator_probe(struct platform_device *pdev) if (!res) return -EINVAL; - drvdata[data_idx].pbias_reg = res->start; drvdata[data_idx].syscon = syscon; drvdata[data_idx].info = info; drvdata[data_idx].desc.name = info->name; drvdata[data_idx].desc.owner = THIS_MODULE; drvdata[data_idx].desc.type = REGULATOR_VOLTAGE; drvdata[data_idx].desc.ops = &pbias_regulator_voltage_ops; + drvdata[data_idx].desc.volt_table = pbias_volt_table; drvdata[data_idx].desc.n_voltages = 2; drvdata[data_idx].desc.enable_time = info->enable_time; + drvdata[data_idx].desc.vsel_reg = res->start; + drvdata[data_idx].desc.vsel_mask = info->vmode; + drvdata[data_idx].desc.enable_reg = res->start; + drvdata[data_idx].desc.enable_mask = info->enable_mask; cfg.init_data = pbias_matches[idx].init_data; cfg.driver_data = &drvdata[data_idx]; -- GitLab From c39e1ef77c76729f34cdcb09bbb3a5096d91a740 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 12 Apr 2014 06:07:23 +0100 Subject: [PATCH 245/797] ARM: 8024/1: Keep DEBUG_UART_{PHYS,VIRT} entries sorted This patch sorts the entries for DEBUG_UART_{PHYS,VIRT}. Signed-off-by: Alexander Shiyan Signed-off-by: Russell King --- arch/arm/Kconfig.debug | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 4a2fc0bf6fc9..eab8ecbe69c1 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1030,9 +1030,9 @@ config DEBUG_UART_PHYS default 0x40100000 if DEBUG_PXA_UART1 default 0x42000000 if ARCH_GEMINI default 0x7c0003f8 if FOOTBRIDGE - default 0x80230000 if DEBUG_PICOXCELL_UART default 0x80070000 if DEBUG_IMX23_UART default 0x80074000 if DEBUG_IMX28_UART + default 0x80230000 if DEBUG_PICOXCELL_UART default 0x808c0000 if ARCH_EP93XX default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX @@ -1096,22 +1096,22 @@ config DEBUG_UART_VIRT default 0xfeb26000 if DEBUG_RK3X_UART1 default 0xfeb30c00 if DEBUG_KEYSTONE_UART0 default 0xfeb31000 if DEBUG_KEYSTONE_UART1 - default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE - default 0xfed60000 if DEBUG_RK29_UART0 - default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 - default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 default 0xfec02000 if DEBUG_SOCFPGA_UART + default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0 default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 default 0xfed12000 if ARCH_KIRKWOOD + default 0xfed60000 if DEBUG_RK29_UART0 + default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 + default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 default 0xfedc0000 if ARCH_EP93XX default 0xfee003f8 if FOOTBRIDGE default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART - default 0xfef36000 if DEBUG_HIGHBANK_UART default 0xfee82340 if ARCH_IOP13XX default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN + default 0xfef36000 if DEBUG_HIGHBANK_UART default 0xfefff700 if ARCH_IOP33X default 0xff003000 if DEBUG_U300_UART default DEBUG_UART_PHYS if !MMU -- GitLab From 244b478386260a8a9150b501bc97644e2e07f8d3 Mon Sep 17 00:00:00 2001 From: Jay Foad Date: Mon, 14 Apr 2014 16:23:15 +0100 Subject: [PATCH 246/797] ARM: 8026/1: Fix emulation of multiply accumulate instructions The emulation for single and double precision multiply accumulate instructions correctly normalised any denormal values in the operand registers, but failed to normalise the destination (accumulator) register. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=70501 Signed-off-by: Jay Foad Signed-off-by: Russell King --- arch/arm/vfp/vfpdouble.c | 2 ++ arch/arm/vfp/vfpsingle.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index 6cac43bd1d86..423f56dd4028 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -866,6 +866,8 @@ vfp_double_multiply_accumulate(int dd, int dn, int dm, u32 fpscr, u32 negate, ch vdp.sign = vfp_sign_negate(vdp.sign); vfp_double_unpack(&vdn, vfp_get_double(dd)); + if (vdn.exponent == 0 && vdn.significand) + vfp_double_normalise_denormal(&vdn); if (negate & NEG_SUBTRACT) vdn.sign = vfp_sign_negate(vdn.sign); diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index b252631b406b..4f96c1617aae 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -915,6 +915,8 @@ vfp_single_multiply_accumulate(int sd, int sn, s32 m, u32 fpscr, u32 negate, cha v = vfp_get_float(sd); pr_debug("VFP: s%u = %08x\n", sd, v); vfp_single_unpack(&vsn, v); + if (vsn.exponent == 0 && vsn.significand) + vfp_single_normalise_denormal(&vsn); if (negate & NEG_SUBTRACT) vsn.sign = vfp_sign_negate(vsn.sign); -- GitLab From 140ab6452c42174d20e2fdd27ed73b889cd86500 Mon Sep 17 00:00:00 2001 From: Mike Qiu Date: Mon, 14 Apr 2014 16:12:35 -0600 Subject: [PATCH 247/797] powerpc/PCI: Fix NULL dereference in sys_pciconfig_iobase() list traversal 3bc955987fb3 ("powerpc/PCI: Use list_for_each_entry() for bus traversal") caused a NULL pointer dereference because the loop body set the iterator to NULL: Unable to handle kernel paging request for data at address 0x00000000 Faulting instruction address: 0xc000000000041d78 Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [c000000000041d78] .sys_pciconfig_iobase+0x68/0x1f0 LR [c000000000041e0c] .sys_pciconfig_iobase+0xfc/0x1f0 Call Trace: [c0000003b4787db0] [c000000000041e0c] .sys_pciconfig_iobase+0xfc/0x1f0 (unreliable) [c0000003b4787e30] [c000000000009ed8] syscall_exit+0x0/0x98 Fix it by using a temporary variable for the iterator. [bhelgaas: changelog, drop tmp_bus initialization] Fixes: 3bc955987fb3 powerpc/PCI: Use list_for_each_entry() for bus traversal Signed-off-by: Mike Qiu Signed-off-by: Bjorn Helgaas --- arch/powerpc/kernel/pci_64.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 2a4779091a58..155013da27e0 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, unsigned long in_devfn) { struct pci_controller* hose; - struct pci_bus *bus = NULL; + struct pci_bus *tmp_bus, *bus = NULL; struct device_node *hose_node; /* Argh ! Please forgive me for that hack, but that's the @@ -229,10 +229,12 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus, * used on pre-domains setup. We return the first match */ - list_for_each_entry(bus, &pci_root_buses, node) { - if (in_bus >= bus->number && in_bus <= bus->busn_res.end) + list_for_each_entry(tmp_bus, &pci_root_buses, node) { + if (in_bus >= tmp_bus->number && + in_bus <= tmp_bus->busn_res.end) { + bus = tmp_bus; break; - bus = NULL; + } } if (bus == NULL || bus->dev.of_node == NULL) return -ENODEV; -- GitLab From de66b584042b8f2cfe4c34ef4faa804dcd8d5843 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 14 Apr 2014 16:18:18 +0200 Subject: [PATCH 248/797] ARM: shmobile: sh73a0: drop address cells from GIC node This is likely a copy-and-paste error from the ARM GIC documentation, that has already been fixed. address-cells should have been set to 0, as with the size cells. As having those properties set to 0 is the same thing as not specifying them, drop them completely. Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Simon Horman --- arch/arm/boot/dts/sh73a0.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index b7bd3b9a6753..5ecf552e1c00 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -34,7 +34,6 @@ gic: interrupt-controller@f0001000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; interrupt-controller; reg = <0xf0001000 0x1000>, <0xf0000100 0x100>; -- GitLab From 64c04a79c377e23449c59060727fcd34cc798eb6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Mon, 14 Apr 2014 16:18:17 +0200 Subject: [PATCH 249/797] ARM: shmobile: r8a7740: drop address cells from GIC node This is likely a copy-and-paste error from the ARM GIC documentation, that has already been fixed. address-cells should have been set to 0, as with the size cells. As having those properties set to 0 is the same thing as not specifying them, drop them completely. Signed-off-by: Lucas Stach Acked-by: Rob Herring Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7740.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi index 8280884bfa59..2551e9438d35 100644 --- a/arch/arm/boot/dts/r8a7740.dtsi +++ b/arch/arm/boot/dts/r8a7740.dtsi @@ -28,7 +28,6 @@ gic: interrupt-controller@c2800000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; - #address-cells = <1>; interrupt-controller; reg = <0xc2800000 0x1000>, <0xc2000000 0x1000>; -- GitLab From d5dda0381f826326071b027f288372f682c24d55 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 14 Apr 2014 19:13:21 +0900 Subject: [PATCH 250/797] ARM: shmobile: koelsch: correct renesas,gpios to renesas,groups in sd[012] pfc Fix typo of renesas,groups in the koeslch dt. The kernel has no renesas,gpios but this should match renesas,groups. Noticed thanks to similar fix for Lager by Rob Taylor and Ben Dooks. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index bdd73e6657b2..de1b6977c69a 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -230,17 +230,17 @@ }; sdhi0_pins: sd0 { - renesas,gpios = "sdhi0_data4", "sdhi0_ctrl"; + renesas,groups = "sdhi0_data4", "sdhi0_ctrl"; renesas,function = "sdhi0"; }; sdhi1_pins: sd1 { - renesas,gpios = "sdhi1_data4", "sdhi1_ctrl"; + renesas,groups = "sdhi1_data4", "sdhi1_ctrl"; renesas,function = "sdhi1"; }; sdhi2_pins: sd2 { - renesas,gpios = "sdhi2_data4", "sdhi2_ctrl"; + renesas,groups = "sdhi2_data4", "sdhi2_ctrl"; renesas,function = "sdhi2"; }; -- GitLab From 1e785f48d29a09b6cf96db7b49b6320dada332e1 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Mon, 14 Apr 2014 17:37:26 -0400 Subject: [PATCH 251/797] net: Start with correct mac_len in skb_network_protocol Sometimes, when the packet arrives at skb_mac_gso_segment() its skb->mac_len already accounts for some of the mac lenght headers in the packet. This seems to happen when forwarding through and OpenSSL tunnel. When we start looking for any vlan headers in skb_network_protocol() we seem to ignore any of the already known mac headers and start with an ETH_HLEN. This results in an incorrect offset, dropped TSO frames and general slowness of the connection. We can start counting from the known skb->mac_len and return at least that much if all mac level headers are known and accounted for. Fixes: 53d6471cef17262d3ad1c7ce8982a234244f68ec (net: Account for all vlan headers in skb_mac_gso_segment) CC: Eric Dumazet CC: Daniel Borkman Tested-by: Martin Filip Signed-off-by: Vlad Yasevich Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 14dac0654f28..5b3042e69f85 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2284,7 +2284,7 @@ EXPORT_SYMBOL(skb_checksum_help); __be16 skb_network_protocol(struct sk_buff *skb, int *depth) { __be16 type = skb->protocol; - int vlan_depth = ETH_HLEN; + int vlan_depth = skb->mac_len; /* Tunnel gso handlers can set protocol to ethernet. */ if (type == htons(ETH_P_TEB)) { -- GitLab From e79323bd87808fdfbc68ce6c5371bd224d9672ee Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 14 Apr 2014 16:58:55 -0400 Subject: [PATCH 252/797] user namespace: fix incorrect memory barriers smp_read_barrier_depends() can be used if there is data dependency between the readers - i.e. if the read operation after the barrier uses address that was obtained from the read operation before the barrier. In this file, there is only control dependency, no data dependecy, so the use of smp_read_barrier_depends() is incorrect. The code could fail in the following way: * the cpu predicts that idx < entries is true and starts executing the body of the for loop * the cpu fetches map->extent[0].first and map->extent[0].count * the cpu fetches map->nr_extents * the cpu verifies that idx < extents is true, so it commits the instructions in the body of the for loop The problem is that in this scenario, the cpu read map->extent[0].first and map->nr_extents in the wrong order. We need a full read memory barrier to prevent it. Signed-off-by: Mikulas Patocka Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds --- kernel/user_namespace.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 0d8f6023fd8d..bf71b4b2d632 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -152,7 +152,7 @@ static u32 map_id_range_down(struct uid_gid_map *map, u32 id, u32 count) /* Find the matching extent */ extents = map->nr_extents; - smp_read_barrier_depends(); + smp_rmb(); for (idx = 0; idx < extents; idx++) { first = map->extent[idx].first; last = first + map->extent[idx].count - 1; @@ -176,7 +176,7 @@ static u32 map_id_down(struct uid_gid_map *map, u32 id) /* Find the matching extent */ extents = map->nr_extents; - smp_read_barrier_depends(); + smp_rmb(); for (idx = 0; idx < extents; idx++) { first = map->extent[idx].first; last = first + map->extent[idx].count - 1; @@ -199,7 +199,7 @@ static u32 map_id_up(struct uid_gid_map *map, u32 id) /* Find the matching extent */ extents = map->nr_extents; - smp_read_barrier_depends(); + smp_rmb(); for (idx = 0; idx < extents; idx++) { first = map->extent[idx].lower_first; last = first + map->extent[idx].count - 1; @@ -615,9 +615,8 @@ static ssize_t map_write(struct file *file, const char __user *buf, * were written before the count of the extents. * * To achieve this smp_wmb() is used on guarantee the write - * order and smp_read_barrier_depends() is guaranteed that we - * don't have crazy architectures returning stale data. - * + * order and smp_rmb() is guaranteed that we don't have crazy + * architectures returning stale data. */ mutex_lock(&id_map_mutex); -- GitLab From 17b9b3b9e88ac6564689283a08034faf2c048fdb Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 14 Apr 2014 16:20:39 +0200 Subject: [PATCH 253/797] ARM: imx6q: clk: Parent DI clocks to video PLL via di_pre_sel Route the video PLL to the display interface clocks via the di_pre_sel and di_sel muxes by default. Signed-off-by: Sascha Hauer Signed-off-by: Philipp Zabel Tested-by: Russell King Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 3ed67b592b48..4a6fb65589fa 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -445,6 +445,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk_set_parent(clk[ldb_di1_sel], clk[pll5_video_div]); } + clk_set_parent(clk[ipu1_di0_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu1_di1_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu2_di0_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu2_di1_pre_sel], clk[pll5_video_div]); + clk_set_parent(clk[ipu1_di0_sel], clk[ipu1_di0_pre]); + clk_set_parent(clk[ipu1_di1_sel], clk[ipu1_di1_pre]); + clk_set_parent(clk[ipu2_di0_sel], clk[ipu2_di0_pre]); + clk_set_parent(clk[ipu2_di1_sel], clk[ipu2_di1_pre]); + /* * The gpmi needs 100MHz frequency in the EDO/Sync mode, * We can not get the 100MHz from the pll2_pfd0_352m. -- GitLab From 4591b13289b54fb5cbce84ee170f7390c576ef8f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 14 Apr 2014 16:20:40 +0200 Subject: [PATCH 254/797] ARM: i.MX6: ipu_di_sel clocks can set parent rates To obtain exact pixel clocks, allow the DI clock selectors to influence the PLLs that they are derived from. Signed-off-by: Philipp Zabel Tested-by: Russell King Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 4a6fb65589fa..2b4d6acfa34a 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -258,14 +258,14 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[ipu2_sel] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); clk[ldb_di0_sel] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); clk[ldb_di1_sel] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); - clk[ipu1_di0_pre_sel] = imx_clk_mux("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu1_di1_pre_sel] = imx_clk_mux("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu2_di0_pre_sel] = imx_clk_mux("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu2_di1_pre_sel] = imx_clk_mux("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels)); - clk[ipu1_di0_sel] = imx_clk_mux("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels)); - clk[ipu1_di1_sel] = imx_clk_mux("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels)); - clk[ipu2_di0_sel] = imx_clk_mux("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels)); - clk[ipu2_di1_sel] = imx_clk_mux("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels)); + clk[ipu1_di0_pre_sel] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di1_pre_sel] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di0_pre_sel] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di1_pre_sel] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di0_sel] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); + clk[ipu1_di1_sel] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di0_sel] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); + clk[ipu2_di1_sel] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); clk[hsi_tx_sel] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); clk[pcie_axi_sel] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); clk[ssi1_sel] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); -- GitLab From 036acea2ceabd19cb5734ae7a9d64c0a5ef90484 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Mon, 14 Apr 2014 23:36:15 -0400 Subject: [PATCH 255/797] ext4: fix ext4_count_free_clusters() with EXT4FS_DEBUG and bigalloc enabled With bigalloc enabled we must use EXT4_CLUSTERS_PER_GROUP() instead of EXT4_BLOCKS_PER_GROUP() otherwise we will go beyond the allocated buffer. $ mount -t ext4 /dev/vde /vde [ 70.573993] EXT4-fs DEBUG (fs/ext4/mballoc.c, 2346): ext4_mb_alloc_groupinfo: [ 70.575174] allocated s_groupinfo array for 1 meta_bg's [ 70.576172] EXT4-fs DEBUG (fs/ext4/super.c, 2092): ext4_check_descriptors: [ 70.576972] Checking group descriptorsBUG: unable to handle kernel paging request at ffff88006ab56000 [ 72.463686] IP: [] __bitmap_weight+0x2a/0x7f [ 72.464168] PGD 295e067 PUD 2961067 PMD 7fa8e067 PTE 800000006ab56060 [ 72.464738] Oops: 0000 [#1] SMP DEBUG_PAGEALLOC [ 72.465139] Modules linked in: [ 72.465402] CPU: 1 PID: 3560 Comm: mount Tainted: G W 3.14.0-rc2-00069-ge57bce1 #60 [ 72.466079] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011 [ 72.466505] task: ffff88007ce6c8a0 ti: ffff88006b7f0000 task.ti: ffff88006b7f0000 [ 72.466505] RIP: 0010:[] [] __bitmap_weight+0x2a/0x7f [ 72.466505] RSP: 0018:ffff88006b7f1c00 EFLAGS: 00010206 [ 72.466505] RAX: 0000000000000000 RBX: 000000000000050a RCX: 0000000000000040 [ 72.466505] RDX: 0000000000000000 RSI: 0000000000080000 RDI: 0000000000000000 [ 72.466505] RBP: ffff88006b7f1c28 R08: 0000000000000002 R09: 0000000000000000 [ 72.466505] R10: 000000000000babe R11: 0000000000000400 R12: 0000000000080000 [ 72.466505] R13: 0000000000000200 R14: 0000000000002000 R15: ffff88006ab55000 [ 72.466505] FS: 00007f43ba1fa840(0000) GS:ffff88007f800000(0000) knlGS:0000000000000000 [ 72.466505] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 72.466505] CR2: ffff88006ab56000 CR3: 000000006b7e6000 CR4: 00000000000006e0 [ 72.466505] Stack: [ 72.466505] ffff88006ab65000 0000000000000000 0000000000000000 0000000000010000 [ 72.466505] ffff88006ab6f400 ffff88006b7f1c58 ffffffff81396bb8 0000000000010000 [ 72.466505] 0000000000000000 ffff88007b869a90 ffff88006a48a000 ffff88006b7f1c70 [ 72.466505] Call Trace: [ 72.466505] [] memweight+0x5f/0x8a [ 72.466505] [] ext4_count_free+0x13/0x21 [ 72.466505] [] ext4_count_free_clusters+0xdb/0x171 [ 72.466505] [] ext4_fill_super+0x117c/0x28ef [ 72.466505] [] ? vsnprintf+0x1c7/0x3f7 [ 72.466505] [] mount_bdev+0x145/0x19c [ 72.466505] [] ? ext4_calculate_overhead+0x2a1/0x2a1 [ 72.466505] [] ext4_mount+0x15/0x17 [ 72.466505] [] mount_fs+0x67/0x150 [ 72.466505] [] vfs_kern_mount+0x64/0xde [ 72.466505] [] do_mount+0x6fe/0x7f5 [ 72.466505] [] ? strndup_user+0x3a/0xd9 [ 72.466505] [] SyS_mount+0x85/0xbe [ 72.466505] [] tracesys+0xdd/0xe2 [ 72.466505] Code: c3 89 f0 b9 40 00 00 00 55 99 48 89 e5 41 57 f7 f9 41 56 49 89 ff 41 55 45 31 ed 41 54 41 89 f4 53 31 db 41 89 c6 45 39 ee 7e 10 <4b> 8b 3c ef 49 ff c5 e8 bf ff ff ff 01 c3 eb eb 31 c0 45 85 f6 [ 72.466505] RIP [] __bitmap_weight+0x2a/0x7f [ 72.466505] RSP [ 72.466505] CR2: ffff88006ab56000 [ 72.466505] ---[ end trace 7d051a08ae138573 ]--- Killed Signed-off-by: "Theodore Ts'o" --- fs/ext4/balloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index 6ea7b1436bbc..5c56785007e0 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -667,7 +667,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb) continue; x = ext4_count_free(bitmap_bh->b_data, - EXT4_BLOCKS_PER_GROUP(sb) / 8); + EXT4_CLUSTERS_PER_GROUP(sb) / 8); printk(KERN_DEBUG "group %u: stored = %d, counted = %u\n", i, ext4_free_group_clusters(sb, gdp), x); bitmap_count += x; -- GitLab From 50e02fd84543d82e663000e780e0ec0cfde52283 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 14 Apr 2014 23:37:35 -0400 Subject: [PATCH 256/797] ext4: remove temporary shim used to merge COLLAPSE_RANGE and ZERO_RANGE In retrospect, this was a bad way to handle things, since it limited testing of these patches. We should just get the VFS level changes merged in first. Signed-off-by: "Theodore Ts'o" --- include/trace/events/ext4.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 010ea89eeb0e..6a1a0245474f 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -16,15 +16,6 @@ struct mpage_da_data; struct ext4_map_blocks; struct extent_status; -/* shim until we merge in the xfs_collapse_range branch */ -#ifndef FALLOC_FL_COLLAPSE_RANGE -#define FALLOC_FL_COLLAPSE_RANGE 0x08 -#endif - -#ifndef FALLOC_FL_ZERO_RANGE -#define FALLOC_FL_ZERO_RANGE 0x10 -#endif - #define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode)) #define show_mballoc_flags(flags) __print_flags(flags, "|", \ -- GitLab From ea05df4e8f5d2466dbbf2e46956e9e202a22232b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Apr 2014 15:38:49 +0200 Subject: [PATCH 257/797] net: cadence: Add architecture dependencies The Cadence ethernet chipsets are only used on specific ARM architectures. Add Kconfig dependencies so that drivers for these chipsets are only buildable on the relevant architectures. Signed-off-by: Jean Delvare Cc: Nicolas Ferre Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 751d5c7b312d..7e49c43b7af3 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig @@ -4,7 +4,7 @@ config NET_CADENCE bool "Cadence devices" - depends on HAS_IOMEM + depends on HAS_IOMEM && (ARM || AVR32 || COMPILE_TEST) default y ---help--- If you have a network (Ethernet) card belonging to this class, say Y. @@ -22,7 +22,7 @@ if NET_CADENCE config ARM_AT91_ETHER tristate "AT91RM9200 Ethernet support" - depends on HAS_DMA + depends on HAS_DMA && (ARCH_AT91RM9200 || COMPILE_TEST) select MACB ---help--- If you wish to compile a kernel for the AT91RM9200 and enable @@ -30,7 +30,7 @@ config ARM_AT91_ETHER config MACB tristate "Cadence MACB/GEM support" - depends on HAS_DMA + depends on HAS_DMA && (PLATFORM_AT32AP || ARCH_AT91 || ARCH_PICOXCELL || ARCH_ZYNQ || COMPILE_TEST) select PHYLIB ---help--- The Cadence MACB ethernet interface is found on many Atmel AT32 and -- GitLab From bb78864a0c3c55461fc757c0c4b674f409518325 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 14 Apr 2014 18:48:01 +0200 Subject: [PATCH 258/797] at86rf230: remove check if AVDD settled The AVDD regulator is only enabled when the RF section is active TX_ON (PLL_ON) state. Since commit 7dcbd22a97eb0689e6c583ad630ae0e7341e34c1 ("ieee802154: ensure that first RF212 state comes from TRX_OFF"). We are in TRX_OFF state at the time at86rf230_hw_init is run. Note that this test would only fail in case of a severe hardware malfunction (faulty/shorted power supply, etc.) so it wasn't all that useful in the first place. Signed-off-by: Alexander Aring Reviewed-by: Werner Almesberger Signed-off-by: David S. Miller --- drivers/net/ieee802154/at86rf230.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 430bb0db9bc4..e102eef0b332 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1025,14 +1025,6 @@ static int at86rf230_hw_init(struct at86rf230_local *lp) return -EINVAL; } - rc = at86rf230_read_subreg(lp, SR_AVDD_OK, &status); - if (rc) - return rc; - if (!status) { - dev_err(&lp->spi->dev, "AVDD error\n"); - return -EINVAL; - } - return 0; } -- GitLab From 2168746cfc075d004fd7044be706054fceb24e59 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 14 Apr 2014 18:48:02 +0200 Subject: [PATCH 259/797] at86rf230: fix __at86rf230_read_subreg function The __at86rf230_read_subreg function don't mask and shift register contents which it should do. This patch adds the necessary masks and shift operations in this function. Since we have csma support this can make some trouble on state changes. Since CSMA support turned on some bits in the TRX_STATUS register that used to be zero, not masking broke checking of the TRX_STATUS field after commanding a state change. Signed-off-by: Alexander Aring Reviewed-by: Werner Almesberger Signed-off-by: David S. Miller --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index e102eef0b332..e36f194673a4 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -365,7 +365,7 @@ __at86rf230_read_subreg(struct at86rf230_local *lp, dev_vdbg(&lp->spi->dev, "buf[1] = %02x\n", buf[1]); if (status == 0) - *data = buf[1]; + *data = (buf[1] & mask) >> shift; return status; } -- GitLab From 1dd333f470b4e1767c9c0a14b05b5104e56b2930 Mon Sep 17 00:00:00 2001 From: "Li, Zhen-Hua" Date: Tue, 15 Apr 2014 09:53:11 +0800 Subject: [PATCH 260/797] driver/net: cosa driver uses udelay incorrectly In cosa driver, udelay with more than 20000 may cause __bad_udelay. Use msleep for instead. Signed-off-by: Li, Zhen-Hua Signed-off-by: David S. Miller --- drivers/net/wan/cosa.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index 84734a805092..83c39e2858bf 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c @@ -1521,11 +1521,7 @@ static int cosa_reset_and_read_id(struct cosa_data *cosa, char *idstring) cosa_putstatus(cosa, 0); cosa_getdata8(cosa); cosa_putstatus(cosa, SR_RST); -#ifdef MODULE msleep(500); -#else - udelay(5*100000); -#endif /* Disable all IRQs from the card */ cosa_putstatus(cosa, 0); -- GitLab From 9f05d3fb644bf178c169d9c70dcfe360e3a006ae Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 14 Apr 2014 22:01:30 -0700 Subject: [PATCH 261/797] iommu/vt-d: Fix get_domain_for_dev() handling of upstream PCIe bridges Commit 146922ec79 ("iommu/vt-d: Make get_domain_for_dev() take struct device") introduced new variables bridge_bus and bridge_devfn to identify the upstream PCIe to PCI bridge responsible for the given target device. Leaving the original bus/devfn variables to identify the target device itself, now that it is no longer assumed to be PCI and we can no longer trivially find that information. However, the patch failed to correctly use the new variables in all cases; instead using the as-yet-uninitialised 'bus' and 'devfn' variables. Reported-by: Alex Williamson Signed-off-by: David Woodhouse --- drivers/iommu/intel-iommu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 13dc2318e17a..f256ffc02e29 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2237,7 +2237,9 @@ static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw) bridge_devfn = dev_tmp->devfn; } spin_lock_irqsave(&device_domain_lock, flags); - info = dmar_search_domain_by_dev_info(segment, bus, devfn); + info = dmar_search_domain_by_dev_info(segment, + bridge_bus, + bridge_devfn); if (info) { iommu = info->iommu; domain = info->domain; -- GitLab From 5ae0566a0fffa09a77ac5996e3854fe91cd87167 Mon Sep 17 00:00:00 2001 From: Jiang Liu Date: Tue, 15 Apr 2014 10:35:35 +0800 Subject: [PATCH 262/797] iommu/vt-d: fix bug in matching PCI devices with DRHD/RMRR descriptors Commit "59ce0515cdaf iommu/vt-d: Update DRHD/RMRR/ATSR device scope caches when PCI hotplug happens" introduces a bug, which fails to match PCI devices with DMAR device scope entries if PCI path array in the entry has more than one level. For example, it fails to handle [1D2h 0466 1] Device Scope Entry Type : 01 [1D3h 0467 1] Entry Length : 0A [1D4h 0468 2] Reserved : 0000 [1D6h 0470 1] Enumeration ID : 00 [1D7h 0471 1] PCI Bus Number : 00 [1D8h 0472 2] PCI Path : 1C,04 [1DAh 0474 2] PCI Path : 00,02 And cause DMA failure on HP DL980 as: DMAR:[fault reason 02] Present bit in context entry is clear dmar: DRHD: handling fault status reg 602 dmar: DMAR:[DMA Read] Request device [02:00.2] fault addr 7f61e000 Reported-and-tested-by: Davidlohr Bueso Signed-off-by: Jiang Liu Signed-off-by: David Woodhouse --- drivers/iommu/dmar.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index f445c10df8df..39f8b717fe84 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -152,7 +152,8 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event) info->seg = pci_domain_nr(dev->bus); info->level = level; if (event == BUS_NOTIFY_ADD_DEVICE) { - for (tmp = dev, level--; tmp; tmp = tmp->bus->self) { + for (tmp = dev; tmp; tmp = tmp->bus->self) { + level--; info->path[level].device = PCI_SLOT(tmp->devfn); info->path[level].function = PCI_FUNC(tmp->devfn); if (pci_is_root_bus(tmp->bus)) -- GitLab From 6faff9b6bd3d2a279b806d721bb2257fdd2e6bf2 Mon Sep 17 00:00:00 2001 From: Max Schwarz Date: Sun, 9 Mar 2014 20:43:11 +0100 Subject: [PATCH 263/797] ARM: rockchip: rk3188: enable pull-ups on UART RX pins The default behaviour of the uart-rx pins on the rk3188 is to be pulled up and a lot of designs use diodes to even prevent them from being raised from the outside. Therefore change the rx-pin settings accordingly. This also fixes a uart receive problem on mass production Radxa Rock boards. Signed-off-by: Max Schwarz Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3188.dtsi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/rk3188.dtsi b/arch/arm/boot/dts/rk3188.dtsi index bb36596ea205..ed9a70af3e3f 100644 --- a/arch/arm/boot/dts/rk3188.dtsi +++ b/arch/arm/boot/dts/rk3188.dtsi @@ -149,7 +149,7 @@ uart0 { uart0_xfer: uart0-xfer { - rockchip,pins = , + rockchip,pins = , ; }; @@ -164,7 +164,7 @@ uart1 { uart1_xfer: uart1-xfer { - rockchip,pins = , + rockchip,pins = , ; }; @@ -179,7 +179,7 @@ uart2 { uart2_xfer: uart2-xfer { - rockchip,pins = , + rockchip,pins = , ; }; /* no rts / cts for uart2 */ @@ -187,7 +187,7 @@ uart3 { uart3_xfer: uart3-xfer { - rockchip,pins = , + rockchip,pins = , ; }; -- GitLab From 5c4348c1f959234664e4667f428cf82b3b8a7c2c Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Fri, 11 Apr 2014 11:44:24 +0200 Subject: [PATCH 264/797] ARM: rockchip: fix copy'n'paste error in smp error messages The error emitted when mapping the pmu failed, wrongly mentions the sram. Reported-by: Kent Borg Signed-off-by: Heiko Stuebner --- arch/arm/mach-rockchip/platsmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index dbfa5a26cfff..072842f6491b 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -152,7 +152,7 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) node = of_find_compatible_node(NULL, NULL, "rockchip,rk3066-pmu"); if (!node) { - pr_err("%s: could not find sram dt node\n", __func__); + pr_err("%s: could not find pmu dt node\n", __func__); return; } -- GitLab From c26ef3eb3c11274bad1b64498d0a134f85755250 Mon Sep 17 00:00:00 2001 From: Steven Miao Date: Tue, 15 Apr 2014 15:17:19 +0800 Subject: [PATCH 265/797] video: bf54x-lq043fb: fix build error Fix build error by including linux/gpio.h. Also drop asm/gpio.h which is not needed. Signed-off-by: Steven Miao Signed-off-by: Tomi Valkeinen --- drivers/video/bf54x-lq043fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 42b8f9d11018..e2c42ad8515a 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -49,13 +49,13 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include -- GitLab From f1c6bb2cb8b81013e8979806f8e15e3d53efb96d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 06:17:49 -0400 Subject: [PATCH 266/797] locks: allow __break_lease to sleep even when break_time is 0 A fl->fl_break_time of 0 has a special meaning to the lease break code that basically means "never break the lease". knfsd uses this to ensure that leases don't disappear out from under it. Unfortunately, the code in __break_lease can end up passing this value to wait_event_interruptible as a timeout, which prevents it from going to sleep at all. This makes __break_lease to spin in a tight loop and causes soft lockups. Fix this by ensuring that we pass a minimum value of 1 as a timeout instead. Cc: Cc: J. Bruce Fields Reported-by: Terry Barnaby Signed-off-by: Jeff Layton --- fs/locks.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 13fc7a6d380a..b380f5543614 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1391,11 +1391,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) restart: break_time = flock->fl_break_time; - if (break_time != 0) { + if (break_time != 0) break_time -= jiffies; - if (break_time == 0) - break_time++; - } + if (break_time == 0) + break_time++; locks_insert_block(flock, new_fl); spin_unlock(&inode->i_lock); error = wait_event_interruptible_timeout(new_fl->fl_wait, -- GitLab From 5ac96345899be859529e05af42f708ae7bd65782 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Apr 2014 16:18:41 +0300 Subject: [PATCH 267/797] drm/omap: print warning when rotating non-TILER fb Print a warning when the user tries to rotate a non-TILER framebuffer. Also set the rotation to 0, to avoid constant flood of the warnings in case of page flipping. Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_fb.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index d2b8c49bfb4a..8b019602ffe6 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -218,6 +218,20 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb, info->rotation_type = OMAP_DSS_ROT_TILER; info->screen_width = omap_gem_tiled_stride(plane->bo, orient); } else { + switch (win->rotation & 0xf) { + case 0: + case BIT(DRM_ROTATE_0): + /* OK */ + break; + + default: + dev_warn(fb->dev->dev, + "rotation '%d' ignored for non-tiled fb\n", + win->rotation); + win->rotation = 0; + break; + } + info->paddr = get_linear_addr(plane, format, 0, x, y); info->rotation_type = OMAP_DSS_ROT_DMA; info->screen_width = plane->pitch; -- GitLab From 772cdc9777403f10c4229c49645024a502dfd783 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 9 Apr 2014 14:51:01 +0300 Subject: [PATCH 268/797] drm/omap: remove extra plane->destroy from crtc destroy All the planes, including primary planes, are now destroyed by the drm framework. Thus we no longer need the explicit call to plane->destroy from the crtc's destroy function. This patch removes the call, thus fixing the crash caused by double freeing the plane. remove omap_crtc->plane->funcs->destroy(omap_crtc->plane) Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_crtc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index f59ef9359e66..b3a7529845b9 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -197,7 +197,6 @@ static void omap_crtc_destroy(struct drm_crtc *crtc) WARN_ON(omap_crtc->apply_irq.registered); omap_irq_unregister(crtc->dev, &omap_crtc->error_irq); - omap_crtc->plane->funcs->destroy(omap_crtc->plane); drm_crtc_cleanup(crtc); kfree(omap_crtc); -- GitLab From b841aedfcfd543d836c856bfde5a17c51cab6b26 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 10 Apr 2014 08:57:55 +0300 Subject: [PATCH 269/797] drm/omap: remove warn from debugfs Patch dfe96ddcfa22b44100814b9435770f6ff1309d37 (omapdrm: simplify locking in the fb debugfs file) removed taking locks when using omapdrm's debugfs to dump fb objects. However, in omap_gem_describe we give a WARN is the lock has not been taken, so that WARN is now seen every time omapdrm debugfs is used. So, presuming the removal of locks is ok, we can also remove the WARN. Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_gem.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index c8d972763889..70798b9fe635 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -980,12 +980,9 @@ int omap_gem_resume(struct device *dev) #ifdef CONFIG_DEBUG_FS void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m) { - struct drm_device *dev = obj->dev; struct omap_gem_object *omap_obj = to_omap_bo(obj); uint64_t off; - WARN_ON(!mutex_is_locked(&dev->struct_mutex)); - off = drm_vma_node_start(&obj->vma_node); seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d", -- GitLab From 15ec2ca964d7a52e7e0a452fe0f9c409d2f3eec6 Mon Sep 17 00:00:00 2001 From: Subhajit Paul Date: Fri, 11 Apr 2014 12:53:30 +0530 Subject: [PATCH 270/797] drm/omap: Fix memory leak in omap_gem_op_async In omap_gem_op_async(), if a waiter is not added to the wait list, it needs to be free'd in the function itself. Make sure we free the waiter for this case. Signed-off-by: Subhajit Paul Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_gem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 70798b9fe635..9a68e9a28438 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1226,6 +1226,8 @@ int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op, } spin_unlock(&sync_lock); + + kfree(waiter); } /* no waiting.. */ -- GitLab From f2cff0f34ff2c51f703880a2b883ea0c9de4a5ac Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 11 Apr 2014 12:53:31 +0530 Subject: [PATCH 271/797] drm/omap: gem sync: wait on correct events A waiter of the type OMAP_GEM_READ should wait for a buffer to be completely written, and only then proceed with reading it. A similar logic applies for waiters with OMAP_GEM_WRITE flag. Currently the function is_waiting() waits on the read_complete/read_target counts in the sync object. This should be the other way round, as a reader should wait for users who are 'writing' to this buffer, and vice versa. Make readers of the buffer(OMAP_GEM_READ) wait on the write counters, and writers to the buffer(OMAP_GEM_WRITE) wait on the read counters in is_waiting() Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_gem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 9a68e9a28438..95dbce286a41 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1047,10 +1047,10 @@ static inline bool is_waiting(struct omap_gem_sync_waiter *waiter) { struct omap_gem_object *omap_obj = waiter->omap_obj; if ((waiter->op & OMAP_GEM_READ) && - (omap_obj->sync->read_complete < waiter->read_target)) + (omap_obj->sync->write_complete < waiter->write_target)) return true; if ((waiter->op & OMAP_GEM_WRITE) && - (omap_obj->sync->write_complete < waiter->write_target)) + (omap_obj->sync->read_complete < waiter->read_target)) return true; return false; } -- GitLab From 71b6667765c7019f3fd5ea5e0c02f65f7331f3e1 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 11 Apr 2014 12:53:32 +0530 Subject: [PATCH 272/797] drm/omap: Fix crash when using LCD3 overlay manager The channel_names list didn't have a string populated for LCD3 manager, this results in a crash when the display's output is connected to LCD3. Add an entry for LCD3. Reported-by: Somnath Mukherjee Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_crtc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index b3a7529845b9..46f8e1e40e88 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -654,6 +654,7 @@ static const char *channel_names[] = { [OMAP_DSS_CHANNEL_LCD] = "lcd", [OMAP_DSS_CHANNEL_DIGIT] = "tv", [OMAP_DSS_CHANNEL_LCD2] = "lcd2", + [OMAP_DSS_CHANNEL_LCD3] = "lcd3", }; void omap_crtc_pre_init(void) -- GitLab From bc905aced30e48a39af7c452bf46228d7c6188b9 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 11 Apr 2014 12:53:34 +0530 Subject: [PATCH 273/797] drm/omap: Use old_fb to synchronize between successive page flips omap_crtc->old_fb is used to check whether the previous page flip has completed or not. However, it's never initialized to anything, so it's always NULL. This results in the check to always succeed, and the page_flip to proceed. Initialize old_fb to the fb that we intend to flip to through page_flip, and therefore prevent a future page flip to proceed if the last one didn't complete. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 46f8e1e40e88..00798247190b 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -360,7 +360,7 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, } omap_crtc->event = event; - primary->fb = fb; + omap_crtc->old_fb = primary->fb = fb; /* * Hold a reference temporarily until the crtc is updated -- GitLab From 38e5597a03d2d1499a785230031c4f48e1d9c6b7 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 11 Apr 2014 12:53:35 +0530 Subject: [PATCH 274/797] drm/omap: protect omap_crtc's event with event_lock spinlock The vblank_cb callback and the page_flip ioctl can occur together in different CPU contexts. vblank_cb uses takes tje drm device's event_lock spinlock when sending the vblank event and updating omap_crtc->event and omap_crtc->od_fb. Use the same spinlock in page_flip, to make sure the above omap_crtc parameters are configured sequentially. Signed-off-by: Archit Taneja Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_crtc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 00798247190b..e3c47a8005ff 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -350,11 +350,15 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, struct omap_crtc *omap_crtc = to_omap_crtc(crtc); struct drm_plane *primary = crtc->primary; struct drm_gem_object *bo; + unsigned long flags; DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1, fb->base.id, event); + spin_lock_irqsave(&dev->event_lock, flags); + if (omap_crtc->old_fb) { + spin_unlock_irqrestore(&dev->event_lock, flags); dev_err(dev->dev, "already a pending flip\n"); return -EINVAL; } @@ -362,6 +366,8 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc, omap_crtc->event = event; omap_crtc->old_fb = primary->fb = fb; + spin_unlock_irqrestore(&dev->event_lock, flags); + /* * Hold a reference temporarily until the crtc is updated * and takes the reference to the bo. This avoids it -- GitLab From 16c50dcfc4c186ed09a4d80fbd511492d024a1c5 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 28 Feb 2014 15:37:10 +0000 Subject: [PATCH 275/797] iommu/arm-smmu: Return 0 on unmap failure The IOMMU core expects the unmap operation to return the number of bytes that have been unmapped or 0 on failure, a negative return value being treated like a number of bytes. Signed-off-by: Laurent Pinchart Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 8b89e33a89fe..69d001a71b22 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1499,7 +1499,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, ret = arm_smmu_handle_mapping(smmu_domain, iova, 0, size, 0); arm_smmu_tlb_inv_context(&smmu_domain->root_cfg); - return ret ? ret : size; + return ret ? 0 : size; } static phys_addr_t arm_smmu_iova_to_phys(struct iommu_domain *domain, -- GitLab From aca1bc4595c5757f01167ab5bfef2a4f8edfcf4f Mon Sep 17 00:00:00 2001 From: Bin Wang Date: Fri, 21 Mar 2014 10:06:07 +0000 Subject: [PATCH 276/797] iommu/arm-smmu: fix panic in arm_smmu_alloc_init_pte MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kernel panic happened when iommu_unmap a buffer larger than 2MB, more than expected pmd entries got “invalidated”, due to a wrong range passed to arm_smmu_alloc_init_pte. it was likely a typo, now we fix it, passing the correct "end" address to arm_smmu_alloc_init_pte. Signed-off-by: Bin Wang Signed-off-by: Will Deacon --- drivers/iommu/arm-smmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69d001a71b22..647c3c7fd742 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1381,7 +1381,7 @@ static int arm_smmu_alloc_init_pmd(struct arm_smmu_device *smmu, pud_t *pud, do { next = pmd_addr_end(addr, end); - ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, end, pfn, + ret = arm_smmu_alloc_init_pte(smmu, pmd, addr, next, pfn, prot, stage); phys += next - addr; } while (pmd++, addr = next, addr < end); -- GitLab From ae450a7d054cd1fe8d003a085858ca5b90cc74d9 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 10 Apr 2014 12:02:54 +0300 Subject: [PATCH 277/797] perf tools: Fix double free in perf test 21 (code-reading.c) perf_evlist__delete() deletes attached cpu and thread maps but the test is still using them, so remove them from the evlist before deleting it. Signed-off-by: Adrian Hunter Link: http://lkml.kernel.org/r/53465E3E.8070201@intel.com Signed-off-by: Jiri Olsa --- tools/perf/tests/code-reading.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c index 653a8fe2db95..bfb186900ac0 100644 --- a/tools/perf/tests/code-reading.c +++ b/tools/perf/tests/code-reading.c @@ -504,6 +504,7 @@ static int do_test_code_reading(bool try_kcore) if (ret < 0) { if (!excl_kernel) { excl_kernel = true; + perf_evlist__set_maps(evlist, NULL, NULL); perf_evlist__delete(evlist); evlist = NULL; continue; -- GitLab From c9e87a472594fd237b2d19dcbe4a3424297f0b1a Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Mon, 14 Apr 2014 12:47:01 +0200 Subject: [PATCH 278/797] perf tools: Instead of redirecting flex output, use -o This gives us a real filename instead of having '' show up all over the place when debugging. Signed-off-by: Cody P Schafer Link: http://lkml.kernel.org/r/1396652539-2416-1-git-send-email-cody@linux.vnet.ibm.com Signed-off-by: Jiri Olsa --- tools/perf/Makefile.perf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 50d875d970c4..e96923310d57 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -192,13 +192,13 @@ endif export PERL_PATH $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c - $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c + $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l $(OUTPUT)util/parse-events-bison.c: util/parse-events.y $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_ $(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c - $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c + $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l $(OUTPUT)util/pmu-bison.c: util/pmu.y $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_ -- GitLab From 3b5b24315781c744ab3868edee931ddb2145e6b5 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Sat, 5 Apr 2014 23:35:53 +0200 Subject: [PATCH 279/797] ASoC: tlv320aic3x: fix shared reset pin for DT Currently the second tlv320aic3x instance fails to be probed from DT if the reset pin is shared with the first one. This patch fixes it by moving the list add of the reset pin into the i2c_probe method. Signed-off-by: Sebastian Reichel Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index b1835103e9b4..d7349bc89ad3 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1399,7 +1399,6 @@ static int aic3x_probe(struct snd_soc_codec *codec) } aic3x_add_widgets(codec); - list_add(&aic3x->list, &reset_list); return 0; @@ -1569,7 +1568,13 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aic3x, &aic3x_dai, 1); - return ret; + + if (ret != 0) + goto err_gpio; + + list_add(&aic3x->list, &reset_list); + + return 0; err_gpio: if (gpio_is_valid(aic3x->gpio_reset) && -- GitLab From 3608aeff47034faee7518ddec52d77fb811e952c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 31 Mar 2014 19:52:44 +0200 Subject: [PATCH 280/797] pata_samsung_cf: fix ata_host_activate() failure handling Add missing clk_disable() call to ata_host_activate() failure path. Cc: Ben Dooks Cc: Kukjin Kim Signed-off-by: Bartlomiej Zolnierkiewicz Reviewed-by: Jingoo Han Signed-off-by: Tejun Heo --- drivers/ata/pata_samsung_cf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index a79566d05666..0610e78c8a2a 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -594,9 +594,13 @@ static int __init pata_s3c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, host); - return ata_host_activate(host, info->irq, - info->irq ? pata_s3c_irq : NULL, - 0, &pata_s3c_sht); + ret = ata_host_activate(host, info->irq, + info->irq ? pata_s3c_irq : NULL, + 0, &pata_s3c_sht); + if (ret) + goto stop_clk; + + return 0; stop_clk: clk_disable(info->clk); -- GitLab From 8aaa414fadaec2b682168a5c937a3950a77956bf Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Tue, 15 Apr 2014 14:37:05 +0200 Subject: [PATCH 281/797] ASoC: alc5623: Fix regmap endianness Commit 0cd257bf9b9b0cbb4fa1a5c988a232506997867c, "ASoC: alc5623: Convert to direct regmap API usage" broke probing of the codec, because of wrong endinness of the ID and codec version read from the device. Fix this by removing the existing flipping of the endiannes, and extracting the codec type byte from the word from the regmap. Signed-off-by: Andrew Lunn Signed-off-by: Mark Brown --- sound/soc/codecs/alc5623.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index f500905e9373..2acf82f4a08a 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -1018,13 +1018,13 @@ static int alc5623_i2c_probe(struct i2c_client *client, dev_err(&client->dev, "failed to read vendor ID1: %d\n", ret); return ret; } - vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); ret = regmap_read(alc5623->regmap, ALC5623_VENDOR_ID2, &vid2); if (ret < 0) { dev_err(&client->dev, "failed to read vendor ID2: %d\n", ret); return ret; } + vid2 >>= 8; if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { dev_err(&client->dev, "unknown or wrong codec\n"); -- GitLab From f2d022aa421ca903a30f63b04528064b7eceaf5e Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 15 Apr 2014 16:26:01 +0300 Subject: [PATCH 282/797] drm/omap: fix the handling of fb ref counts With the recent primary-plane changes for drm, the primary plane's framebuffer needs to be ref counted the same way as for non-primary-planes. This was not done by the omapdrm driver, which caused the ref count to drop to 0 too early, causing problems. This patch moves the fb unref and ref from omap_plane_update to omap_plane_mode_set. This way the fb refs are updated for both primary and non-primary cases, as omap_plane_update calls omap_plane_mode_set. Signed-off-by: Tomi Valkeinen --- drivers/gpu/drm/omapdrm/omap_plane.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index df1725247cca..3cf31ee59aac 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -225,6 +225,11 @@ int omap_plane_mode_set(struct drm_plane *plane, omap_plane->apply_done_cb.arg = arg; } + if (plane->fb) + drm_framebuffer_unreference(plane->fb); + + drm_framebuffer_reference(fb); + plane->fb = fb; plane->crtc = crtc; @@ -241,11 +246,6 @@ static int omap_plane_update(struct drm_plane *plane, struct omap_plane *omap_plane = to_omap_plane(plane); omap_plane->enabled = true; - if (plane->fb) - drm_framebuffer_unreference(plane->fb); - - drm_framebuffer_reference(fb); - /* omap_plane_mode_set() takes adjusted src */ switch (omap_plane->win.rotation & 0xf) { case BIT(DRM_ROTATE_90): -- GitLab From 4461bbc05bf11fa4251acded60e4645863a4158a Mon Sep 17 00:00:00 2001 From: Boris Ostrovsky Date: Thu, 10 Apr 2014 12:17:09 -0400 Subject: [PATCH 283/797] x86/xen: Fix 32-bit PV guests's usage of kernel_stack Commit 198d208df4371734ac4728f69cb585c284d20a15 ("x86: Keep thread_info on thread stack in x86_32") made 32-bit kernels use kernel_stack to point to thread_info. That change missed a couple of updates needed by Xen's 32-bit PV guests: 1. kernel_stack needs to be initialized for secondary CPUs 2. GET_THREAD_INFO() now uses %fs register which may not be the kernel's version when executing xen_iret(). With respect to the second issue, we don't need GET_THREAD_INFO() anymore: we used it as an intermediate step to get to per_cpu xen_vcpu and avoid referencing %fs. Now that we are going to use %fs anyway we may as well go directly to xen_vcpu. Signed-off-by: Boris Ostrovsky Signed-off-by: David Vrabel --- arch/x86/xen/smp.c | 3 ++- arch/x86/xen/xen-asm_32.S | 25 +++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index a18eadd8bb40..7005974c3ff3 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c @@ -441,10 +441,11 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle) irq_ctx_init(cpu); #else clear_tsk_thread_flag(idle, TIF_FORK); +#endif per_cpu(kernel_stack, cpu) = (unsigned long)task_stack_page(idle) - KERNEL_STACK_OFFSET + THREAD_SIZE; -#endif + xen_setup_runstate_info(cpu); xen_setup_timer(cpu); xen_init_lock_cpu(cpu); diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S index 33ca6e42a4ca..fd92a64d748e 100644 --- a/arch/x86/xen/xen-asm_32.S +++ b/arch/x86/xen/xen-asm_32.S @@ -75,6 +75,17 @@ ENDPROC(xen_sysexit) * stack state in whatever form its in, we keep things simple by only * using a single register which is pushed/popped on the stack. */ + +.macro POP_FS +1: + popw %fs +.pushsection .fixup, "ax" +2: movw $0, (%esp) + jmp 1b +.popsection + _ASM_EXTABLE(1b,2b) +.endm + ENTRY(xen_iret) /* test eflags for special cases */ testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp) @@ -83,15 +94,13 @@ ENTRY(xen_iret) push %eax ESP_OFFSET=4 # bytes pushed onto stack - /* - * Store vcpu_info pointer for easy access. Do it this way to - * avoid having to reload %fs - */ + /* Store vcpu_info pointer for easy access */ #ifdef CONFIG_SMP - GET_THREAD_INFO(%eax) - movl %ss:TI_cpu(%eax), %eax - movl %ss:__per_cpu_offset(,%eax,4), %eax - mov %ss:xen_vcpu(%eax), %eax + pushw %fs + movl $(__KERNEL_PERCPU), %eax + movl %eax, %fs + movl %fs:xen_vcpu, %eax + POP_FS #else movl %ss:xen_vcpu, %eax #endif -- GitLab From 3a7745215e7f73a5c7d9bcdc50661a55b39052a3 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 14 Apr 2014 22:02:30 +0200 Subject: [PATCH 284/797] dm verity: fix biovecs hash calculation regression Commit 003b5c5719f159f4f4bf97511c4702a0638313dd ("block: Convert drivers to immutable biovecs") incorrectly converted biovec iteration in dm-verity to always calculate the hash from a full biovec, but the function only needs to calculate the hash from part of the biovec (up to the calculated "todo" value). Fix this issue by limiting hash input to only the requested data size. This problem was identified using the cryptsetup regression test for veritysetup (verity-compat-test). Signed-off-by: Milan Broz Acked-by: Mikulas Patocka Signed-off-by: Mike Snitzer Cc: stable@vger.kernel.org # 3.14+ --- drivers/md/dm-verity.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c index 796007a5e0e1..7a7bab8947ae 100644 --- a/drivers/md/dm-verity.c +++ b/drivers/md/dm-verity.c @@ -330,15 +330,17 @@ static int verity_verify_io(struct dm_verity_io *io) return r; } } - todo = 1 << v->data_dev_block_bits; - while (io->iter.bi_size) { + do { u8 *page; + unsigned len; struct bio_vec bv = bio_iter_iovec(bio, io->iter); page = kmap_atomic(bv.bv_page); - r = crypto_shash_update(desc, page + bv.bv_offset, - bv.bv_len); + len = bv.bv_len; + if (likely(len >= todo)) + len = todo; + r = crypto_shash_update(desc, page + bv.bv_offset, len); kunmap_atomic(page); if (r < 0) { @@ -346,8 +348,9 @@ static int verity_verify_io(struct dm_verity_io *io) return r; } - bio_advance_iter(bio, &io->iter, bv.bv_len); - } + bio_advance_iter(bio, &io->iter, len); + todo -= len; + } while (todo); if (!v->version) { r = crypto_shash_update(desc, v->salt, v->salt_size); -- GitLab From f6da9fe45c3074b909084ae9da5f55034ebffeb4 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 15 Apr 2014 10:28:04 +0200 Subject: [PATCH 285/797] irqchip: vic: Properly chain the cascaded IRQs We are flagging the parent IRQ as chained, then we must also make sure to call the chained_irq_[enter|exit] functions for things to work smoothly. Signed-off-by: Linus Walleij Link: http://lkml.kernel.org/r/1397550484-7119-1-git-send-email-linus.walleij@linaro.org Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-vic.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c index 37dab0b472cd..7d35287f9e90 100644 --- a/drivers/irqchip/irq-vic.c +++ b/drivers/irqchip/irq-vic.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -228,12 +229,17 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs) static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc) { u32 stat, hwirq; + struct irq_chip *host_chip = irq_desc_get_chip(desc); struct vic_device *vic = irq_desc_get_handler_data(desc); + chained_irq_enter(host_chip, desc); + while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) { hwirq = ffs(stat) - 1; generic_handle_irq(irq_find_mapping(vic->domain, hwirq)); } + + chained_irq_exit(host_chip, desc); } /* -- GitLab From cea37f87519ca3172a4e8ddd3ffcd2b4232b341f Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Tue, 1 Apr 2014 19:15:59 +0900 Subject: [PATCH 286/797] xen: fix memory leak in __xen_pcibk_add_pci_dev() It need to free dev_entry when it failed to assign to a new slot on the virtual PCI bus. smatch says: drivers/xen/xen-pciback/vpci.c:142 __xen_pcibk_add_pci_dev() warn: possible memory leak of 'dev_entry' Signed-off-by: Daeseok Youn Signed-off-by: David Vrabel --- drivers/xen/xen-pciback/vpci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c index 3165ce361b00..51afff96c515 100644 --- a/drivers/xen/xen-pciback/vpci.c +++ b/drivers/xen/xen-pciback/vpci.c @@ -137,6 +137,8 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, /* Publish this device. */ if (!err) err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid); + else + kfree(dev_entry); out: return err; -- GitLab From c0914e61660fa7d501ef9394b26f4847ef3dc98e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 28 Mar 2014 11:24:59 +0300 Subject: [PATCH 287/797] xen-pciback: silence an unwanted debug printk There is a missing curly brace here so we might print some extra debug information. Signed-off-by: Dan Carpenter Signed-off-by: David Vrabel --- drivers/xen/xen-pciback/pciback_ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index 929dd46bb40c..607e41460c0d 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c @@ -217,7 +217,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, if (result == 0) { for (i = 0; i < op->value; i++) { op->msix_entries[i].entry = entries[i].entry; - if (entries[i].vector) + if (entries[i].vector) { op->msix_entries[i].vector = xen_pirq_from_irq(entries[i].vector); if (unlikely(verbose_request)) @@ -225,6 +225,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, "MSI-X[%d]: %d\n", pci_name(dev), i, op->msix_entries[i].vector); + } } } else pr_warn_ratelimited("%s: error enabling MSI-X for guest %u: err %d!\n", -- GitLab From e0fc17a936334c08b2729fff87168c03fdecf5b6 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 4 Apr 2014 14:48:04 -0400 Subject: [PATCH 288/797] xen/spinlock: Don't enable them unconditionally. The git commit a945928ea2709bc0e8e8165d33aed855a0110279 ('xen: Do not enable spinlocks before jump_label_init() has executed') was added to deal with the jump machinery. Earlier the code that turned on the jump label was only called by Xen specific functions. But now that it had been moved to the initcall machinery it gets called on Xen, KVM, and baremetal - ouch!. And the detection machinery to only call it on Xen wasn't remembered in the heat of merge window excitement. This means that the slowpath is enabled on baremetal while it should not be. Reported-by: Waiman Long Acked-by: Steven Rostedt CC: stable@vger.kernel.org CC: Boris Ostrovsky Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: David Vrabel --- arch/x86/xen/spinlock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c index 4d3acc34a998..0ba5f3b967f0 100644 --- a/arch/x86/xen/spinlock.c +++ b/arch/x86/xen/spinlock.c @@ -274,7 +274,7 @@ void __init xen_init_spinlocks(void) printk(KERN_DEBUG "xen: PV spinlocks disabled\n"); return; } - + printk(KERN_DEBUG "xen: PV spinlocks enabled\n"); pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning); pv_lock_ops.unlock_kick = xen_unlock_kick; } @@ -290,6 +290,9 @@ static __init int xen_init_spinlocks_jump(void) if (!xen_pvspin) return 0; + if (!xen_domain()) + return 0; + static_key_slow_inc(¶virt_ticketlocks_enabled); return 0; } -- GitLab From 027bd7e89906a076225b23d1ca4b6702c84e72dc Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 4 Apr 2014 14:53:40 -0400 Subject: [PATCH 289/797] xen/xenbus: Avoid synchronous wait on XenBus stalling shutdown/restart. The 'read_reply' works with 'process_msg' to read of a reply in XenBus. 'process_msg' is running from within the 'xenbus' thread. Whenever a message shows up in XenBus it is put on a xs_state.reply_list list and 'read_reply' picks it up. The problem is if the backend domain or the xenstored process is killed. In which case 'xenbus' is still awaiting - and 'read_reply' if called - stuck forever waiting for the reply_list to have some contents. This is normally not a problem - as the backend domain can come back or the xenstored process can be restarted. However if the domain is in process of being powered off/restarted/halted - there is no point of waiting on it coming back - as we are effectively being terminated and should not impede the progress. This patch solves this problem by checking whether the guest is the right domain. If it is an initial domain and hurtling towards death - there is no point of continuing the wait. All other type of guests continue with their behavior (as Xenstore is expected to still be running in another domain). Fixes-Bug: http://bugs.xenproject.org/xen/bug/8 Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: Boris Ostrovsky Reviewed-by: David Vrabel Signed-off-by: David Vrabel --- drivers/xen/xenbus/xenbus_xs.c | 44 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index b6d5fff43d16..ba804f3d8278 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -50,6 +50,7 @@ #include #include #include "xenbus_comms.h" +#include "xenbus_probe.h" struct xs_stored_msg { struct list_head list; @@ -139,6 +140,29 @@ static int get_error(const char *errorstring) return xsd_errors[i].errnum; } +static bool xenbus_ok(void) +{ + switch (xen_store_domain_type) { + case XS_LOCAL: + switch (system_state) { + case SYSTEM_POWER_OFF: + case SYSTEM_RESTART: + case SYSTEM_HALT: + return false; + default: + break; + } + return true; + case XS_PV: + case XS_HVM: + /* FIXME: Could check that the remote domain is alive, + * but it is normally initial domain. */ + return true; + default: + break; + } + return false; +} static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) { struct xs_stored_msg *msg; @@ -148,9 +172,20 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len) while (list_empty(&xs_state.reply_list)) { spin_unlock(&xs_state.reply_lock); - /* XXX FIXME: Avoid synchronous wait for response here. */ - wait_event(xs_state.reply_waitq, - !list_empty(&xs_state.reply_list)); + if (xenbus_ok()) + /* XXX FIXME: Avoid synchronous wait for response here. */ + wait_event_timeout(xs_state.reply_waitq, + !list_empty(&xs_state.reply_list), + msecs_to_jiffies(500)); + else { + /* + * If we are in the process of being shut-down there is + * no point of trying to contact XenBus - it is either + * killed (xenstored application) or the other domain + * has been killed or is unreachable. + */ + return ERR_PTR(-EIO); + } spin_lock(&xs_state.reply_lock); } @@ -215,6 +250,9 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg) mutex_unlock(&xs_state.request_mutex); + if (IS_ERR(ret)) + return ret; + if ((msg->type == XS_TRANSACTION_END) || ((req_msg.type == XS_TRANSACTION_START) && (msg->type == XS_ERROR))) -- GitLab From eb47f71200b7d5b4c8c1f8c75675f592d855aafd Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Fri, 4 Apr 2014 14:53:41 -0400 Subject: [PATCH 290/797] xen/manage: Poweroff forcefully if user-space is not yet up. The user can launch the guest in this sequence: xl create -p /vm.cfg [launch, but pause it] xl shutdown latest [sets control/shutdown=poweroff] xl unpause latest xl console latest [and see that the guest has completely ignored the shutdown request] In reality the guest hasn't ignored it. It registers a watch and gets a notification that there is value. It then calls the shutdown_handler which ends up calling orderly_shutdown. Unfortunately that is so early in the bootup that there are no user-space. Which means that the orderly_shutdown fails. But since the force flag was set to false it continues on without reporting. What we really want to is to use the force when we are in the SYSTEM_BOOTING state and not use the 'force' when SYSTEM_RUNNING. However, if we are in the running state - and the shutdown command has been given before the user-space has been setup, there is nothing we can do. Worst yet, we stop ignoring the 'xl shutdown' requests! As such, the other part of this patch is to only stop ignoring the 'xl shutdown' when we are truly in the power off sequence. That means the user can do multiple 'xl shutdown' and we will try to act on them instead of ignoring them. Fixes-Bug: http://bugs.xenproject.org/xen/bug/6 Reported-by: Alex Bligh Signed-off-by: Konrad Rzeszutek Wilk Signed-off-by: David Vrabel --- drivers/xen/manage.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index fc6c94c0b436..32f9236c959f 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -198,10 +198,32 @@ struct shutdown_handler { void (*cb)(void); }; +static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused) +{ + switch (code) { + case SYS_DOWN: + case SYS_HALT: + case SYS_POWER_OFF: + shutting_down = SHUTDOWN_POWEROFF; + default: + break; + } + return NOTIFY_DONE; +} static void do_poweroff(void) { - shutting_down = SHUTDOWN_POWEROFF; - orderly_poweroff(false); + switch (system_state) { + case SYSTEM_BOOTING: + orderly_poweroff(true); + break; + case SYSTEM_RUNNING: + orderly_poweroff(false); + break; + default: + /* Don't do it when we are halting/rebooting. */ + pr_info("Ignoring Xen toolstack shutdown.\n"); + break; + } } static void do_reboot(void) @@ -307,6 +329,10 @@ static struct xenbus_watch shutdown_watch = { .callback = shutdown_handler }; +static struct notifier_block xen_reboot_nb = { + .notifier_call = poweroff_nb, +}; + static int setup_shutdown_watcher(void) { int err; @@ -317,6 +343,7 @@ static int setup_shutdown_watcher(void) return err; } + #ifdef CONFIG_MAGIC_SYSRQ err = register_xenbus_watch(&sysrq_watch); if (err) { @@ -345,6 +372,7 @@ int xen_setup_shutdown_event(void) if (!xen_domain()) return -ENODEV; register_xenstore_notifier(&xenstore_notifier); + register_reboot_notifier(&xen_reboot_nb); return 0; } -- GitLab From b0270e91014dabfceaf37f5b40ad51bbf21a1302 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 15 Apr 2014 12:58:34 -0400 Subject: [PATCH 291/797] ipv4: add a sock pointer to ip_queue_xmit() ip_queue_xmit() assumes the skb it has to transmit is attached to an inet socket. Commit 31c70d5956fc ("l2tp: keep original skb ownership") changed l2tp to not change skb ownership and thus broke this assumption. One fix is to add a new 'struct sock *sk' parameter to ip_queue_xmit(), so that we do not assume skb->sk points to the socket used by l2tp tunnel. Fixes: 31c70d5956fc ("l2tp: keep original skb ownership") Reported-by: Zhan Jianyu Tested-by: Zhan Jianyu Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/inet6_connection_sock.h | 2 +- include/net/inet_connection_sock.h | 2 +- include/net/ip.h | 2 +- net/dccp/output.c | 2 +- net/ipv4/ip_output.c | 5 +++-- net/ipv4/tcp_output.c | 2 +- net/ipv6/inet6_connection_sock.c | 3 +-- net/l2tp/l2tp_core.c | 4 ++-- net/l2tp/l2tp_ip.c | 2 +- net/sctp/protocol.c | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h index f981ba7adeed..74af137304be 100644 --- a/include/net/inet6_connection_sock.h +++ b/include/net/inet6_connection_sock.h @@ -40,7 +40,7 @@ void inet6_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); -int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl); +int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu); #endif /* _INET6_CONNECTION_SOCK_H */ diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index c55aeed41ace..7a4313887568 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -36,7 +36,7 @@ struct tcp_congestion_ops; * (i.e. things that depend on the address family) */ struct inet_connection_sock_af_ops { - int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl); + int (*queue_xmit)(struct sock *sk, struct sk_buff *skb, struct flowi *fl); void (*send_check)(struct sock *sk, struct sk_buff *skb); int (*rebuild_header)(struct sock *sk); void (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb); diff --git a/include/net/ip.h b/include/net/ip.h index 25064c28e059..77e73d293e09 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -111,7 +111,7 @@ int ip_do_nat(struct sk_buff *skb); void ip_send_check(struct iphdr *ip); int __ip_local_out(struct sk_buff *skb); int ip_local_out(struct sk_buff *skb); -int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl); +int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); void ip_init(void); int ip_append_data(struct sock *sk, struct flowi4 *fl4, int getfrag(void *from, char *to, int offset, int len, diff --git a/net/dccp/output.c b/net/dccp/output.c index 8876078859da..0248e8a3460c 100644 --- a/net/dccp/output.c +++ b/net/dccp/output.c @@ -138,7 +138,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb) DCCP_INC_STATS(DCCP_MIB_OUTSEGS); - err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl); + err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl); return net_xmit_eval(err); } return -ENOBUFS; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 1a0755fea491..7ad68b860935 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -315,9 +315,9 @@ static void ip_copy_addrs(struct iphdr *iph, const struct flowi4 *fl4) sizeof(fl4->saddr) + sizeof(fl4->daddr)); } -int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl) +/* Note: skb->sk can be different from sk, in case of tunnels */ +int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl) { - struct sock *sk = skb->sk; struct inet_sock *inet = inet_sk(sk); struct ip_options_rcu *inet_opt; struct flowi4 *fl4; @@ -389,6 +389,7 @@ int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl) ip_select_ident_more(skb, &rt->dst, sk, (skb_shinfo(skb)->gso_segs ?: 1) - 1); + /* TODO : should we use skb->sk here instead of sk ? */ skb->priority = sk->sk_priority; skb->mark = sk->sk_mark; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 699fb102e971..025e25093984 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -981,7 +981,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, tcp_skb_pcount(skb)); - err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl); + err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl); if (likely(err <= 0)) return err; diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c index c9138189415a..d4ade34ab375 100644 --- a/net/ipv6/inet6_connection_sock.c +++ b/net/ipv6/inet6_connection_sock.c @@ -224,9 +224,8 @@ static struct dst_entry *inet6_csk_route_socket(struct sock *sk, return dst; } -int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused) +int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused) { - struct sock *sk = skb->sk; struct ipv6_pinfo *np = inet6_sk(sk); struct flowi6 fl6; struct dst_entry *dst; diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 47f7a5490555..a4e37d7158dc 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1131,10 +1131,10 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, skb->local_df = 1; #if IS_ENABLED(CONFIG_IPV6) if (tunnel->sock->sk_family == PF_INET6 && !tunnel->v4mapped) - error = inet6_csk_xmit(skb, NULL); + error = inet6_csk_xmit(tunnel->sock, skb, NULL); else #endif - error = ip_queue_xmit(skb, fl); + error = ip_queue_xmit(tunnel->sock, skb, fl); /* Update stats */ if (error >= 0) { diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 0b44d855269c..3397fe6897c0 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c @@ -487,7 +487,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m xmit: /* Queue the packet to IP for output */ - rc = ip_queue_xmit(skb, &inet->cork.fl); + rc = ip_queue_xmit(sk, skb, &inet->cork.fl); rcu_read_unlock(); error: diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 4e1d0fcb028e..c09757fbf803 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -957,7 +957,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb, SCTP_INC_STATS(sock_net(&inet->sk), SCTP_MIB_OUTSCTPPACKS); - return ip_queue_xmit(skb, &transport->fl); + return ip_queue_xmit(&inet->sk, skb, &transport->fl); } static struct sctp_af sctp_af_inet; -- GitLab From 3063a12be2b07c64e9802708a19489342e64c1a3 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 28 Mar 2014 14:31:47 -0500 Subject: [PATCH 292/797] usb: musb: fix PHY power on/off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commi 30a70b0 (usb: musb: fix obex in g_nokia.ko causing kernel panic) removed phy_power_on() and phy_power_off() calls from runtime PM callbacks but it failed to note that the driver depended on pm_runtime_get_sync() calls to power up the PHY, thus leaving some platforms without any means to have a working PHY. Fix that by enabling the phy during omap2430_musb_init() and killing it in omap2430_musb_exit(). Fixes: 30a70b0 (usb: musb: fix obex in g_nokia.ko causing kernel panic) Cc: # v3.14 Cc: Pali Rohár Cc: Ivaylo Dimitrov Reported-by: Michael Scott Tested-by: Michael Scott Tested-by: Stefan Roese Reported-by: Rabin Vincent Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index d341c149a2f9..819a7cdcb866 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -416,6 +416,7 @@ static int omap2430_musb_init(struct musb *musb) omap_musb_set_mailbox(glue); phy_init(musb->phy); + phy_power_on(musb->phy); pm_runtime_put_noidle(musb->controller); return 0; @@ -478,6 +479,7 @@ static int omap2430_musb_exit(struct musb *musb) del_timer_sync(&musb_idle_timer); omap2430_low_level_exit(musb); + phy_power_off(musb->phy); phy_exit(musb->phy); return 0; -- GitLab From 8b2bc2c9351b4c09bc3d9096e2a7af3988565dbf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 7 Apr 2014 10:58:01 -0500 Subject: [PATCH 293/797] usb: musb: omap2430: make sure clocks are enabled when running mailbox on early initialization we could fall into a situation where the mailbox is called before MUSB's clocks are running, in order to avoid that, make sure mailbox is always wrapped with pm_runtime calls. Reported-by: Stefan Roese Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 819a7cdcb866..d369bf1f3936 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -316,7 +316,13 @@ static void omap_musb_mailbox_work(struct work_struct *mailbox_work) { struct omap2430_glue *glue = container_of(mailbox_work, struct omap2430_glue, omap_musb_mailbox_work); + struct musb *musb = glue_to_musb(glue); + struct device *dev = musb->controller; + + pm_runtime_get_sync(dev); omap_musb_set_mailbox(glue); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); } static irqreturn_t omap2430_musb_interrupt(int irq, void *__hci) -- GitLab From 20474129d8bb0e6f113634f4f0f4f1584d0beed2 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 14 Apr 2014 15:31:05 -0700 Subject: [PATCH 294/797] mwifiex: process event before command response During extended scan, SCAN report event is always followed by command response. Sometimes It is observed that command response is processed before SCAN report which leads to a crash, because current command node is cleared while handling the response. This patch makes sure that driver's main thread gives priority to events over command responses. Signed-off-by: Amitkumar Karwar Signed-off-by: Maithili Hinge Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 77db0886c6e2..9c771b3e9918 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -292,6 +292,12 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) mwifiex_handle_rx_packet(adapter, skb); + /* Check for event */ + if (adapter->event_received) { + adapter->event_received = false; + mwifiex_process_event(adapter); + } + /* Check for Cmd Resp */ if (adapter->cmd_resp_received) { adapter->cmd_resp_received = false; @@ -304,12 +310,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) } } - /* Check for event */ - if (adapter->event_received) { - adapter->event_received = false; - mwifiex_process_event(adapter); - } - /* Check if we need to confirm Sleep Request received previously */ if (adapter->ps_state == PS_STATE_PRE_SLEEP) { -- GitLab From f8d2b9209ad648a8e9aa973d32fb64aa2ab01d00 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Mon, 14 Apr 2014 15:31:06 -0700 Subject: [PATCH 295/797] mwifiex: fix hung task on command timeout Sometimes when command timeout occurs due to a firmware or hardware bug, there may be some synchronous commands in command queue. These commands are never downloaded to firmware causing hung task warnings. This patch replaces wait_event_interruptible call with wait_event_interruptible_timeout to fix the issue. Signed-off-by: Amitkumar Karwar Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/sta_ioctl.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 894270611f2c..536c14aa71f3 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -60,9 +60,10 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, int status; /* Wait for completion */ - status = wait_event_interruptible(adapter->cmd_wait_q.wait, - *(cmd_queued->condition)); - if (status) { + status = wait_event_interruptible_timeout(adapter->cmd_wait_q.wait, + *(cmd_queued->condition), + (12 * HZ)); + if (status <= 0) { dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); mwifiex_cancel_all_pending_cmd(adapter); return status; -- GitLab From aad88724c9d54acb1a9737cb6069d8470fa85f74 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 15 Apr 2014 13:47:15 -0400 Subject: [PATCH 296/797] ipv4: add a sock pointer to dst->output() path. In the dst->output() path for ipv4, the code assumes the skb it has to transmit is attached to an inet socket, specifically via ip_mc_output() : The sk_mc_loop() test triggers a WARN_ON() when the provider of the packet is an AF_PACKET socket. The dst->output() method gets an additional 'struct sock *sk' parameter. This needs a cascade of changes so that this parameter can be propagated from vxlan to final consumer. Fixes: 8f646c922d55 ("vxlan: keep original skb ownership") Reported-by: lucien xin Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 4 ++-- include/net/dst.h | 14 +++++++++++--- include/net/ip.h | 11 ++++++++--- include/net/ip_tunnels.h | 2 +- include/net/ipv6.h | 2 +- include/net/xfrm.h | 6 +++--- net/core/dst.c | 15 +++++++++------ net/decnet/dn_route.c | 16 ++++++++++++++-- net/ipv4/ip_output.c | 11 +++++------ net/ipv4/ip_tunnel.c | 2 +- net/ipv4/ip_tunnel_core.c | 4 ++-- net/ipv4/route.c | 4 ++-- net/ipv4/xfrm4_output.c | 2 +- net/ipv6/ip6_output.c | 2 +- net/ipv6/route.c | 14 +++++++------- net/ipv6/sit.c | 5 +++-- net/ipv6/xfrm6_output.c | 2 +- net/openvswitch/vport-gre.c | 2 +- net/xfrm/xfrm_policy.c | 2 +- 19 files changed, 74 insertions(+), 46 deletions(-) diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index c55e316373a1..82355d5d155a 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1755,8 +1755,8 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, if (err) return err; - return iptunnel_xmit(rt, skb, src, dst, IPPROTO_UDP, tos, ttl, df, - false); + return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP, + tos, ttl, df, false); } EXPORT_SYMBOL_GPL(vxlan_xmit_skb); diff --git a/include/net/dst.h b/include/net/dst.h index 46ed958e0c6e..71c60f42be48 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -45,7 +45,7 @@ struct dst_entry { void *__pad1; #endif int (*input)(struct sk_buff *); - int (*output)(struct sk_buff *); + int (*output)(struct sock *sk, struct sk_buff *skb); unsigned short flags; #define DST_HOST 0x0001 @@ -367,7 +367,11 @@ static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) return child; } -int dst_discard(struct sk_buff *skb); +int dst_discard_sk(struct sock *sk, struct sk_buff *skb); +static inline int dst_discard(struct sk_buff *skb) +{ + return dst_discard_sk(skb->sk, skb); +} void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, int initial_obsolete, unsigned short flags); void __dst_free(struct dst_entry *dst); @@ -449,9 +453,13 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) } /* Output packet to network from transport. */ +static inline int dst_output_sk(struct sock *sk, struct sk_buff *skb) +{ + return skb_dst(skb)->output(sk, skb); +} static inline int dst_output(struct sk_buff *skb) { - return skb_dst(skb)->output(skb); + return dst_output_sk(skb->sk, skb); } /* Input packet from network to transport. */ diff --git a/include/net/ip.h b/include/net/ip.h index 77e73d293e09..3ec2b0fb9d83 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -104,13 +104,18 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); int ip_local_deliver(struct sk_buff *skb); int ip_mr_input(struct sk_buff *skb); -int ip_output(struct sk_buff *skb); -int ip_mc_output(struct sk_buff *skb); +int ip_output(struct sock *sk, struct sk_buff *skb); +int ip_mc_output(struct sock *sk, struct sk_buff *skb); int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); int ip_do_nat(struct sk_buff *skb); void ip_send_check(struct iphdr *ip); int __ip_local_out(struct sk_buff *skb); -int ip_local_out(struct sk_buff *skb); +int ip_local_out_sk(struct sock *sk, struct sk_buff *skb); +static inline int ip_local_out(struct sk_buff *skb) +{ + return ip_local_out_sk(skb->sk, skb); +} + int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); void ip_init(void); int ip_append_data(struct sock *sk, struct flowi4 *fl4, diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index e77c10405d51..a4daf9eb8562 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -153,7 +153,7 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph, } int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto); -int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, +int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl, __be16 df, bool xnet); diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 4f541f11ce63..d640925bc454 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -731,7 +731,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, * skb processing functions */ -int ip6_output(struct sk_buff *skb); +int ip6_output(struct sock *sk, struct sk_buff *skb); int ip6_forward(struct sk_buff *skb); int ip6_input(struct sk_buff *skb); int ip6_mc_input(struct sk_buff *skb); diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 32682ae47b3f..116e9c7e19cb 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -333,7 +333,7 @@ struct xfrm_state_afinfo { const xfrm_address_t *saddr); int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); - int (*output)(struct sk_buff *skb); + int (*output)(struct sock *sk, struct sk_buff *skb); int (*output_finish)(struct sk_buff *skb); int (*extract_input)(struct xfrm_state *x, struct sk_buff *skb); @@ -1540,7 +1540,7 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb); int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb); -int xfrm4_output(struct sk_buff *skb); +int xfrm4_output(struct sock *sk, struct sk_buff *skb); int xfrm4_output_finish(struct sk_buff *skb); int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err); int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol); @@ -1565,7 +1565,7 @@ __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); -int xfrm6_output(struct sk_buff *skb); +int xfrm6_output(struct sock *sk, struct sk_buff *skb); int xfrm6_output_finish(struct sk_buff *skb); int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, u8 **prevhdr); diff --git a/net/core/dst.c b/net/core/dst.c index ca4231ec7347..80d6286c8b62 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -142,12 +142,12 @@ static void dst_gc_task(struct work_struct *work) mutex_unlock(&dst_gc_mutex); } -int dst_discard(struct sk_buff *skb) +int dst_discard_sk(struct sock *sk, struct sk_buff *skb) { kfree_skb(skb); return 0; } -EXPORT_SYMBOL(dst_discard); +EXPORT_SYMBOL(dst_discard_sk); const u32 dst_default_metrics[RTAX_MAX + 1] = { /* This initializer is needed to force linker to place this variable @@ -184,7 +184,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, dst->xfrm = NULL; #endif dst->input = dst_discard; - dst->output = dst_discard; + dst->output = dst_discard_sk; dst->error = 0; dst->obsolete = initial_obsolete; dst->header_len = 0; @@ -209,8 +209,10 @@ static void ___dst_free(struct dst_entry *dst) /* The first case (dev==NULL) is required, when protocol module is unloaded. */ - if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) - dst->input = dst->output = dst_discard; + if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) { + dst->input = dst_discard; + dst->output = dst_discard_sk; + } dst->obsolete = DST_OBSOLETE_DEAD; } @@ -361,7 +363,8 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev, return; if (!unregister) { - dst->input = dst->output = dst_discard; + dst->input = dst_discard; + dst->output = dst_discard_sk; } else { dst->dev = dev_net(dst->dev)->loopback_dev; dev_hold(dst->dev); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index ce0cbbfe0f43..daccc4a36d80 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -752,7 +752,7 @@ static int dn_to_neigh_output(struct sk_buff *skb) return n->output(n, skb); } -static int dn_output(struct sk_buff *skb) +static int dn_output(struct sock *sk, struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); struct dn_route *rt = (struct dn_route *)dst; @@ -838,6 +838,18 @@ static int dn_forward(struct sk_buff *skb) * Used to catch bugs. This should never normally get * called. */ +static int dn_rt_bug_sk(struct sock *sk, struct sk_buff *skb) +{ + struct dn_skb_cb *cb = DN_SKB_CB(skb); + + net_dbg_ratelimited("dn_rt_bug: skb from:%04x to:%04x\n", + le16_to_cpu(cb->src), le16_to_cpu(cb->dst)); + + kfree_skb(skb); + + return NET_RX_DROP; +} + static int dn_rt_bug(struct sk_buff *skb) { struct dn_skb_cb *cb = DN_SKB_CB(skb); @@ -1463,7 +1475,7 @@ static int dn_route_input_slow(struct sk_buff *skb) rt->n = neigh; rt->dst.lastuse = jiffies; - rt->dst.output = dn_rt_bug; + rt->dst.output = dn_rt_bug_sk; switch (res.type) { case RTN_UNICAST: rt->dst.input = dn_forward; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 7ad68b860935..1cbeba5edff9 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -101,17 +101,17 @@ int __ip_local_out(struct sk_buff *skb) skb_dst(skb)->dev, dst_output); } -int ip_local_out(struct sk_buff *skb) +int ip_local_out_sk(struct sock *sk, struct sk_buff *skb) { int err; err = __ip_local_out(skb); if (likely(err == 1)) - err = dst_output(skb); + err = dst_output_sk(sk, skb); return err; } -EXPORT_SYMBOL_GPL(ip_local_out); +EXPORT_SYMBOL_GPL(ip_local_out_sk); static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) { @@ -226,9 +226,8 @@ static int ip_finish_output(struct sk_buff *skb) return ip_finish_output2(skb); } -int ip_mc_output(struct sk_buff *skb) +int ip_mc_output(struct sock *sk, struct sk_buff *skb) { - struct sock *sk = skb->sk; struct rtable *rt = skb_rtable(skb); struct net_device *dev = rt->dst.dev; @@ -287,7 +286,7 @@ int ip_mc_output(struct sk_buff *skb) !(IPCB(skb)->flags & IPSKB_REROUTED)); } -int ip_output(struct sk_buff *skb) +int ip_output(struct sock *sk, struct sk_buff *skb) { struct net_device *dev = skb_dst(skb)->dev; diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e77381d1df9a..484d0ce27ef7 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -670,7 +670,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, return; } - err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol, + err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol, tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); iptunnel_xmit_stats(err, &dev->stats, dev->tstats); diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index e0c2b1d2ea4e..bcf206c79005 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -46,7 +46,7 @@ #include #include -int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, +int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, __be32 src, __be32 dst, __u8 proto, __u8 tos, __u8 ttl, __be16 df, bool xnet) { @@ -76,7 +76,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, iph->ttl = ttl; __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); - err = ip_local_out(skb); + err = ip_local_out_sk(sk, skb); if (unlikely(net_xmit_eval(err))) pkt_len = 0; return pkt_len; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 20a59c388e6e..1485aafcad59 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1129,7 +1129,7 @@ static void ipv4_link_failure(struct sk_buff *skb) dst_set_expires(&rt->dst, 0); } -static int ip_rt_bug(struct sk_buff *skb) +static int ip_rt_bug(struct sock *sk, struct sk_buff *skb) { pr_debug("%s: %pI4 -> %pI4, %s\n", __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, @@ -2218,7 +2218,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or new->__use = 1; new->input = dst_discard; - new->output = dst_discard; + new->output = dst_discard_sk; new->dev = ort->dst.dev; if (new->dev) diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index baa0f63731fd..40e701f2e1e0 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -86,7 +86,7 @@ int xfrm4_output_finish(struct sk_buff *skb) return xfrm_output(skb); } -int xfrm4_output(struct sk_buff *skb) +int xfrm4_output(struct sock *sk, struct sk_buff *skb) { struct dst_entry *dst = skb_dst(skb); struct xfrm_state *x = dst->xfrm; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 3284d61577c0..40e7581374f7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -132,7 +132,7 @@ static int ip6_finish_output(struct sk_buff *skb) return ip6_finish_output2(skb); } -int ip6_output(struct sk_buff *skb) +int ip6_output(struct sock *sk, struct sk_buff *skb) { struct net_device *dev = skb_dst(skb)->dev; struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 5ea462eacd9f..4011617cca68 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -84,9 +84,9 @@ static void ip6_dst_ifdown(struct dst_entry *, static int ip6_dst_gc(struct dst_ops *ops); static int ip6_pkt_discard(struct sk_buff *skb); -static int ip6_pkt_discard_out(struct sk_buff *skb); +static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb); static int ip6_pkt_prohibit(struct sk_buff *skb); -static int ip6_pkt_prohibit_out(struct sk_buff *skb); +static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb); static void ip6_link_failure(struct sk_buff *skb); static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb, u32 mtu); @@ -290,7 +290,7 @@ static const struct rt6_info ip6_blk_hole_entry_template = { .obsolete = DST_OBSOLETE_FORCE_CHK, .error = -EINVAL, .input = dst_discard, - .output = dst_discard, + .output = dst_discard_sk, }, .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP), .rt6i_protocol = RTPROT_KERNEL, @@ -1058,7 +1058,7 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori new->__use = 1; new->input = dst_discard; - new->output = dst_discard; + new->output = dst_discard_sk; if (dst_metrics_read_only(&ort->dst)) new->_metrics = ort->dst._metrics; @@ -1577,7 +1577,7 @@ int ip6_route_add(struct fib6_config *cfg) switch (cfg->fc_type) { case RTN_BLACKHOLE: rt->dst.error = -EINVAL; - rt->dst.output = dst_discard; + rt->dst.output = dst_discard_sk; rt->dst.input = dst_discard; break; case RTN_PROHIBIT: @@ -2129,7 +2129,7 @@ static int ip6_pkt_discard(struct sk_buff *skb) return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_INNOROUTES); } -static int ip6_pkt_discard_out(struct sk_buff *skb) +static int ip6_pkt_discard_out(struct sock *sk, struct sk_buff *skb) { skb->dev = skb_dst(skb)->dev; return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES); @@ -2140,7 +2140,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb) return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_INNOROUTES); } -static int ip6_pkt_prohibit_out(struct sk_buff *skb) +static int ip6_pkt_prohibit_out(struct sock *sk, struct sk_buff *skb) { skb->dev = skb_dst(skb)->dev; return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES); diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 1693c8d885f0..8da8268d65f8 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -974,8 +974,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, goto out; } - err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, IPPROTO_IPV6, tos, - ttl, df, !net_eq(tunnel->net, dev_net(dev))); + err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, + IPPROTO_IPV6, tos, ttl, df, + !net_eq(tunnel->net, dev_net(dev))); iptunnel_xmit_stats(err, &dev->stats, dev->tstats); return NETDEV_TX_OK; diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 6cd625e37706..19ef329bdbf8 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -163,7 +163,7 @@ static int __xfrm6_output(struct sk_buff *skb) return x->outer_mode->afinfo->output_finish(skb); } -int xfrm6_output(struct sk_buff *skb) +int xfrm6_output(struct sock *sk, struct sk_buff *skb) { return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, skb_dst(skb)->dev, __xfrm6_output); diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index a3d6951602db..ebb6e2442554 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c @@ -174,7 +174,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) skb->local_df = 1; - return iptunnel_xmit(rt, skb, fl.saddr, + return iptunnel_xmit(skb->sk, rt, skb, fl.saddr, OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, OVS_CB(skb)->tun_key->ipv4_tos, OVS_CB(skb)->tun_key->ipv4_ttl, df, false); diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index f02f511b7107..c08fbd11ceff 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -1842,7 +1842,7 @@ static void xfrm_policy_queue_process(unsigned long arg) xfrm_pol_put(pol); } -static int xdst_queue_output(struct sk_buff *skb) +static int xdst_queue_output(struct sock *sk, struct sk_buff *skb) { unsigned long sched_next; struct dst_entry *dst = skb_dst(skb); -- GitLab From 521c42990e9d561ed5ed9f501f07639d0512b3c9 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 15 Apr 2014 10:54:37 +0530 Subject: [PATCH 297/797] tick-common: Fix wrong check in tick_check_replacement() tick_check_replacement() returns if a replacement of clock_event_device is possible or not. It does this as the first check: if (tick_check_percpu(curdev, newdev, smp_processor_id())) return false; Thats wrong. tick_check_percpu() returns true when the device is useable. Check for false instead. [ tglx: Massaged changelog ] Signed-off-by: Viresh Kumar Cc: # v3.11+ Cc: linaro-kernel@lists.linaro.org Cc: fweisbec@gmail.com Cc: Arvind.Chauhan@arm.com Cc: linaro-networking@linaro.org Link: http://lkml.kernel.org/r/486a02efe0246635aaba786e24b42d316438bf3b.1397537987.git.viresh.kumar@linaro.org Signed-off-by: Thomas Gleixner --- kernel/time/tick-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 015661279b68..0a0608edeb26 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -276,7 +276,7 @@ static bool tick_check_preferred(struct clock_event_device *curdev, bool tick_check_replacement(struct clock_event_device *curdev, struct clock_event_device *newdev) { - if (tick_check_percpu(curdev, newdev, smp_processor_id())) + if (!tick_check_percpu(curdev, newdev, smp_processor_id())) return false; return tick_check_preferred(curdev, newdev); -- GitLab From 03e6bdc5c4d0fc166bfd5d3cf749a5a0c1b5b1bd Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 15 Apr 2014 10:54:40 +0530 Subject: [PATCH 298/797] tick-sched: Don't call update_wall_time() when delta is lesser than tick_period In tick_do_update_jiffies64() we are processing ticks only if delta is greater than tick_period. This is what we are supposed to do here and it broke a bit with this patch: commit 47a1b796 (tick/timekeeping: Call update_wall_time outside the jiffies lock) With above patch, we might end up calling update_wall_time() even if delta is found to be smaller that tick_period. Fix this by returning when the delta is less than tick period. [ tglx: Made it a 3 liner and massaged changelog ] Signed-off-by: Viresh Kumar Cc: linaro-kernel@lists.linaro.org Cc: fweisbec@gmail.com Cc: Arvind.Chauhan@arm.com Cc: linaro-networking@linaro.org Cc: John Stultz Cc: # v3.14+ Link: http://lkml.kernel.org/r/80afb18a494b0bd9710975bcc4de134ae323c74f.1397537987.git.viresh.kumar@linaro.org Signed-off-by: Thomas Gleixner --- kernel/time/tick-sched.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 9f8af69c67ec..e947d968c5b5 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -84,6 +84,9 @@ static void tick_do_update_jiffies64(ktime_t now) /* Keep the tick_next_period variable up to date */ tick_next_period = ktime_add(last_jiffies_update, tick_period); + } else { + write_sequnlock(&jiffies_lock); + return; } write_sequnlock(&jiffies_lock); update_wall_time(); -- GitLab From 27630532ef5ead28b98cfe28d8f95222ef91c2b7 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 15 Apr 2014 10:54:41 +0530 Subject: [PATCH 299/797] tick-sched: Check tick_nohz_enabled in tick_nohz_switch_to_nohz() Since commit d689fe222 (NOHZ: Check for nohz active instead of nohz enabled) the tick_nohz_switch_to_nohz() function returns because it checks for the tick_nohz_active flag. This can't be set, because the function itself sets it. Undo the change in tick_nohz_switch_to_nohz(). Signed-off-by: Viresh Kumar Cc: linaro-kernel@lists.linaro.org Cc: fweisbec@gmail.com Cc: Arvind.Chauhan@arm.com Cc: linaro-networking@linaro.org Cc: # 3.13+ Link: http://lkml.kernel.org/r/40939c05f2d65d781b92b20302b02243d0654224.1397537987.git.viresh.kumar@linaro.org Signed-off-by: Thomas Gleixner --- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index e947d968c5b5..6558b7ac112d 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -970,7 +970,7 @@ static void tick_nohz_switch_to_nohz(void) struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); ktime_t next; - if (!tick_nohz_active) + if (!tick_nohz_enabled) return; local_irq_disable(); -- GitLab From 29d1e7209e1866a1b6b686107cce9f5a9b886a53 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Fri, 21 Mar 2014 00:42:54 +0100 Subject: [PATCH 300/797] staging/rtl8821ae: Fix OOM handling in _rtl_init_deferred_work() alloc_workqueue() can fail, handle this case. Signed-off-by: Richard Weinberger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8821ae/base.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8821ae/base.c b/drivers/staging/rtl8821ae/base.c index e5073fe24770..a4c9cc437bc6 100644 --- a/drivers/staging/rtl8821ae/base.c +++ b/drivers/staging/rtl8821ae/base.c @@ -388,7 +388,7 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) } -static void _rtl_init_deferred_work(struct ieee80211_hw *hw) +static int _rtl_init_deferred_work(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -410,6 +410,9 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name); #endif /**/ + if (!rtlpriv->works.rtl_wq) + return -ENOMEM; + INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq, (void *)rtl_watchdog_wq_callback); INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq, @@ -421,6 +424,8 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw) INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq, (void *)rtl_fwevt_wq_callback); + return 0; + } void rtl_deinit_deferred_work(struct ieee80211_hw *hw) @@ -519,7 +524,8 @@ int rtl_init_core(struct ieee80211_hw *hw) INIT_LIST_HEAD(&rtlpriv->entry_list); /* <6> init deferred work */ - _rtl_init_deferred_work(hw); + if (_rtl_init_deferred_work(hw)) + return 1; /* <7> */ #ifdef VIF_TODO -- GitLab From 54d63f787b652755e66eb4dd8892ee6d3f5197fc Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Mon, 14 Apr 2014 17:11:38 +0200 Subject: [PATCH 301/797] ip6_gre: don't allow to remove the fb_tunnel_dev It's possible to remove the FB tunnel with the command 'ip link del ip6gre0' but this is unsafe, the module always supposes that this device exists. For example, ip6gre_tunnel_lookup() may use it unconditionally. Let's add a rtnl handler for dellink, which will never remove the FB tunnel (we let ip6gre_destroy_tunnels() do the job). Introduced by commit c12b395a4664 ("gre: Support GRE over IPv6"). CC: Dmitry Kozlov Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/ipv6/ip6_gre.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index c98338b81d30..9d921462b57f 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -1559,6 +1559,15 @@ static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[], return 0; } +static void ip6gre_dellink(struct net_device *dev, struct list_head *head) +{ + struct net *net = dev_net(dev); + struct ip6gre_net *ign = net_generic(net, ip6gre_net_id); + + if (dev != ign->fb_tunnel_dev) + unregister_netdevice_queue(dev, head); +} + static size_t ip6gre_get_size(const struct net_device *dev) { return @@ -1636,6 +1645,7 @@ static struct rtnl_link_ops ip6gre_link_ops __read_mostly = { .validate = ip6gre_tunnel_validate, .newlink = ip6gre_newlink, .changelink = ip6gre_changelink, + .dellink = ip6gre_dellink, .get_size = ip6gre_get_size, .fill_info = ip6gre_fill_info, }; -- GitLab From 8564ae09e08340a26c5408637cc4b32dba9f1640 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 15 Apr 2014 11:37:14 +0200 Subject: [PATCH 302/797] qlcnic: Fix MSI-X initialization code Function qlcnic_setup_tss_rss_intr() might enter endless loop in case pci_enable_msix() contiguously returns a positive number of MSI-Xs that could have been allocated. Besides, the function contains 'err = -EIO;' assignment that never could be reached. This update fixes the aforementioned issues. Cc: Shahed Shaikh Cc: Dept-HSGLinuxNICDev@qlogic.com Cc: netdev@vger.kernel.org Cc: linux-pci@vger.kernel.org Signed-off-by: Alexander Gordeev Acked-by: Shahed Shaikh Signed-off-by: David S. Miller --- .../net/ethernet/qlogic/qlcnic/qlcnic_main.c | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 84d011ed7ec2..dbf75393f758 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -670,7 +670,7 @@ int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter) else num_msix += adapter->drv_tx_rings; - if (adapter->drv_rss_rings > 0) + if (adapter->drv_rss_rings > 0) num_msix += adapter->drv_rss_rings; else num_msix += adapter->drv_sds_rings; @@ -686,19 +686,15 @@ int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter) return -ENOMEM; } -restore: for (vector = 0; vector < num_msix; vector++) adapter->msix_entries[vector].entry = vector; +restore: err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); - if (err == 0) { - adapter->ahw->num_msix = num_msix; - if (adapter->drv_tss_rings > 0) - adapter->drv_tx_rings = adapter->drv_tss_rings; + if (err > 0) { + if (!adapter->drv_tss_rings && !adapter->drv_rss_rings) + return -ENOSPC; - if (adapter->drv_rss_rings > 0) - adapter->drv_sds_rings = adapter->drv_rss_rings; - } else { netdev_info(adapter->netdev, "Unable to allocate %d MSI-X vectors, Available vectors %d\n", num_msix, err); @@ -716,12 +712,20 @@ int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter) "Restoring %d Tx, %d SDS rings for total %d vectors.\n", adapter->drv_tx_rings, adapter->drv_sds_rings, num_msix); - goto restore; - err = -EIO; + goto restore; + } else if (err < 0) { + return err; } - return err; + adapter->ahw->num_msix = num_msix; + if (adapter->drv_tss_rings > 0) + adapter->drv_tx_rings = adapter->drv_tss_rings; + + if (adapter->drv_rss_rings > 0) + adapter->drv_sds_rings = adapter->drv_rss_rings; + + return 0; } int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) -- GitLab From 6f1d7210376727d090e04b8635e6dda4d7eb7b0c Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Tue, 15 Apr 2014 14:22:34 -0500 Subject: [PATCH 303/797] cxgb4: use the correct max size for firmware flash The wrong max fw size was being used and causing false "too big" errors running ethtool -f. Signed-off-by: Steve Wise Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index fb2fe65903c2..bba67681aeaa 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -682,7 +682,7 @@ enum { SF_RD_ID = 0x9f, /* read ID */ SF_ERASE_SECTOR = 0xd8, /* erase sector */ - FW_MAX_SIZE = 512 * 1024, + FW_MAX_SIZE = 16 * SF_SEC_SIZE, }; /** -- GitLab From e7a62df8e8b4a5ecbbf4339b5b3671ae6582e50a Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 15 Apr 2014 08:38:17 -0700 Subject: [PATCH 304/797] of: Clean up of_update_property After searching for the old property, bail out with -ENODEV if it was not found. It is unnecessary to check if oldprop is NULL before removing its binary file; the check was already done before. Signed-off-by: Guenter Roeck Signed-off-by: Rob Herring --- drivers/of/base.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/of/base.c b/drivers/of/base.c index f72d19b7e5d2..6d4ee22708c9 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1828,17 +1828,13 @@ int of_update_property(struct device_node *np, struct property *newprop) next = &(*next)->next; } raw_spin_unlock_irqrestore(&devtree_lock, flags); - if (rc) - return rc; + if (!found) + return -ENODEV; /* Update the sysfs attribute */ - if (oldprop) - sysfs_remove_bin_file(&np->kobj, &oldprop->attr); + sysfs_remove_bin_file(&np->kobj, &oldprop->attr); __of_add_property_sysfs(np, newprop); - if (!found) - return -ENODEV; - return 0; } -- GitLab From ec03ab77cc2c39d115118fcd4fc11a5801cbb70e Mon Sep 17 00:00:00 2001 From: Wilfried Klaebe Date: Tue, 25 Mar 2014 17:59:39 +0000 Subject: [PATCH 305/797] staging: rtl8188eu: remove spaces, correct counts to unbreak P2P ioctls staging: rtl8188eu: remove spaces, correct counts to unbreak P2P ioctls It looks like someone did a search-and-replace on that driver, putting spaces before "=" characters, without checking this is OK everywhere. Also, in some places, there's memcpm()s/strncmp()s checking for some different length than the fixed string argument. These things result in code not working as intended. Fix that. Signed-off-by: Wilfried Klaebe Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/os_dep/ioctl_linux.c | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c index 2636e7f3dbb8..cf30a08912d1 100644 --- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c +++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c @@ -359,7 +359,7 @@ static char *translate_scan(struct adapter *padapter, if (wpa_len > 0) { p = buf; _rtw_memset(buf, 0, MAX_WPA_IE_LEN); - p += sprintf(p, "wpa_ie ="); + p += sprintf(p, "wpa_ie="); for (i = 0; i < wpa_len; i++) p += sprintf(p, "%02x", wpa_ie[i]); @@ -376,7 +376,7 @@ static char *translate_scan(struct adapter *padapter, if (rsn_len > 0) { p = buf; _rtw_memset(buf, 0, MAX_WPA_IE_LEN); - p += sprintf(p, "rsn_ie ="); + p += sprintf(p, "rsn_ie="); for (i = 0; i < rsn_len; i++) p += sprintf(p, "%02x", rsn_ie[i]); _rtw_memset(&iwe, 0, sizeof(iwe)); @@ -2899,7 +2899,7 @@ static int rtw_p2p_get_status(struct net_device *dev, /* Commented by Albert 2010/10/12 */ /* Because of the output size limitation, I had removed the "Role" information. */ /* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */ - sprintf(extra, "\n\nStatus =%.2d\n", rtw_p2p_state(pwdinfo)); + sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo)); wrqu->data.length = strlen(extra); return ret; @@ -2918,7 +2918,7 @@ static int rtw_p2p_get_req_cm(struct net_device *dev, struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev); struct wifidirect_info *pwdinfo = &(padapter->wdinfo); - sprintf(extra, "\n\nCM =%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req); + sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req); wrqu->data.length = strlen(extra); return ret; } @@ -2935,7 +2935,7 @@ static int rtw_p2p_get_role(struct net_device *dev, pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]); - sprintf(extra, "\n\nRole =%.2d\n", rtw_p2p_role(pwdinfo)); + sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo)); wrqu->data.length = strlen(extra); return ret; } @@ -3022,7 +3022,7 @@ static int rtw_p2p_get_op_ch(struct net_device *dev, DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel); - sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel); + sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel); wrqu->data.length = strlen(extra); return ret; } @@ -3043,7 +3043,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev, u8 blnMatch = 0; u16 attr_content = 0; uint attr_contentlen = 0; - /* 6 is the string "wpsCM =", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */ + /* 6 is the string "wpsCM=", 17 is the MAC addr, we have to clear it at wrqu->data.pointer */ u8 attr_content_str[6 + 17] = {0x00}; /* Commented by Albert 20110727 */ @@ -3079,7 +3079,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev, rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *) &be_tmp, &attr_contentlen); if (attr_contentlen) { attr_content = be16_to_cpu(be_tmp); - sprintf(attr_content_str, "\n\nM =%.4d", attr_content); + sprintf(attr_content_str, "\n\nM=%.4d", attr_content); blnMatch = 1; } } @@ -3091,7 +3091,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev, spin_unlock_bh(&pmlmepriv->scanned_queue.lock); if (!blnMatch) - sprintf(attr_content_str, "\n\nM = 0000"); + sprintf(attr_content_str, "\n\nM=0000"); if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17)) return -EFAULT; @@ -3172,9 +3172,9 @@ static int rtw_p2p_get_go_device_address(struct net_device *dev, spin_unlock_bh(&pmlmepriv->scanned_queue.lock); if (!blnMatch) - snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add = NULL"); + snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=NULL"); else - snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add =%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", + snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]); if (copy_to_user(wrqu->data.pointer, go_devadd_str, sizeof(go_devadd_str))) @@ -3198,7 +3198,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev, u8 blnMatch = 0; u8 dev_type[8] = {0x00}; uint dev_type_len = 0; - u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type =", we have to clear it at wrqu->data.pointer */ + u8 dev_type_str[17 + 9] = {0x00}; /* +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */ /* Commented by Albert 20121209 */ /* The input data is the MAC address which the application wants to know its device type. */ @@ -3239,7 +3239,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev, memcpy(&be_tmp, dev_type, 2); type = be16_to_cpu(be_tmp); - sprintf(dev_type_str, "\n\nN =%.2d", type); + sprintf(dev_type_str, "\n\nN=%.2d", type); blnMatch = 1; } } @@ -3252,7 +3252,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev, spin_unlock_bh(&pmlmepriv->scanned_queue.lock); if (!blnMatch) - sprintf(dev_type_str, "\n\nN = 00"); + sprintf(dev_type_str, "\n\nN=00"); if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) { return -EFAULT; @@ -3277,7 +3277,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev, u8 blnMatch = 0; u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = {0x00}; uint dev_len = 0; - u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN =", we have to clear it at wrqu->data.pointer */ + u8 dev_name_str[WPS_MAX_DEVICE_NAME_LEN + 5] = {0x00}; /* +5 is for the str "devN=", we have to clear it at wrqu->data.pointer */ /* Commented by Albert 20121225 */ /* The input data is the MAC address which the application wants to know its device name. */ @@ -3310,7 +3310,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev, if (wpsie) { rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len); if (dev_len) { - sprintf(dev_name_str, "\n\nN =%s", dev_name); + sprintf(dev_name_str, "\n\nN=%s", dev_name); blnMatch = 1; } } @@ -3323,7 +3323,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev, spin_unlock_bh(&pmlmepriv->scanned_queue.lock); if (!blnMatch) - sprintf(dev_name_str, "\n\nN = 0000"); + sprintf(dev_name_str, "\n\nN=0000"); if (copy_to_user(wrqu->data.pointer, dev_name_str, 5 + ((dev_len > 17) ? dev_len : 17))) return -EFAULT; @@ -3349,7 +3349,7 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev, u8 attr_content[2] = {0x00}; u8 inv_proc_str[17 + 8] = {0x00}; - /* +8 is for the str "InvProc =", we have to clear it at wrqu->data.pointer */ + /* +8 is for the str "InvProc=", we have to clear it at wrqu->data.pointer */ /* Commented by Ouden 20121226 */ /* The application wants to know P2P initiation procedure is supported or not. */ @@ -3397,12 +3397,12 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev, spin_unlock_bh(&pmlmepriv->scanned_queue.lock); if (!blnMatch) { - sprintf(inv_proc_str, "\nIP =-1"); + sprintf(inv_proc_str, "\nIP=-1"); } else { if (attr_content[0] & 0x20) - sprintf(inv_proc_str, "\nIP = 1"); + sprintf(inv_proc_str, "\nIP=1"); else - sprintf(inv_proc_str, "\nIP = 0"); + sprintf(inv_proc_str, "\nIP=0"); } if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17)) return -EFAULT; @@ -3512,7 +3512,7 @@ static int rtw_p2p_invite_req(struct net_device *dev, /* The input data contains two informations. */ /* 1. First information is the P2P device address which you want to send to. */ /* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */ - /* Command line sample: iwpriv wlan0 p2p_set invite ="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */ + /* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */ /* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */ DBG_88E("[%s] data = %s\n", __func__, extra); @@ -3805,48 +3805,48 @@ static int rtw_p2p_set(struct net_device *dev, #ifdef CONFIG_88EU_P2P DBG_88E("[%s] extra = %s\n", __func__, extra); - if (!memcmp(extra, "enable =", 7)) { + if (!memcmp(extra, "enable=", 7)) { rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]); - } else if (!memcmp(extra, "setDN =", 6)) { + } else if (!memcmp(extra, "setDN=", 6)) { wrqu->data.length -= 6; rtw_p2p_setDN(dev, info, wrqu, &extra[6]); - } else if (!memcmp(extra, "profilefound =", 13)) { + } else if (!memcmp(extra, "profilefound=", 13)) { wrqu->data.length -= 13; rtw_p2p_profilefound(dev, info, wrqu, &extra[13]); - } else if (!memcmp(extra, "prov_disc =", 10)) { + } else if (!memcmp(extra, "prov_disc=", 10)) { wrqu->data.length -= 10; rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]); - } else if (!memcmp(extra, "nego =", 5)) { + } else if (!memcmp(extra, "nego=", 5)) { wrqu->data.length -= 5; rtw_p2p_connect(dev, info, wrqu, &extra[5]); - } else if (!memcmp(extra, "intent =", 7)) { + } else if (!memcmp(extra, "intent=", 7)) { /* Commented by Albert 2011/03/23 */ /* The wrqu->data.length will include the null character */ /* So, we will decrease 7 + 1 */ wrqu->data.length -= 8; rtw_p2p_set_intent(dev, info, wrqu, &extra[7]); - } else if (!memcmp(extra, "ssid =", 5)) { + } else if (!memcmp(extra, "ssid=", 5)) { wrqu->data.length -= 5; rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]); - } else if (!memcmp(extra, "got_wpsinfo =", 12)) { + } else if (!memcmp(extra, "got_wpsinfo=", 12)) { wrqu->data.length -= 12; rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]); - } else if (!memcmp(extra, "listen_ch =", 10)) { + } else if (!memcmp(extra, "listen_ch=", 10)) { /* Commented by Albert 2011/05/24 */ /* The wrqu->data.length will include the null character */ /* So, we will decrease (10 + 1) */ wrqu->data.length -= 11; rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]); - } else if (!memcmp(extra, "op_ch =", 6)) { + } else if (!memcmp(extra, "op_ch=", 6)) { /* Commented by Albert 2011/05/24 */ /* The wrqu->data.length will include the null character */ /* So, we will decrease (6 + 1) */ wrqu->data.length -= 7; rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]); - } else if (!memcmp(extra, "invite =", 7)) { + } else if (!memcmp(extra, "invite=", 7)) { wrqu->data.length -= 8; rtw_p2p_invite_req(dev, info, wrqu, &extra[7]); - } else if (!memcmp(extra, "persistent =", 11)) { + } else if (!memcmp(extra, "persistent=", 11)) { wrqu->data.length -= 11; rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]); } @@ -3887,7 +3887,7 @@ static int rtw_p2p_get(struct net_device *dev, "group_id", 8)) { rtw_p2p_get_groupid(dev, info, wrqu, extra); } else if (!memcmp((__force const char *)wrqu->data.pointer, - "peer_deva_inv", 9)) { + "peer_deva_inv", 13)) { /* Get the P2P device address when receiving the P2P Invitation request frame. */ rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra); } else if (!memcmp((__force const char *)wrqu->data.pointer, @@ -6920,7 +6920,7 @@ static int rtw_mp_ctx(struct net_device *dev, DBG_88E("%s: in =%s\n", __func__, extra); - countPkTx = strncmp(extra, "count =", 5); /* strncmp true is 0 */ + countPkTx = strncmp(extra, "count=", 6); /* strncmp true is 0 */ cotuTx = strncmp(extra, "background", 20); CarrSprTx = strncmp(extra, "background, cs", 20); scTx = strncmp(extra, "background, sc", 20); @@ -7044,7 +7044,7 @@ static int rtw_mp_arx(struct net_device *dev, DBG_88E("%s: %s\n", __func__, input); bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp true is 0 */ - bStopRx = (strncmp(input, "stop", 5) == 0) ? 1 : 0; /* strncmp true is 0 */ + bStopRx = (strncmp(input, "stop", 4) == 0) ? 1 : 0; /* strncmp true is 0 */ bQueryPhy = (strncmp(input, "phy", 3) == 0) ? 1 : 0; /* strncmp true is 0 */ if (bStartRx) { -- GitLab From 21c5e8408d105386c54603aed2cae9195143d87d Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Mon, 24 Mar 2014 13:45:13 -0600 Subject: [PATCH 306/797] staging/usbip: userspace - fix usbipd SIGSEGV from refresh_exported_devices() refresh_exported_devices() doesn't check udev_device_new_from_syspath() return value and passed in null dev to udev_device_get_driver() resulting in a segmentation fault. Change it to check for null return value from both udev_device_new_from_syspath() and udev_device_get_driver(). Signed-off-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c index c5bf60b135b9..92caef7474c7 100644 --- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c @@ -118,6 +118,7 @@ static int refresh_exported_devices(void) struct udev_list_entry *devices, *dev_list_entry; struct udev_device *dev; const char *path; + const char *driver; enumerate = udev_enumerate_new(udev_context); udev_enumerate_add_match_subsystem(enumerate, "usb"); @@ -128,10 +129,12 @@ static int refresh_exported_devices(void) udev_list_entry_foreach(dev_list_entry, devices) { path = udev_list_entry_get_name(dev_list_entry); dev = udev_device_new_from_syspath(udev_context, path); + if (dev == NULL) + continue; /* Check whether device uses usbip-host driver. */ - if (!strcmp(udev_device_get_driver(dev), - USBIP_HOST_DRV_NAME)) { + driver = udev_device_get_driver(dev); + if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) { edev = usbip_exported_device_new(path); if (!edev) { dbg("usbip_exported_device_new failed"); -- GitLab From de4734bc651d19ed71ad30222aac9b1416e1bd52 Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Tue, 25 Mar 2014 06:47:13 -0600 Subject: [PATCH 307/797] staging/usbip: fix store_attach() sscanf return value check sscanf() parses the input buffer for four input items. However, the return value check is incorrect, as it checks for one input item instead of four which is what it is expecting in the input buffer. As a result, sscanf() will always fail even when the input buffer is correct. Signed-off-by: Shuah Khan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index 47bddcdde0a6..211f43f67ea2 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c @@ -184,7 +184,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, * @devid: unique device identifier in a remote host * @speed: usb device speed in a remote host */ - if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 1) + if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4) return -EINVAL; usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n", -- GitLab From d06fb58cb63c66ddcc2ac94edf99f505f4919da0 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Thu, 3 Apr 2014 10:32:17 +0200 Subject: [PATCH 308/797] staging: fpgaboot: clean up Makefile This Makefile tries to set the DEBUG macro but it uses an unknown Kconfig macro to do so. Since no code appears to even care about the DEBUG macro this line can safely be removed. Signed-off-by: Paul Bolle Reviewed-by: Insop Song Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/gs_fpgaboot/Makefile b/drivers/staging/gs_fpgaboot/Makefile index 34cb606e0e3d..d2f0211ba540 100644 --- a/drivers/staging/gs_fpgaboot/Makefile +++ b/drivers/staging/gs_fpgaboot/Makefile @@ -1,4 +1,2 @@ gs_fpga-y += gs_fpgaboot.o io.o obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o - -ccflags-$(CONFIG_GS_FPGA_DEBUG) := -DDEBUG -- GitLab From 1a52489318c16aaff71059b3892a1a2f3bb8ecec Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 26 Mar 2014 12:01:48 +0900 Subject: [PATCH 309/797] staging: vme: fix memory leak in vme_user_probe() If vme_master_request() returns NULL when it failed, it need to free buffers for master. And also removes unreachable code in vme_user_probe(). Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 792792715673..ffb4eeefdddb 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -776,7 +776,8 @@ static int vme_user_probe(struct vme_dev *vdev) image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL); if (image[i].kern_buf == NULL) { err = -ENOMEM; - goto err_master_buf; + vme_master_free(image[i].resource); + goto err_master; } } @@ -819,8 +820,6 @@ static int vme_user_probe(struct vme_dev *vdev) return 0; - /* Ensure counter set correcty to destroy all sysfs devices */ - i = VME_DEVS; err_sysfs: while (i > 0) { i--; @@ -830,12 +829,10 @@ static int vme_user_probe(struct vme_dev *vdev) /* Ensure counter set correcty to unalloc all master windows */ i = MASTER_MAX + 1; -err_master_buf: - for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) - kfree(image[i].kern_buf); err_master: while (i > MASTER_MINOR) { i--; + kfree(image[i].kern_buf); vme_master_free(image[i].resource); } -- GitLab From 14e6e35d04995c118f41582299f6861ab209bdb3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 25 Mar 2014 16:48:35 +0100 Subject: [PATCH 310/797] staging: gs_fpgaboot: remove __TIMESTAMP__ macro We specifically build the kernel with -Werror=date-time to detect such macros, which gives us this error: gs_fpgaboot/gs_fpgaboot.c:376:44: error: macro "__TIMESTAMP__" might prevent reproducible builds [-Werror=date-time] pr_info("built at %s UTC\n", __TIMESTAMP__); The obvious fix is to remove the printk output line. Signed-off-by: Arnd Bergmann Signed-off-by: Insop Song Acked-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/staging/gs_fpgaboot/gs_fpgaboot.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c index 89bc84d833e6..7506900c9b8d 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c @@ -373,7 +373,6 @@ static int __init gs_fpgaboot_init(void) r = -1; pr_info("FPGA DOWNLOAD --->\n"); - pr_info("built at %s UTC\n", __TIMESTAMP__); pr_info("FPGA image file name: %s\n", file); -- GitLab From f5d197b614d8fbc5c25307e7eff1d663653966fa Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Tue, 15 Apr 2014 19:43:20 +0200 Subject: [PATCH 311/797] staging: rtl8723au: Fix buffer overflow in rtw_get_wfd_ie() Add bounds checking to not allow WFD Information Elements larger than 128, and make sure we use the correct buffer size MAX_WFD_IE_LEN instea of hardcoding the size. This also simplifies rtw_get_wfd_ie() by using the cfg80211 infrastructure. Reported-by: Dan Carpenter Signed-off-by: Jes Sorensen Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8723au/core/rtw_ieee80211.c | 46 +++++-------------- drivers/staging/rtl8723au/core/rtw_mlme_ext.c | 2 +- drivers/staging/rtl8723au/core/rtw_p2p.c | 4 +- .../staging/rtl8723au/core/rtw_wlan_util.c | 2 +- 4 files changed, 16 insertions(+), 38 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c index 780631fd3b6d..a48ab25a7d8a 100644 --- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c @@ -1496,45 +1496,23 @@ void rtw_wlan_bssid_ex_remove_p2p_attr23a(struct wlan_bssid_ex *bss_ex, u8 attr_ int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen) { int match; - uint cnt = 0; - u8 eid, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A}; + const u8 *ie; - match = false; + match = 0; - if (in_len < 0) { + if (in_len < 0) return match; - } - - while (cnt < in_len) - { - eid = in_ie[cnt]; - if ((eid == _VENDOR_SPECIFIC_IE_) && - !memcmp(&in_ie[cnt+2], wfd_oui, 4)) { - if (wfd_ie != NULL) { - memcpy(wfd_ie, &in_ie[cnt], in_ie[cnt + 1] + 2); - - } else { - if (wfd_ielen != NULL) { - *wfd_ielen = 0; - } - } - - if (wfd_ielen != NULL) { - *wfd_ielen = in_ie[cnt + 1] + 2; - } - - cnt += in_ie[cnt + 1] + 2; - - match = true; - break; - } else { - cnt += in_ie[cnt + 1] +2; /* goto next */ - } - } + ie = cfg80211_find_vendor_ie(0x506F9A, 0x0A, in_ie, in_len); + if (ie && (ie[1] <= (MAX_WFD_IE_LEN - 2))) { + if (wfd_ie) { + *wfd_ielen = ie[1] + 2; + memcpy(wfd_ie, ie, ie[1] + 2); + } else + if (wfd_ielen) + *wfd_ielen = 0; - if (match == true) { - match = cnt; + match = 1; } return match; diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c index 4c753639ea5a..1f3e8a0aece4 100644 --- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c @@ -1281,7 +1281,7 @@ unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *prec u8 p2p_status_code = P2P_STATUS_SUCCESS; u8 *p2pie; u32 p2pielen = 0; - u8 wfd_ie[ 128 ] = { 0x00 }; + u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 }; u32 wfd_ielen = 0; #endif /* CONFIG_8723AU_P2P */ diff --git a/drivers/staging/rtl8723au/core/rtw_p2p.c b/drivers/staging/rtl8723au/core/rtw_p2p.c index 27a6cc76973d..1a961e3f3a55 100644 --- a/drivers/staging/rtl8723au/core/rtw_p2p.c +++ b/drivers/staging/rtl8723au/core/rtw_p2p.c @@ -2535,7 +2535,7 @@ u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo, u8 *pfra u16 wps_devicepassword_id = 0x0000; uint wps_devicepassword_id_len = 0; #ifdef CONFIG_8723AU_P2P - u8 wfd_ie[ 128 ] = { 0x00 }; + u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 }; u32 wfd_ielen = 0; #endif /* CONFIG_8723AU_P2P */ @@ -2741,7 +2741,7 @@ u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo, u8 *pfr u32 ies_len; u8 * p2p_ie; #ifdef CONFIG_8723AU_P2P - u8 wfd_ie[ 128 ] = { 0x00 }; + u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 }; u32 wfd_ielen = 0; #endif /* CONFIG_8723AU_P2P */ diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index 0dfcfbce3b52..e743b053b8a2 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -570,7 +570,7 @@ void flush_all_cam_entry23a(struct rtw_adapter *padapter) int WFD_info_handler(struct rtw_adapter *padapter, struct ndis_802_11_var_ies * pIE) { struct wifidirect_info *pwdinfo; - u8 wfd_ie[128] = {0x00}; + u8 wfd_ie[MAX_WFD_IE_LEN] = {0x00}; u32 wfd_ielen = 0; pwdinfo = &padapter->wdinfo; -- GitLab From 67807ce55f6e5ad5c04a748aa195333d6af05654 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 16 Apr 2014 10:09:08 +0800 Subject: [PATCH 312/797] ALSA: hda - add headset mic detect quirk for a Dell laptop When we plug a 3-ring headset on the Dell machine (VID: 0x10ec0255, SID: 0x1028067f), the headset mic can't be detected, after apply this patch, the headset mic can work well. BugLink: https://bugs.launchpad.net/bugs/1297581 Cc: David Henningsson Cc: stable@vger.kernel.org Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f7766febaebe..26895d1bbd91 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4621,6 +4621,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), -- GitLab From 2dda47d1a416750bf69eb11dd9b6607d18287b0c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Apr 2014 11:32:06 +0200 Subject: [PATCH 313/797] platform: Fix timberdale dependencies VIDEO_TIMBERDALE selects TIMB_DMA which itself depends on MFD_TIMBERDALE, so VIDEO_TIMBERDALE should either select or depend on MFD_TIMBERDALE as well. I chose to make it depend on it because I think it makes more sense and it is consistent with what other options are doing. Adding a "|| HAS_IOMEM" to the TIMB_DMA dependencies silenced the kconfig warning about unmet direct dependencies but it was wrong: without MFD_TIMBERDALE, TIMB_DMA is useless as the driver has no device to bind to. Signed-off-by: Jean Delvare Cc: Vinod Koul Cc: Dan Williams Cc: Mauro Carvalho Chehab Signed-off-by: Vinod Koul --- drivers/dma/Kconfig | 2 +- drivers/media/platform/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index ba06d1d2f99e..5c5863842de9 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -197,7 +197,7 @@ config AMCC_PPC440SPE_ADMA config TIMB_DMA tristate "Timberdale FPGA DMA support" - depends on MFD_TIMBERDALE || HAS_IOMEM + depends on MFD_TIMBERDALE select DMA_ENGINE help Enable support for the Timberdale FPGA DMA engine. diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index c137abfa0c54..20f1655e6d75 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -56,7 +56,7 @@ config VIDEO_VIU config VIDEO_TIMBERDALE tristate "Support for timberdale Video In/LogiWIN" - depends on VIDEO_V4L2 && I2C && DMADEVICES + depends on MFD_TIMBERDALE && VIDEO_V4L2 && I2C && DMADEVICES select DMA_ENGINE select TIMB_DMA select VIDEO_ADV7180 -- GitLab From f3817e777ca3a089381a5b2370fbb869c3bcce6f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Apr 2014 10:29:33 +0300 Subject: [PATCH 314/797] dmaengine: sirf: off by one in of_dma_sirfsoc_xlate() The ">" here should be ">=" or we are one step beyond the end of the sdma->channels[] array. Fixes: 2e041c94628c ('dmaengine: sirf: enable generic dt binding for dma channels') Signed-off-by: Dan Carpenter Acked-by: Barry Song Signed-off-by: Vinod Koul --- drivers/dma/sirf-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index a1bd8298d55f..03f7820fa333 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c @@ -666,7 +666,7 @@ static struct dma_chan *of_dma_sirfsoc_xlate(struct of_phandle_args *dma_spec, struct sirfsoc_dma *sdma = ofdma->of_dma_data; unsigned int request = dma_spec->args[0]; - if (request > SIRFSOC_DMA_CHANNELS) + if (request >= SIRFSOC_DMA_CHANNELS) return NULL; return dma_get_slave_channel(&sdma->channels[request].chan); -- GitLab From 8edc51c197b8f409bef7b21755254e6f3ce7ed23 Mon Sep 17 00:00:00 2001 From: Yuan Yao Date: Fri, 4 Apr 2014 12:27:55 +0800 Subject: [PATCH 315/797] dma: fix eDMA driver as a subsys_initcall Because of some driver base on DMA, changed the initcall order as subsys_initcall. Signed-off-by: Yuan Yao Signed-off-by: Vinod Koul --- drivers/dma/fsl-edma.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index 381e793184ba..b396a7fb53ab 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -968,7 +968,17 @@ static struct platform_driver fsl_edma_driver = { .remove = fsl_edma_remove, }; -module_platform_driver(fsl_edma_driver); +static int __init fsl_edma_init(void) +{ + return platform_driver_register(&fsl_edma_driver); +} +subsys_initcall(fsl_edma_init); + +static void __exit fsl_edma_exit(void) +{ + platform_driver_unregister(&fsl_edma_driver); +} +module_exit(fsl_edma_exit); MODULE_ALIAS("platform:fsl-edma"); MODULE_DESCRIPTION("Freescale eDMA engine driver"); -- GitLab From 5be44a6fb1edb57d7d2d77151870dcd79c8c0e58 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 4 Apr 2014 08:41:26 +0200 Subject: [PATCH 316/797] x86: Remove the PCI reboot method from the default chain Steve reported a reboot hang and bisected it back to this commit: a4f1987e4c54 x86, reboot: Add EFI and CF9 reboot methods into the default list He heroically tested all reboot methods and found the following: reboot=t # triple fault ok reboot=k # keyboard ctrl FAIL reboot=b # BIOS ok reboot=a # ACPI FAIL reboot=e # EFI FAIL [system has no EFI] reboot=p # PCI 0xcf9 FAIL And I think it's pretty obvious that we should only try PCI 0xcf9 as a last resort - if at all. The other observation is that (on this box) we should never try the PCI reboot method, but close with either the 'triple fault' or the 'BIOS' (terminal!) reboot methods. Thirdly, CF9_COND is a total misnomer - it should be something like CF9_SAFE or CF9_CAREFUL, and 'CF9' should be 'CF9_FORCE' ... So this patch fixes the worst problems: - it orders the actual reboot logic to follow the reboot ordering pattern - it was in a pretty random order before for no good reason. - it fixes the CF9 misnomers and uses BOOT_CF9_FORCE and BOOT_CF9_SAFE flags to make the code more obvious. - it tries the BIOS reboot method before the PCI reboot method. (Since 'BIOS' is a terminal reboot method resulting in a hang if it does not work, this is essentially equivalent to removing the PCI reboot method from the default reboot chain.) - just for the miraculous possibility of terminal (resulting in hang) reboot methods of triple fault or BIOS returning without having done their job, there's an ordering between them as well. Reported-and-bisected-and-tested-by: Steven Rostedt Cc: Li Aubrey Cc: Linus Torvalds Cc: Matthew Garrett Link: http://lkml.kernel.org/r/20140404064120.GB11877@gmail.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/reboot.c | 72 +++++++++++++++++++++------------------- include/linux/reboot.h | 14 ++++---- 2 files changed, 44 insertions(+), 42 deletions(-) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 654b46574b91..3399d3a99730 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -114,8 +114,8 @@ EXPORT_SYMBOL(machine_real_restart); */ static int __init set_pci_reboot(const struct dmi_system_id *d) { - if (reboot_type != BOOT_CF9) { - reboot_type = BOOT_CF9; + if (reboot_type != BOOT_CF9_FORCE) { + reboot_type = BOOT_CF9_FORCE; pr_info("%s series board detected. Selecting %s-method for reboots.\n", d->ident, "PCI"); } @@ -458,20 +458,23 @@ void __attribute__((weak)) mach_reboot_fixups(void) } /* - * Windows compatible x86 hardware expects the following on reboot: + * To the best of our knowledge Windows compatible x86 hardware expects + * the following on reboot: * * 1) If the FADT has the ACPI reboot register flag set, try it * 2) If still alive, write to the keyboard controller * 3) If still alive, write to the ACPI reboot register again * 4) If still alive, write to the keyboard controller again * 5) If still alive, call the EFI runtime service to reboot - * 6) If still alive, write to the PCI IO port 0xCF9 to reboot - * 7) If still alive, inform BIOS to do a proper reboot + * 6) If no EFI runtime service, call the BIOS to do a reboot * - * If the machine is still alive at this stage, it gives up. We default to - * following the same pattern, except that if we're still alive after (7) we'll - * try to force a triple fault and then cycle between hitting the keyboard - * controller and doing that + * We default to following the same pattern. We also have + * two other reboot methods: 'triple fault' and 'PCI', which + * can be triggered via the reboot= kernel boot option or + * via quirks. + * + * This means that this function can never return, it can misbehave + * by not rebooting properly and hanging. */ static void native_machine_emergency_restart(void) { @@ -492,6 +495,11 @@ static void native_machine_emergency_restart(void) for (;;) { /* Could also try the reset bit in the Hammer NB */ switch (reboot_type) { + case BOOT_ACPI: + acpi_reboot(); + reboot_type = BOOT_KBD; + break; + case BOOT_KBD: mach_reboot_fixups(); /* For board specific fixups */ @@ -509,43 +517,29 @@ static void native_machine_emergency_restart(void) } break; - case BOOT_TRIPLE: - load_idt(&no_idt); - __asm__ __volatile__("int3"); - - /* We're probably dead after this, but... */ - reboot_type = BOOT_KBD; - break; - - case BOOT_BIOS: - machine_real_restart(MRR_BIOS); - - /* We're probably dead after this, but... */ - reboot_type = BOOT_TRIPLE; - break; - - case BOOT_ACPI: - acpi_reboot(); - reboot_type = BOOT_KBD; - break; - case BOOT_EFI: if (efi_enabled(EFI_RUNTIME_SERVICES)) efi.reset_system(reboot_mode == REBOOT_WARM ? EFI_RESET_WARM : EFI_RESET_COLD, EFI_SUCCESS, 0, NULL); - reboot_type = BOOT_CF9_COND; + reboot_type = BOOT_BIOS; + break; + + case BOOT_BIOS: + machine_real_restart(MRR_BIOS); + + /* We're probably dead after this, but... */ + reboot_type = BOOT_CF9_SAFE; break; - case BOOT_CF9: + case BOOT_CF9_FORCE: port_cf9_safe = true; /* Fall through */ - case BOOT_CF9_COND: + case BOOT_CF9_SAFE: if (port_cf9_safe) { - u8 reboot_code = reboot_mode == REBOOT_WARM ? - 0x06 : 0x0E; + u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E; u8 cf9 = inb(0xcf9) & ~reboot_code; outb(cf9|2, 0xcf9); /* Request hard reset */ udelay(50); @@ -553,7 +547,15 @@ static void native_machine_emergency_restart(void) outb(cf9|reboot_code, 0xcf9); udelay(50); } - reboot_type = BOOT_BIOS; + reboot_type = BOOT_TRIPLE; + break; + + case BOOT_TRIPLE: + load_idt(&no_idt); + __asm__ __volatile__("int3"); + + /* We're probably dead after this, but... */ + reboot_type = BOOT_KBD; break; } } diff --git a/include/linux/reboot.h b/include/linux/reboot.h index 9e7db9e73cc1..48bf152761c7 100644 --- a/include/linux/reboot.h +++ b/include/linux/reboot.h @@ -20,13 +20,13 @@ enum reboot_mode { extern enum reboot_mode reboot_mode; enum reboot_type { - BOOT_TRIPLE = 't', - BOOT_KBD = 'k', - BOOT_BIOS = 'b', - BOOT_ACPI = 'a', - BOOT_EFI = 'e', - BOOT_CF9 = 'p', - BOOT_CF9_COND = 'q', + BOOT_TRIPLE = 't', + BOOT_KBD = 'k', + BOOT_BIOS = 'b', + BOOT_ACPI = 'a', + BOOT_EFI = 'e', + BOOT_CF9_FORCE = 'p', + BOOT_CF9_SAFE = 'q', }; extern enum reboot_type reboot_type; -- GitLab From 8dc9abb93dde94e7f2bc719032fe16f5713df05c Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Wed, 16 Apr 2014 15:53:12 +0800 Subject: [PATCH 317/797] ALSA: hda/realtek - Add headset Mic support for Dell machine Signed-off-by: Kailang Yang Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 26895d1bbd91..c643dfc0a826 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5541,6 +5541,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), + SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), -- GitLab From 22bbd5d949dc7fdd72a4e78e767fa09d8e54b446 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 4 Apr 2014 16:31:05 -0600 Subject: [PATCH 318/797] gpu: host1x: handle the correct # of syncpt regs BIT_WORD() truncates rather than rounds, so the loops in syncpt_thresh_isr() and _host1x_intr_disable_all_syncpt_intrs() use <= rather than < in an attempt to process the correct number of registers when rounding of the conversion of count of bits to count of words is necessary. However, when rounding isn't necessary because the value is already a multiple of the divisor (as is the case for all values of nb_pts the code actually sees), this causes one too many registers to be processed. Solve this by using and explicit DIV_ROUND_UP() call, rather than BIT_WORD(), and comparing with < rather than <=. Fixes: 7ede0b0bf3e2 ("gpu: host1x: Add syncpoint wait and interrupts") Cc: # 3.10 Signed-off-by: Stephen Warren Acked-By: Terje Bergstrom Signed-off-by: Thierry Reding --- drivers/gpu/host1x/hw/intr_hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c index db9017adfe2b..498b37e39058 100644 --- a/drivers/gpu/host1x/hw/intr_hw.c +++ b/drivers/gpu/host1x/hw/intr_hw.c @@ -47,7 +47,7 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id) unsigned long reg; int i, id; - for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) { + for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) { reg = host1x_sync_readl(host, HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i)); for_each_set_bit(id, ®, BITS_PER_LONG) { @@ -64,7 +64,7 @@ static void _host1x_intr_disable_all_syncpt_intrs(struct host1x *host) { u32 i; - for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) { + for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) { host1x_sync_writel(host, 0xffffffffu, HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i)); host1x_sync_writel(host, 0xffffffffu, -- GitLab From cbfbbabb89b37f6bad05f478d906a385149f288d Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 9 Apr 2014 14:26:59 +0200 Subject: [PATCH 319/797] drm/tegra: Remove gratuitous pad field The version of the drm_tegra_submit structure that was merged all the way back in 3.10 contains a pad field that was originally intended to properly pad the following __u64 field. Unfortunately it seems like a different field was dropped during review that caused this padding to become unnecessary, but the pad field wasn't removed at that time. One possible side-effect of this is that since the __u64 following the pad is now no longer properly aligned, the compiler may (or may not) introduce padding itself, which results in no predictable ABI. Rectify this by removing the pad field so that all fields are again naturally aligned. Technically this is breaking existing userspace ABI, but given that there aren't any (released) userspace drivers that make use of this yet, the fallout should be minimal. Fixes: d43f81cbaf43 ("drm/tegra: Add gr2d device") Cc: # 3.10 Signed-off-by: Thierry Reding --- include/uapi/drm/tegra_drm.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h index b042b48495d9..b75482112428 100644 --- a/include/uapi/drm/tegra_drm.h +++ b/include/uapi/drm/tegra_drm.h @@ -120,7 +120,6 @@ struct drm_tegra_submit { __u32 num_waitchks; __u32 waitchk_mask; __u32 timeout; - __u32 pad; __u64 syncpts; __u64 cmdbufs; __u64 relocs; -- GitLab From 32702e96a9f76ea0e0a1d218310d2ac1adbd2907 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Wed, 26 Mar 2014 10:31:44 -0700 Subject: [PATCH 320/797] usb: dwc3: gadget: Iterate only over valid endpoints Make dwc3_gadget_resize_tx_fifos() iterate only over IN endpoints that are actually present, based on the num_in_eps parameter. This terminates the loop so as to prevent dereferencing a potential NULL dwc->eps[i] where i >= (num_in_eps + num_out_eps). Signed-off-by: Jack Pham Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a740eac74d56..70715eeededd 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -187,15 +187,12 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) * improve this algorithm so that we better use the internal * FIFO space */ - for (num = 0; num < DWC3_ENDPOINTS_NUM; num++) { - struct dwc3_ep *dep = dwc->eps[num]; - int fifo_number = dep->number >> 1; + for (num = 0; num < dwc->num_in_eps; num++) { + /* bit0 indicates direction; 1 means IN ep */ + struct dwc3_ep *dep = dwc->eps[(num << 1) | 1]; int mult = 1; int tmp; - if (!(dep->number & 1)) - continue; - if (!(dep->flags & DWC3_EP_ENABLED)) continue; @@ -224,8 +221,7 @@ int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s: Fifo Addr %04x Size %d\n", dep->name, last_fifo_depth, fifo_size & 0xffff); - dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(fifo_number), - fifo_size); + dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num), fifo_size); last_fifo_depth += (fifo_size & 0xffff); } -- GitLab From 9c1b70361e0b38e4acb8e62b54da66538cb77ff2 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 26 Mar 2014 18:46:38 +0200 Subject: [PATCH 321/797] usb: gadget: zero: Fix SuperSpeed enumeration for alternate setting 1 It was impossible to enumerate on a SuperSpeed (XHCI) host with alternate setting = 1 due to the wrongly set 'bMaxBurst' field in the SuperSpeed Endpoint Companion descriptor. Testcase: modprobe -r usbtest; modprobe usbtest alt=1 modprobe g_zero plug device to SuperSpeed port on the host. Without this patch the host always complains like so "usb 12-2: Not enough bandwidth for new device state. usb 12-2: Not enough bandwidth for altsetting 1" Bug was introduced by commit cf9a08ae in v3.9 Fixes: cf9a08ae5aec (usb: gadget: convert source sink and loopback to new function interface) Cc: 3.9+ # 3.9+ Reviewed-by: Felipe Balbi Acked-by: Sebastian Andrzej Siewior Signed-off-by: Roger Quadros Signed-off-by: Felipe Balbi --- drivers/usb/gadget/zero.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 9f170c53e3d9..134f354ede62 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -300,7 +300,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) ss_opts->isoc_interval = gzero_options.isoc_interval; ss_opts->isoc_maxpacket = gzero_options.isoc_maxpacket; ss_opts->isoc_mult = gzero_options.isoc_mult; - ss_opts->isoc_maxburst = gzero_options.isoc_maxpacket; + ss_opts->isoc_maxburst = gzero_options.isoc_maxburst; ss_opts->bulk_buflen = gzero_options.bulk_buflen; func_ss = usb_get_function(func_inst_ss); -- GitLab From f45e5f00dacf09362a16339d372fcc96705e40c7 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 26 Mar 2014 11:43:09 +0200 Subject: [PATCH 322/797] usb: dwc3: core: Fix gadget for system suspend/resume During system resume, if the event buffers are not setup before the gadget controller starts then we start with invalid context and this can lead to bus access errors. This is especially true for platforms that loose the controller context during system suspend. e.g. AM437x. The following backtrace was found when the system is suspended and resumed with g_zero loaded on AM437x-evm (USB cable connected to host all the while). [ 120.981506] WARNING: CPU: 0 PID: 1656 at drivers/bus/omap_l3_noc.c:137 l3_interrupt_handler+0x198/0x28c() [ 120.981514] L3 custom error: MASTER:USB0 WR TARGET:GPMC [ 120.981638] Modules linked in: g_mass_storage usb_f_mass_storage libcomposite configfs bufferclass_ti(O) omaplfb(O) cryptodev(O) dwc3 snd_soc_evm snd_soc_omap snd_pe [ 120.981659] CPU: 0 PID: 1656 Comm: sh Tainted: G O 3.12.10-gc559824 #1 [ 120.981669] Backtrace: [ 120.981705] [] (dump_backtrace+0x0/0x10c) from [] (show_stack+0x18/0x1c) [ 120.981730] r6:c02819ac r5:00000009 r4:ec137cb8 r3:00000000 [ 120.981767] [] (show_stack+0x0/0x1c) from [] (dump_stack+0x20/0x28) [ 120.981802] [] (dump_stack+0x0/0x28) from [] (warn_slowpath_common+0x70/0x90) [ 120.981830] [] (warn_slowpath_common+0x0/0x90) from [] (warn_slowpath_fmt+0x38/0x40) [ 120.981856] r8:c0855eb0 r7:00000002 r6:f1000700 r5:00000007 r4:80080003 [ 120.981886] [] (warn_slowpath_fmt+0x0/0x40) from [] (l3_interrupt_handler+0x198/0x28c) [ 120.981900] r3:c0801ab8 r2:c06cb354 [ 120.981936] [] (l3_interrupt_handler+0x0/0x28c) from [] (handle_irq_event_percpu+0x54/0x1b8) [ 120.981962] [] (handle_irq_event_percpu+0x0/0x1b8) from [] (handle_irq_event+0x30/0x40) [ 120.981993] [] (handle_irq_event+0x0/0x40) from [] (handle_fasteoi_irq+0x74/0x128) [ 120.982006] r4:ed0056c0 r3:00000000 [ 120.982033] [] (handle_fasteoi_irq+0x0/0x128) from [] (generic_handle_irq+0x28/0x38) [ 120.982046] r4:0000002a r3:c0073fe4 [ 120.982085] [] (generic_handle_irq+0x0/0x38) from [] (handle_IRQ+0x38/0x8c) [ 120.982098] r4:c080137c r3:00000182 [ 120.982124] [] (handle_IRQ+0x0/0x8c) from [] (gic_handle_irq+0x30/0x5c) [ 120.982145] r6:ec137dd0 r5:c07ac480 r4:fa24010c r3:00000100 [ 120.982169] [] (gic_handle_irq+0x0/0x5c) from [] (__irq_svc+0x40/0x54) [ 120.982179] Exception stack(0xec137dd0 to 0xec137e18) [ 120.982195] 7dc0: 00000000 a00001d3 00000000 00000004 [ 120.982216] 7de0: a0000153 ec1d9010 c080de90 ec137e30 c080debc 00000000 ed756e44 ec137e2c [ 120.982232] 7e00: ec137de0 ec137e18 bf1150e4 bf115474 60000153 ffffffff [ 120.982253] r7:ec137e04 r6:ffffffff r5:60000153 r4:bf115474 [ 120.982327] [] (dwc3_complete+0x0/0x40 [dwc3]) from [] (dpm_complete+0xd4/0x19c) [ 120.982341] r5:ed756e10 r4:ed756e64 [ 120.982370] [] (dpm_complete+0x0/0x19c) from [] (dpm_resume_end+0x1c/0x20) [ 120.982400] [] (dpm_resume_end+0x0/0x20) from [] (suspend_devices_and_enter+0x118/0x33c) [ 120.982412] r4:c0833da4 r3:00000000 [ 120.982436] [] (suspend_devices_and_enter+0x0/0x33c) from [] (pm_suspend+0x218/0x254) [ 120.982458] [] (pm_suspend+0x0/0x254) from [] (state_store+0x70/0xc0) [ 120.982478] r6:c057a6cc r5:c06a8320 r4:00000003 r3:0000006d [ 120.982515] [] (state_store+0x0/0xc0) from [] (kobj_attr_store+0x1c/0x28) [ 120.982546] [] (kobj_attr_store+0x0/0x28) from [] (sysfs_write_file+0x170/0x1a4) [ 120.982583] [] (sysfs_write_file+0x0/0x1a4) from [] (vfs_write+0xb8/0x190) [ 120.982611] [] (vfs_write+0x0/0x190) from [] (SyS_write+0x44/0x78) [ 120.982641] [] (SyS_write+0x0/0x78) from [] (ret_fast_syscall+0x0/0x30) Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index d001417e8e37..10aaaae9af25 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -821,6 +821,7 @@ static void dwc3_complete(struct device *dev) spin_lock_irqsave(&dwc->lock, flags); + dwc3_event_buffers_setup(dwc); switch (dwc->dr_mode) { case USB_DR_MODE_PERIPHERAL: case USB_DR_MODE_OTG: @@ -828,7 +829,6 @@ static void dwc3_complete(struct device *dev) /* FALLTHROUGH */ case USB_DR_MODE_HOST: default: - dwc3_event_buffers_setup(dwc); break; } -- GitLab From 5cdf7d5be8443ba0e14a5cfe551c59f931983647 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 27 Mar 2014 08:09:21 +0100 Subject: [PATCH 323/797] usb: gadget: gadgetfs: Initialize CHIP to NULL before UDC probe Otherwise the value from the last probe would be retained that possibly is freed since (the UDC is removed) and therefore no longer relevant. Reproducible with the dummy UDC: modprobe dummy_hcd mount -t gadgetfs gadgetfs /dev/gadget umount /dev/gadget rmmod dummy_hcd mount -t gadgetfs gadgetfs /dev/gadget BUG: unable to handle kernel paging request at ffffffffa066fd9d Call Trace: [] ? d_alloc_name+0x22/0x50 [] ? selinux_d_instantiate+0x1c/0x20 [] gadgetfs_create_file+0x27/0xa0 [gadgetfs] [] ? setup_req.isra.4+0x80/0x80 [gadgetfs] [] gadgetfs_fill_super+0x13c/0x180 [gadgetfs] [] mount_single+0x92/0xc0 [] gadgetfs_mount+0x18/0x20 [gadgetfs] [] mount_fs+0x39/0x1b0 [] ? __alloc_percpu+0x10/0x20 [] vfs_kern_mount+0x63/0xf0 [] do_mount+0x23e/0xac0 [] ? strndup_user+0x4b/0xf0 [] SyS_mount+0x83/0xc0 [] system_call_fastpath+0x16/0x1b Signed-off-by: Lubomir Rintel Signed-off-by: Felipe Balbi --- drivers/usb/gadget/inode.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index b5be6f0308c2..a925d0cbcd41 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -2043,6 +2043,7 @@ gadgetfs_fill_super (struct super_block *sb, void *opts, int silent) return -ESRCH; /* fake probe to determine $CHIP */ + CHIP = NULL; usb_gadget_probe_driver(&probe_driver); if (!CHIP) return -ENODEV; -- GitLab From 0fca91b8a446d4a38b8f3d4772c4a8665ebcd7b2 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 2 Apr 2014 11:46:51 +0200 Subject: [PATCH 324/797] usb: musb: dsps: move debugfs_remove_recursive() When the platform initialization fails due to missing resources, it will return -EPROBE_DEFER after dsps_musb_init() has been called. dsps_musb_init() calls dsps_musb_dbg_init() to allocate the debugfs nodes. At a later point in time, the probe will be retried, and dsps_musb_dbg_init() will be called again. debugfs_create_dir() will fail this time, as the node already exists, and so the entire device probe will fail with -ENOMEM. Fix this by moving debugfs_remove_recursive() from dsps_remove() to the plaform's exit function, so it will be cleanly torn down when the probe fails. It also feels more natural this way, as .exit is the counterpart to .init. Signed-off-by: Daniel Mack Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_dsps.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 3372ded5def7..e2fd263585de 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c @@ -470,8 +470,9 @@ static int dsps_musb_exit(struct musb *musb) struct dsps_glue *glue = dev_get_drvdata(dev->parent); del_timer_sync(&glue->timer); - usb_phy_shutdown(musb->xceiv); + debugfs_remove_recursive(glue->dbgfs_root); + return 0; } @@ -708,8 +709,6 @@ static int dsps_remove(struct platform_device *pdev) pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - debugfs_remove_recursive(glue->dbgfs_root); - return 0; } -- GitLab From fc696881c6ec991f39a2f93d41f9ae841c6ace38 Mon Sep 17 00:00:00 2001 From: Suresh Gupta Date: Wed, 2 Apr 2014 22:26:46 +0530 Subject: [PATCH 325/797] usb : gadget : fsl: fix the fault issue on rmmod completion in udc_controller->done should be assign with proper value before complete called. The complete called in fsl_udc_release which intern called from usb_del_gadget_udc, so moving assignment before calling usb_del_gadget_udc Signed-off-by: Suresh Gupta Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 15960af0f67e..dcd0b07ae3a0 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -2532,8 +2532,8 @@ static int __exit fsl_udc_remove(struct platform_device *pdev) if (!udc_controller) return -ENODEV; - usb_del_gadget_udc(&udc_controller->gadget); udc_controller->done = &done; + usb_del_gadget_udc(&udc_controller->gadget); fsl_udc_clk_release(); -- GitLab From ae8dd0cc4146740e24ffb2092530c47e838001c5 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 4 Apr 2014 22:27:59 -0300 Subject: [PATCH 326/797] usb: gadget: rndis: Include "u_rndis.h" Include "u_rndis.h" in order to fix the following sparse warning: drivers/usb/gadget/rndis.c:1144:5: warning: symbol 'rndis_init' was not declared. Should it be static? drivers/usb/gadget/rndis.c:1177:6: warning: symbol 'rndis_exit' was not declared. Should it be static? Signed-off-by: Fabio Estevam Signed-off-by: Felipe Balbi --- drivers/usb/gadget/rndis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index d822d822efb3..7ed452d90f4d 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c @@ -35,6 +35,7 @@ #include #include +#include "u_rndis.h" #undef VERBOSE_DEBUG -- GitLab From 9dc9cb0c9ad0f999e29ce4c4f307cd2abbe752d3 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Tue, 15 Apr 2014 07:58:15 +0200 Subject: [PATCH 327/797] usb: phy: return an error in usb_get_phy() if try_module_get() fails In case we found a matching USB PHY in usb_get_phy() but the call to try_module_get() fails, we shouldn't return a (probably soon dangling) pointer but an ERR_PTR instead. Signed-off-by: Mathias Krause Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/phy/phy.c b/drivers/usb/phy/phy.c index 8afa813d690b..36b6bce33b20 100644 --- a/drivers/usb/phy/phy.c +++ b/drivers/usb/phy/phy.c @@ -132,6 +132,9 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type) if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { pr_debug("PHY: unable to find transceiver of type %s\n", usb_phy_type_string(type)); + if (!IS_ERR(phy)) + phy = ERR_PTR(-ENODEV); + goto err0; } -- GitLab From 97839ca4b06ab27790700ad7da6be9a75fc0cc1d Mon Sep 17 00:00:00 2001 From: Chao Bi Date: Mon, 14 Apr 2014 11:19:53 +0800 Subject: [PATCH 328/797] usb: gadget: ffs: race between ffs_epfile_io() and ffs_func_eps_disable() ffs_epfile_io() is called from userspace, while ffs_func_eps_disable() might be called from USB disconnect interrupt, the two functions would run in parallel but they are not well protected, that epfile->ep would be removed by ffs_func_eps_disable() during ffs_epfile_io() is referring this pointer, then it leads to kernel PANIC. The scenario is as below: Thread 1 Thread 2 | | SyS_read dwc3_gadget_disconnect_interrupt | | ffs_epfile_read reset_config | | ffs_epfile_io ffs_func_eps_disable | | ----- usb_ep_disable(): epfile->ep->ep->desc = NULL | | usb_ep_align_maybe(): ----- it refers ep->desc->wMaxPacketSize ----- Signed-off-by: Chao Bi Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_fs.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 2e164dca08e8..1e12b3ee56fd 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -745,6 +745,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) */ struct usb_gadget *gadget = epfile->ffs->gadget; + spin_lock_irq(&epfile->ffs->eps_lock); + /* In the meantime, endpoint got disabled or changed. */ + if (epfile->ep != ep) { + spin_unlock_irq(&epfile->ffs->eps_lock); + return -ESHUTDOWN; + } /* * Controller may require buffer size to be aligned to * maxpacketsize of an out endpoint. @@ -752,6 +758,7 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data) data_len = io_data->read ? usb_ep_align_maybe(gadget, ep->ep, io_data->len) : io_data->len; + spin_unlock_irq(&epfile->ffs->eps_lock); data = kmalloc(data_len, GFP_KERNEL); if (unlikely(!data)) -- GitLab From c23fdc7da4853c25509255419bf88ed94cd42a5b Mon Sep 17 00:00:00 2001 From: Mohit Kumar Date: Wed, 16 Apr 2014 10:23:28 -0600 Subject: [PATCH 329/797] PCI: designware: Fix comment for setting number of lanes Corrects comment for setting number of lanes. Signed-off-by: Mohit Kumar Signed-off-by: Bjorn Helgaas Acked-by: Jingoo Han --- drivers/pci/host/pcie-designware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 509a29d84509..8909e7748e67 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -764,7 +764,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) u32 membase; u32 memlimit; - /* set the number of lines as 4 */ + /* set the number of lanes */ dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val); val &= ~PORT_LINK_MODE_MASK; switch (pp->lanes) { -- GitLab From 017fcdc30cdae18c0946eef1ece1f14b4c7897ba Mon Sep 17 00:00:00 2001 From: Mohit Kumar Date: Wed, 16 Apr 2014 10:23:34 -0600 Subject: [PATCH 330/797] PCI: designware: Fix iATU programming for cfg1, io and mem viewport This patch corrects iATU programming for cfg1, io and mem viewport. Enable ATU only after configuring it. Signed-off-by: Mohit Kumar Signed-off-by: Ajay Khandelwal Signed-off-by: Bjorn Helgaas Acked-by: Jingoo Han Cc: stable@vger.kernel.org --- drivers/pci/host/pcie-designware.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 8909e7748e67..a9a62ce4bf05 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -520,13 +520,13 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, PCIE_ATU_VIEWPORT); dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE); dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE); dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1, PCIE_ATU_LIMIT); dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); } static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) @@ -535,7 +535,6 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, PCIE_ATU_VIEWPORT); dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE); dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE); dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1, @@ -543,6 +542,7 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), PCIE_ATU_UPPER_TARGET); + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); } static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) @@ -551,7 +551,6 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, PCIE_ATU_VIEWPORT); dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); - dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE); dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE); dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1, @@ -559,6 +558,7 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), PCIE_ATU_UPPER_TARGET); + dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2); } static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, -- GitLab From f86b3e392780050e5907f1c0f3cb6c4cc05fd6bb Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 Apr 2014 10:23:46 -0600 Subject: [PATCH 331/797] PCI: designware: Use new OF interrupt mapping when possible Use new OF interrupt mapping (of_irq_parse_and_map_pci()) when possible. This is the recommended method of doing the IRQ mapping. For old devicetrees we fall back to the previous practice. This makes INTB, INTC, and INTD work on i.MX. Tested-by: Tim Harvey Signed-off-by: Lucas Stach Signed-off-by: Bjorn Helgaas Reviewed-by: Marek Vasut Acked-by: Arnd Bergmann Acked-by: Jingoo Han --- drivers/pci/host/pcie-designware.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index a9a62ce4bf05..c4e373294476 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -490,7 +491,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp) dw_pci.nr_controllers = 1; dw_pci.private_data = (void **)&pp; - pci_common_init(&dw_pci); + pci_common_init_dev(pp->dev, &dw_pci); pci_assign_unassigned_resources(); #ifdef CONFIG_PCI_DOMAINS dw_pci.domain++; @@ -723,7 +724,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) if (pp) { pp->root_bus_nr = sys->busnr; - bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops, + bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops, sys, &sys->resources); } else { bus = NULL; @@ -736,8 +737,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); + int irq; - return pp->irq; + irq = of_irq_parse_and_map_pci(dev, slot, pin); + if (!irq) + irq = pp->irq; + + return irq; } static void dw_pcie_add_bus(struct pci_bus *bus) -- GitLab From f8f2fe7355fb04dd129d49ac0ad440beb44f0f79 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 Apr 2014 10:24:09 -0600 Subject: [PATCH 332/797] PCI: rcar: Use new OF interrupt mapping when possible Use new OF interrupt mapping (of_irq_parse_and_map_pci()) when possible. This is the recommended method of doing the IRQ mapping. For old devicetrees we fall back to the previous practice. This allows interrupts to be remapped across bridges. Signed-off-by: Lucas Stach Signed-off-by: Bjorn Helgaas Acked-by: Simon Horman --- drivers/pci/host/pci-rcar-gen2.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index fd3e3ab56509..4fe349dcaf59 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -180,8 +181,13 @@ static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) { struct pci_sys_data *sys = dev->bus->sysdata; struct rcar_pci_priv *priv = sys->private_data; + int irq; + + irq = of_irq_parse_and_map_pci(dev, slot, pin); + if (!irq) + irq = priv->irq; - return priv->irq; + return irq; } #ifdef CONFIG_PCI_DEBUG -- GitLab From f5d3352b2751f8de7e06e23a04ac0b4c474075e9 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Wed, 16 Apr 2014 10:24:32 -0600 Subject: [PATCH 333/797] PCI: tegra: Use new OF interrupt mapping when possible Use new OF interrupt mapping (of_irq_parse_and_map_pci()) when possible. This is the recommended method of doing the IRQ mapping. For old devicetrees we fall back to the previous practice. This allows interrupts to be remapped across bridges. Tested-by: Stephen Warren Signed-off-by: Lucas Stach Signed-off-by: Bjorn Helgaas Acked-by: Arnd Bergmann --- drivers/pci/host/pci-tegra.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 330f7e3a32dd..083cf37ca047 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -639,10 +639,15 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) { struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata); + int irq; tegra_cpuidle_pcie_irqs_in_use(); - return pcie->irq; + irq = of_irq_parse_and_map_pci(pdev, slot, pin); + if (!irq) + irq = pcie->irq; + + return irq; } static void tegra_pcie_add_bus(struct pci_bus *bus) -- GitLab From 9ae794ac5e407d3bc3fec785db481d5a2c0fa275 Mon Sep 17 00:00:00 2001 From: David Milburn Date: Wed, 16 Apr 2014 11:43:46 -0500 Subject: [PATCH 334/797] ahci: do not request irq for dummy port System may crash in ahci_hw_interrupt() or ahci_thread_fn() when accessing the interrupt status in a port's private_data if the port is actually a DUMMY port. 00:1f.2 SATA controller: Intel Corporation 82801JI (ICH10 Family) SATA AHCI Controller [ 9.352080] ahci 0000:00:1f.2: AHCI 0001.0200 32 slots 6 ports 3 Gbps 0x1 impl SATA mode [ 9.352084] ahci 0000:00:1f.2: flags: 64bit ncq sntf pm led clo pio slum part ccc [ 9.368155] Console: switching to colour frame buffer device 128x48 [ 9.439759] mgag200 0000:11:00.0: fb0: mgadrmfb frame buffer device [ 9.446765] mgag200 0000:11:00.0: registered panic notifier [ 9.470166] scsi1 : ahci [ 9.479166] scsi2 : ahci [ 9.488172] scsi3 : ahci [ 9.497174] scsi4 : ahci [ 9.506175] scsi5 : ahci [ 9.515174] scsi6 : ahci [ 9.518181] ata1: SATA max UDMA/133 abar m2048@0x95c00000 port 0x95c00100 irq 91 [ 9.526448] ata2: DUMMY [ 9.529182] ata3: DUMMY [ 9.531916] ata4: DUMMY [ 9.534650] ata5: DUMMY [ 9.537382] ata6: DUMMY [ 9.576196] [drm] Initialized mgag200 1.0.0 20110418 for 0000:11:00.0 on minor 0 [ 9.845257] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300) [ 9.865161] ata1.00: ATAPI: Optiarc DVD RW AD-7580S, FX04, max UDMA/100 [ 9.891407] ata1.00: configured for UDMA/100 [ 9.900525] scsi 1:0:0:0: CD-ROM Optiarc DVD RW AD-7580S FX04 PQ: 0 ANSI: 5 [ 10.247399] iTCO_vendor_support: vendor-support=0 [ 10.261572] iTCO_wdt: Intel TCO WatchDog Timer Driver v1.11 [ 10.269764] iTCO_wdt: unable to reset NO_REBOOT flag, device disabled by hardware/BIOS [ 10.301932] sd 0:2:0:0: [sda] 570310656 512-byte logical blocks: (291 GB/271 GiB) [ 10.317085] sd 0:2:0:0: [sda] Write Protect is off [ 10.328326] sd 0:2:0:0: [sda] Write cache: disabled, read cache: disabled, supports DPO and FUA [ 10.375452] BUG: unable to handle kernel NULL pointer dereference at 000000000000003c [ 10.384217] IP: [] ahci_hw_interrupt+0x100/0x130 [libahci] [ 10.392101] PGD 0 [ 10.394353] Oops: 0000 [#1] SMP [ 10.397978] Modules linked in: sr_mod(+) cdrom sd_mod iTCO_wdt crc_t10dif iTCO_vendor_support crct10dif_common ahci libahci libata lpc_ich mfd_core mgag200 syscopyarea sysfillrect sysimgblt i2c_algo_bit drm_kms_helper ttm drm i2c_core megaraid_sas dm_mirror dm_region_hash dm_log dm_mod [ 10.426499] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.15.0-rc1 #1 [ 10.433495] Hardware name: QCI QSSC-S4R/QSSC-S4R, BIOS QSSC-S4R.QCI.01.00.S013.032920111005 03/29/2011 [ 10.443886] task: ffffffff81906460 ti: ffffffff818f0000 task.ti: ffffffff818f0000 [ 10.452239] RIP: 0010:[] [] ahci_hw_interrupt+0x100/0x130 [libahci] [ 10.462838] RSP: 0018:ffff880033c03d98 EFLAGS: 00010046 [ 10.468767] RAX: 0000000000a400a4 RBX: ffff880029a6bc18 RCX: 00000000fffffffa [ 10.476731] RDX: 00000000000000a4 RSI: ffff880029bb0000 RDI: ffff880029a6bc18 [ 10.484696] RBP: ffff880033c03dc8 R08: 0000000000000000 R09: ffff88002f800490 [ 10.492661] R10: 0000000000000000 R11: 0000000000000005 R12: 0000000000000000 [ 10.500625] R13: ffff880029a6bd98 R14: 0000000000000000 R15: ffffc90000194000 [ 10.508590] FS: 0000000000000000(0000) GS:ffff880033c00000(0000) knlGS:0000000000000000 [ 10.517623] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 10.524035] CR2: 000000000000003c CR3: 00000000328ff000 CR4: 00000000000007b0 [ 10.531999] Stack: [ 10.534241] 0000000000000017 ffff880031ba7d00 000000000000005c ffff880031ba7d00 [ 10.542535] 0000000000000000 000000000000005c ffff880033c03e10 ffffffff810c2a1e [ 10.550827] ffff880031ae2900 000000008108fb4f ffff880031ae2900 ffff880031ae2984 [ 10.559121] Call Trace: [ 10.561849] [ 10.563994] [] handle_irq_event_percpu+0x3e/0x1a0 [ 10.571309] [] handle_irq_event+0x3d/0x60 [ 10.577631] [] try_one_irq.isra.6+0x8d/0xf0 [ 10.584142] [] note_interrupt+0x173/0x1f0 [ 10.590460] [] handle_irq_event_percpu+0xae/0x1a0 [ 10.597554] [] handle_irq_event+0x3d/0x60 [ 10.603872] [] handle_edge_irq+0x77/0x130 [ 10.610199] [] handle_irq+0xbf/0x150 [ 10.616040] [] ? vtime_account_idle+0xe/0x50 [ 10.622654] [] ? atomic_notifier_call_chain+0x1a/0x20 [ 10.630140] [] do_IRQ+0x4f/0xf0 [ 10.635490] [] common_interrupt+0x6d/0x6d [ 10.641805] [ 10.643950] [] ? cpuidle_enter_state+0x4f/0xc0 [ 10.650972] [] ? cpuidle_enter_state+0x48/0xc0 [ 10.657775] [] cpuidle_enter+0x17/0x20 [ 10.663807] [] cpu_startup_entry+0x2c0/0x3d0 [ 10.670423] [] rest_init+0x77/0x80 [ 10.676065] [] start_kernel+0x40f/0x41a [ 10.682190] [] ? repair_env_string+0x5c/0x5c [ 10.688799] [] ? early_idt_handlers+0x120/0x120 [ 10.695699] [] x86_64_start_reservations+0x2a/0x2c [ 10.702889] [] x86_64_start_kernel+0x143/0x152 [ 10.709689] Code: a0 fc ff 85 c0 8b 4d d4 74 c3 48 8b 7b 08 89 ca 48 c7 c6 60 66 13 a0 31 c0 e8 9d 70 28 e1 8b 4d d4 eb aa 0f 1f 84 00 00 00 00 00 <45> 8b 64 24 3c 48 89 df e8 23 47 4c e1 41 83 fc 01 19 c0 48 83 [ 10.731470] RIP [] ahci_hw_interrupt+0x100/0x130 [libahci] [ 10.739441] RSP [ 10.743333] CR2: 000000000000003c [ 10.747032] ---[ end trace b6e82636970e2690 ]--- [ 10.760190] Kernel panic - not syncing: Fatal exception in interrupt [ 10.767291] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff) Cc: Alexander Gordeev Cc: Tejun Heo Cc: Signed-of-by: David Milburn Fixes: 5ca72c4f7c41 ("AHCI: Support multiple MSIs") --- drivers/ata/ahci.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 5a0bf8ed649b..e45b18ee04c3 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1232,18 +1232,14 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis) return rc; for (i = 0; i < host->n_ports; i++) { - const char* desc; struct ahci_port_priv *pp = host->ports[i]->private_data; /* pp is NULL for dummy ports */ if (pp) - desc = pp->irq_desc; - else - desc = dev_driver_string(host->dev); - - rc = devm_request_threaded_irq(host->dev, - irq + i, ahci_hw_interrupt, ahci_thread_fn, IRQF_SHARED, - desc, host->ports[i]); + rc = devm_request_threaded_irq(host->dev, + irq + i, ahci_hw_interrupt, + ahci_thread_fn, IRQF_SHARED, + pp->irq_desc, host->ports[i]); if (rc) goto out_free_irqs; } -- GitLab From c0b5a64d937f8fff79b10410a8a70ecaa9a1c580 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Fri, 28 Mar 2014 14:42:07 -0700 Subject: [PATCH 335/797] [IA64] Change default PSR.ac from '1' to '0' (Fix erratum #237) April 2014 Itanium processor specification update: http://www.intel.com/content/www/us/en/processors/itanium/itanium-specification-update.html describes this erratum: ========================================================================= 237. Under a complex set of conditions, store to load forwarding for a sub 8-byte load may complete incorrectly Problem: A load instruction may complete incorrectly when a code sequence using 4-byte or smaller load and store operations to the same address is executed in combination with specific timing of all the following concurrent conditions: store to load forwarding, alignment checking enabled, a mis-predicted branch, and complex cache utilization activity. Implication: The affected sub 8-byte instruction may complete incorrectly resulting in unpredictable system behavior. There is an extremely low probability of exposure due to the significant number of complex microarchitectural concurrent conditions required to encounter the erratum. Workaround: Set PSR.ac = 0 to completely avoid the erratum. Disabling Hyper-Threading will significantly reduce exposure to the conditions that contribute to encountering the erratum. Status: See the Summary Table of Changes for the affected steppings. ========================================================================= [Table of changes essentially lists all models from McKinley to Tukwila] The PSR.ac bit controls whether the processor will always generate an unaligned reference trap (0x5a00) for a misaligned data access (when PSR.ac=1) or if it will let the access succeed when running on a cpu that implements logic to handle some unaligned accesses. Way back in 2008 in commit b704882e70d87d7f56db5ff17e2253f3fa90e4f3 [IA64] Rationalize kernel mode alignment checking we made the decision to always enable strict checking. We were already doing so in trap/interrupt context because the common preamble code set this bit - but the rest of supervisor code (and by inheritance user code) ran with PSR.ac=0. We now reverse that decision and set PSR.ac=0 everywhere in the kernel (also inherited by user processes). This will avoid the erratum using the method described in the Itanium specification update. Net effect for users is that the processor will handle unaligned access when it can (typically with a tiny performance bubble in the pipeline ... but much less invasive than taking a trap and having the OS perform the access). Signed-off-by: Tony Luck --- arch/ia64/kernel/head.S | 2 +- arch/ia64/kernel/ivt.S | 2 +- arch/ia64/kvm/vmm_ivt.S | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index e6f80fcf013b..a4acddad0c78 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -259,7 +259,7 @@ start_ap: * Switch into virtual mode: */ movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \ - |IA64_PSR_DI|IA64_PSR_AC) + |IA64_PSR_DI) ;; mov cr.ipsr=r16 movl r17=1f diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index 689ffcaa284e..18e794a57248 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -58,7 +58,7 @@ #include #include -#if 1 +#if 0 # define PSR_DEFAULT_BITS psr.ac #else # define PSR_DEFAULT_BITS 0 diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S index 24018484c6e9..397e34a63e18 100644 --- a/arch/ia64/kvm/vmm_ivt.S +++ b/arch/ia64/kvm/vmm_ivt.S @@ -64,7 +64,7 @@ #include "kvm_minstate.h" #include "vti.h" -#if 1 +#if 0 # define PSR_DEFAULT_BITS psr.ac #else # define PSR_DEFAULT_BITS 0 -- GitLab From e02ba72aabfade4c9cd6e3263e9b57bf890ad25c Mon Sep 17 00:00:00 2001 From: Anatol Pomozov Date: Tue, 15 Apr 2014 11:31:33 -0700 Subject: [PATCH 336/797] aio: block io_destroy() until all context requests are completed deletes aio context and all resources related to. It makes sense that no IO operations connected to the context should be running after the context is destroyed. As we removed io_context we have no chance to get requests status or call io_getevents(). man page for io_destroy says that this function may block until all context's requests are completed. Before kernel 3.11 io_destroy() blocked indeed, but since aio refactoring in 3.11 it is not true anymore. Here is a pseudo-code that shows a testcase for a race condition discovered in 3.11: initialize io_context io_submit(read to buffer) io_destroy() // context is destroyed so we can free the resources free(buffers); // if the buffer is allocated by some other user he'll be surprised // to learn that the buffer still filled by an outstanding operation // from the destroyed io_context The fix is straight-forward - add a completion struct and wait on it in io_destroy, complete() should be called when number of in-fligh requests reaches zero. If two or more io_destroy() called for the same context simultaneously then only the first one waits for IO completion, other calls behaviour is undefined. Tested: ran http://pastebin.com/LrPsQ4RL testcase for several hours and do not see the race condition anymore. Signed-off-by: Anatol Pomozov Signed-off-by: Benjamin LaHaise --- fs/aio.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 12a3de0ee6da..2adbb0398ab9 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -112,6 +112,11 @@ struct kioctx { struct work_struct free_work; + /* + * signals when all in-flight requests are done + */ + struct completion *requests_done; + struct { /* * This counts the number of available slots in the ringbuffer, @@ -508,6 +513,10 @@ static void free_ioctx_reqs(struct percpu_ref *ref) { struct kioctx *ctx = container_of(ref, struct kioctx, reqs); + /* At this point we know that there are no any in-flight requests */ + if (ctx->requests_done) + complete(ctx->requests_done); + INIT_WORK(&ctx->free_work, free_ioctx); schedule_work(&ctx->free_work); } @@ -718,7 +727,8 @@ static struct kioctx *ioctx_alloc(unsigned nr_events) * when the processes owning a context have all exited to encourage * the rapid destruction of the kioctx. */ -static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx) +static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx, + struct completion *requests_done) { if (!atomic_xchg(&ctx->dead, 1)) { struct kioctx_table *table; @@ -747,7 +757,11 @@ static void kill_ioctx(struct mm_struct *mm, struct kioctx *ctx) if (ctx->mmap_size) vm_munmap(ctx->mmap_base, ctx->mmap_size); + ctx->requests_done = requests_done; percpu_ref_kill(&ctx->users); + } else { + if (requests_done) + complete(requests_done); } } @@ -809,7 +823,7 @@ void exit_aio(struct mm_struct *mm) */ ctx->mmap_size = 0; - kill_ioctx(mm, ctx); + kill_ioctx(mm, ctx, NULL); } } @@ -1185,7 +1199,7 @@ SYSCALL_DEFINE2(io_setup, unsigned, nr_events, aio_context_t __user *, ctxp) if (!IS_ERR(ioctx)) { ret = put_user(ioctx->user_id, ctxp); if (ret) - kill_ioctx(current->mm, ioctx); + kill_ioctx(current->mm, ioctx, NULL); percpu_ref_put(&ioctx->users); } @@ -1203,8 +1217,22 @@ SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx) { struct kioctx *ioctx = lookup_ioctx(ctx); if (likely(NULL != ioctx)) { - kill_ioctx(current->mm, ioctx); + struct completion requests_done = + COMPLETION_INITIALIZER_ONSTACK(requests_done); + + /* Pass requests_done to kill_ioctx() where it can be set + * in a thread-safe way. If we try to set it here then we have + * a race condition if two io_destroy() called simultaneously. + */ + kill_ioctx(current->mm, ioctx, &requests_done); percpu_ref_put(&ioctx->users); + + /* Wait until all IO for the context are done. Otherwise kernel + * keep using user-space buffers even if user thinks the context + * is destroyed. + */ + wait_for_completion(&requests_done); + return 0; } pr_debug("EINVAL: io_destroy: invalid context id\n"); -- GitLab From e283546c0465dd3026bc94f7b1a9de7f6b8969ec Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Wed, 16 Apr 2014 19:27:48 +0100 Subject: [PATCH 337/797] sfc:On MCDI timeout, issue an FLR (and mark MCDI to fail-fast) When an MCDI command times out (whether or not we find it completed when we poll), call efx_mcdi_abandon(), which tells all subsequent MCDI calls to fail-fast, and queues up an FLR. Because an FLR doesn't lead to receiving any reboot even from the MC (unlike most other types of reset), we have to call efx_ef10_reset_mc_allocations. In efx_start_all(), if a reset (of any kind) is pending, we bail out. Without this, attempts to reconfigure (e.g. change mtu) can cause driver/mc state inconsistency if the first MCDI call triggers an FLR. For similar reasons, on EF10, in efx_reset_down(method=RESET_TYPE_MCDI_TIMEOUT), set the number of active queues to zero before calling efx_stop_all(). And, on farch, in efx_reset_up(method=RESET_TYPE_MCDI_TIMEOUT), set active_queues and flushes pending & outstanding to zero. efx_mcdi_mode_{poll,event}() should not take us out of fail-fast mode. Instead, this is done by efx_mcdi_reset() after the FLR completes. The new FLR reset_type RESET_TYPE_MCDI_TIMEOUT doesn't really fit into the hierarchy of reset 'scopes' whereby efx_reset() decides some resets subsume others. Thus, it uses separate logic. Also, fixed up some inconsistency around RESET_TYPE_MC_BIST, which was in the wrong place in that hierarchy. Signed-off-by: Shradha Shah Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef10.c | 12 +++++- drivers/net/ethernet/sfc/efx.c | 19 +++++++-- drivers/net/ethernet/sfc/enum.h | 23 +++++++---- drivers/net/ethernet/sfc/falcon.c | 4 ++ drivers/net/ethernet/sfc/farch.c | 22 +++++++++++ drivers/net/ethernet/sfc/mcdi.c | 55 +++++++++++++++++++++------ drivers/net/ethernet/sfc/mcdi.h | 13 +++++++ drivers/net/ethernet/sfc/net_driver.h | 4 ++ drivers/net/ethernet/sfc/nic.h | 1 + drivers/net/ethernet/sfc/siena.c | 2 + 10 files changed, 133 insertions(+), 22 deletions(-) diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 21c20ea0dad0..b5ed30a39144 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -738,8 +738,11 @@ static int efx_ef10_reset(struct efx_nic *efx, enum reset_type reset_type) /* If it was a port reset, trigger reallocation of MC resources. * Note that on an MC reset nothing needs to be done now because we'll * detect the MC reset later and handle it then. + * For an FLR, we never get an MC reset event, but the MC has reset all + * resources assigned to us, so we have to trigger reallocation now. */ - if (reset_type == RESET_TYPE_ALL && !rc) + if ((reset_type == RESET_TYPE_ALL || + reset_type == RESET_TYPE_MCDI_TIMEOUT) && !rc) efx_ef10_reset_mc_allocations(efx); return rc; } @@ -2141,6 +2144,11 @@ static int efx_ef10_fini_dmaq(struct efx_nic *efx) return 0; } +static void efx_ef10_prepare_flr(struct efx_nic *efx) +{ + atomic_set(&efx->active_queues, 0); +} + static bool efx_ef10_filter_equal(const struct efx_filter_spec *left, const struct efx_filter_spec *right) { @@ -3603,6 +3611,8 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { .probe_port = efx_mcdi_port_probe, .remove_port = efx_mcdi_port_remove, .fini_dmaq = efx_ef10_fini_dmaq, + .prepare_flr = efx_ef10_prepare_flr, + .finish_flr = efx_port_dummy_op_void, .describe_stats = efx_ef10_describe_stats, .update_stats = efx_ef10_update_stats, .start_stats = efx_mcdi_mac_start_stats, diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 57b971e5e6b2..63d595fd3cc5 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -76,6 +76,7 @@ const char *const efx_reset_type_names[] = { [RESET_TYPE_RECOVER_OR_ALL] = "RECOVER_OR_ALL", [RESET_TYPE_WORLD] = "WORLD", [RESET_TYPE_RECOVER_OR_DISABLE] = "RECOVER_OR_DISABLE", + [RESET_TYPE_MC_BIST] = "MC_BIST", [RESET_TYPE_DISABLE] = "DISABLE", [RESET_TYPE_TX_WATCHDOG] = "TX_WATCHDOG", [RESET_TYPE_INT_ERROR] = "INT_ERROR", @@ -83,7 +84,7 @@ const char *const efx_reset_type_names[] = { [RESET_TYPE_DMA_ERROR] = "DMA_ERROR", [RESET_TYPE_TX_SKIP] = "TX_SKIP", [RESET_TYPE_MC_FAILURE] = "MC_FAILURE", - [RESET_TYPE_MC_BIST] = "MC_BIST", + [RESET_TYPE_MCDI_TIMEOUT] = "MCDI_TIMEOUT (FLR)", }; /* Reset workqueue. If any NIC has a hardware failure then a reset will be @@ -1739,7 +1740,8 @@ static void efx_start_all(struct efx_nic *efx) /* Check that it is appropriate to restart the interface. All * of these flags are safe to read under just the rtnl lock */ - if (efx->port_enabled || !netif_running(efx->net_dev)) + if (efx->port_enabled || !netif_running(efx->net_dev) || + efx->reset_pending) return; efx_start_port(efx); @@ -2334,6 +2336,9 @@ void efx_reset_down(struct efx_nic *efx, enum reset_type method) { EFX_ASSERT_RESET_SERIALISED(efx); + if (method == RESET_TYPE_MCDI_TIMEOUT) + efx->type->prepare_flr(efx); + efx_stop_all(efx); efx_disable_interrupts(efx); @@ -2354,6 +2359,10 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) EFX_ASSERT_RESET_SERIALISED(efx); + if (method == RESET_TYPE_MCDI_TIMEOUT) + efx->type->finish_flr(efx); + + /* Ensure that SRAM is initialised even if we're disabling the device */ rc = efx->type->init(efx); if (rc) { netif_err(efx, drv, efx->net_dev, "failed to initialise NIC\n"); @@ -2417,7 +2426,10 @@ int efx_reset(struct efx_nic *efx, enum reset_type method) /* Clear flags for the scopes we covered. We assume the NIC and * driver are now quiescent so that there is no race here. */ - efx->reset_pending &= -(1 << (method + 1)); + if (method < RESET_TYPE_MAX_METHOD) + efx->reset_pending &= -(1 << (method + 1)); + else /* it doesn't fit into the well-ordered scope hierarchy */ + __clear_bit(method, &efx->reset_pending); /* Reinitialise bus-mastering, which may have been turned off before * the reset was scheduled. This is still appropriate, even in the @@ -2546,6 +2558,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) case RESET_TYPE_DISABLE: case RESET_TYPE_RECOVER_OR_DISABLE: case RESET_TYPE_MC_BIST: + case RESET_TYPE_MCDI_TIMEOUT: method = type; netif_dbg(efx, drv, efx->net_dev, "scheduling %s reset\n", RESET_TYPE(method)); diff --git a/drivers/net/ethernet/sfc/enum.h b/drivers/net/ethernet/sfc/enum.h index 75ef7ef6450b..d1dbb5fb31bb 100644 --- a/drivers/net/ethernet/sfc/enum.h +++ b/drivers/net/ethernet/sfc/enum.h @@ -143,6 +143,7 @@ enum efx_loopback_mode { * @RESET_TYPE_WORLD: Reset as much as possible * @RESET_TYPE_RECOVER_OR_DISABLE: Try to recover. Apply RESET_TYPE_DISABLE if * unsuccessful. + * @RESET_TYPE_MC_BIST: MC entering BIST mode. * @RESET_TYPE_DISABLE: Reset datapath, MAC and PHY; leave NIC disabled * @RESET_TYPE_TX_WATCHDOG: reset due to TX watchdog * @RESET_TYPE_INT_ERROR: reset due to internal error @@ -150,14 +151,16 @@ enum efx_loopback_mode { * @RESET_TYPE_DMA_ERROR: DMA error * @RESET_TYPE_TX_SKIP: hardware completed empty tx descriptors * @RESET_TYPE_MC_FAILURE: MC reboot/assertion + * @RESET_TYPE_MCDI_TIMEOUT: MCDI timeout. */ enum reset_type { - RESET_TYPE_INVISIBLE = 0, - RESET_TYPE_RECOVER_OR_ALL = 1, - RESET_TYPE_ALL = 2, - RESET_TYPE_WORLD = 3, - RESET_TYPE_RECOVER_OR_DISABLE = 4, - RESET_TYPE_DISABLE = 5, + RESET_TYPE_INVISIBLE, + RESET_TYPE_RECOVER_OR_ALL, + RESET_TYPE_ALL, + RESET_TYPE_WORLD, + RESET_TYPE_RECOVER_OR_DISABLE, + RESET_TYPE_MC_BIST, + RESET_TYPE_DISABLE, RESET_TYPE_MAX_METHOD, RESET_TYPE_TX_WATCHDOG, RESET_TYPE_INT_ERROR, @@ -165,7 +168,13 @@ enum reset_type { RESET_TYPE_DMA_ERROR, RESET_TYPE_TX_SKIP, RESET_TYPE_MC_FAILURE, - RESET_TYPE_MC_BIST, + /* RESET_TYPE_MCDI_TIMEOUT is actually a method, not just a reason, but + * it doesn't fit the scope hierarchy (not well-ordered by inclusion). + * We encode this by having its enum value be greater than + * RESET_TYPE_MAX_METHOD. This also prevents issuing it with + * efx_ioctl_reset. + */ + RESET_TYPE_MCDI_TIMEOUT, RESET_TYPE_MAX, }; diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 8ec20b713cc6..fae25a418647 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -2696,6 +2696,8 @@ const struct efx_nic_type falcon_a1_nic_type = { .fini_dmaq = efx_farch_fini_dmaq, .prepare_flush = falcon_prepare_flush, .finish_flush = efx_port_dummy_op_void, + .prepare_flr = efx_port_dummy_op_void, + .finish_flr = efx_farch_finish_flr, .describe_stats = falcon_describe_nic_stats, .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, @@ -2790,6 +2792,8 @@ const struct efx_nic_type falcon_b0_nic_type = { .fini_dmaq = efx_farch_fini_dmaq, .prepare_flush = falcon_prepare_flush, .finish_flush = efx_port_dummy_op_void, + .prepare_flr = efx_port_dummy_op_void, + .finish_flr = efx_farch_finish_flr, .describe_stats = falcon_describe_nic_stats, .update_stats = falcon_update_nic_stats, .start_stats = falcon_start_nic_stats, diff --git a/drivers/net/ethernet/sfc/farch.c b/drivers/net/ethernet/sfc/farch.c index a08761360cdf..0537381cd2f6 100644 --- a/drivers/net/ethernet/sfc/farch.c +++ b/drivers/net/ethernet/sfc/farch.c @@ -741,6 +741,28 @@ int efx_farch_fini_dmaq(struct efx_nic *efx) return rc; } +/* Reset queue and flush accounting after FLR + * + * One possible cause of FLR recovery is that DMA may be failing (eg. if bus + * mastering was disabled), in which case we don't receive (RXQ) flush + * completion events. This means that efx->rxq_flush_outstanding remained at 4 + * after the FLR; also, efx->active_queues was non-zero (as no flush completion + * events were received, and we didn't go through efx_check_tx_flush_complete()) + * If we don't fix this up, on the next call to efx_realloc_channels() we won't + * flush any RX queues because efx->rxq_flush_outstanding is at the limit of 4 + * for batched flush requests; and the efx->active_queues gets messed up because + * we keep incrementing for the newly initialised queues, but it never went to + * zero previously. Then we get a timeout every time we try to restart the + * queues, as it doesn't go back to zero when we should be flushing the queues. + */ +void efx_farch_finish_flr(struct efx_nic *efx) +{ + atomic_set(&efx->rxq_flush_pending, 0); + atomic_set(&efx->rxq_flush_outstanding, 0); + atomic_set(&efx->active_queues, 0); +} + + /************************************************************************** * * Event queue processing diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 7bd4b14bf3b3..5239cf9bdc56 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -52,12 +52,7 @@ static void efx_mcdi_timeout_async(unsigned long context); static int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, bool *was_attached_out); static bool efx_mcdi_poll_once(struct efx_nic *efx); - -static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) -{ - EFX_BUG_ON_PARANOID(!efx->mcdi); - return &efx->mcdi->iface; -} +static void efx_mcdi_abandon(struct efx_nic *efx); int efx_mcdi_init(struct efx_nic *efx) { @@ -558,6 +553,8 @@ static int _efx_mcdi_rpc_finish(struct efx_nic *efx, unsigned cmd, size_t inlen, rc = 0; } + efx_mcdi_abandon(efx); + /* Close the race with efx_mcdi_ev_cpl() executing just too late * and completing a request we've just cancelled, by ensuring * that the seqno check therein fails. @@ -672,6 +669,9 @@ int efx_mcdi_rpc_start(struct efx_nic *efx, unsigned cmd, if (efx->mc_bist_for_other_fn) return -ENETDOWN; + if (mcdi->mode == MCDI_MODE_FAIL) + return -ENETDOWN; + efx_mcdi_acquire_sync(mcdi); efx_mcdi_send_request(efx, cmd, inbuf, inlen); return 0; @@ -812,7 +812,11 @@ void efx_mcdi_mode_poll(struct efx_nic *efx) return; mcdi = efx_mcdi(efx); - if (mcdi->mode == MCDI_MODE_POLL) + /* If already in polling mode, nothing to do. + * If in fail-fast state, don't switch to polled completion. + * FLR recovery will do that later. + */ + if (mcdi->mode == MCDI_MODE_POLL || mcdi->mode == MCDI_MODE_FAIL) return; /* We can switch from event completion to polled completion, because @@ -841,8 +845,8 @@ void efx_mcdi_flush_async(struct efx_nic *efx) mcdi = efx_mcdi(efx); - /* We must be in polling mode so no more requests can be queued */ - BUG_ON(mcdi->mode != MCDI_MODE_POLL); + /* We must be in poll or fail mode so no more requests can be queued */ + BUG_ON(mcdi->mode == MCDI_MODE_EVENTS); del_timer_sync(&mcdi->async_timer); @@ -875,8 +879,11 @@ void efx_mcdi_mode_event(struct efx_nic *efx) return; mcdi = efx_mcdi(efx); - - if (mcdi->mode == MCDI_MODE_EVENTS) + /* If already in event completion mode, nothing to do. + * If in fail-fast state, don't switch to event completion. FLR + * recovery will do that later. + */ + if (mcdi->mode == MCDI_MODE_EVENTS || mcdi->mode == MCDI_MODE_FAIL) return; /* We can't switch from polled to event completion in the middle of a @@ -966,6 +973,19 @@ static void efx_mcdi_ev_bist(struct efx_nic *efx) spin_unlock(&mcdi->iface_lock); } +/* MCDI timeouts seen, so make all MCDI calls fail-fast and issue an FLR to try + * to recover. + */ +static void efx_mcdi_abandon(struct efx_nic *efx) +{ + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); + + if (xchg(&mcdi->mode, MCDI_MODE_FAIL) == MCDI_MODE_FAIL) + return; /* it had already been done */ + netif_dbg(efx, hw, efx->net_dev, "MCDI is timing out; trying to recover\n"); + efx_schedule_reset(efx, RESET_TYPE_MCDI_TIMEOUT); +} + /* Called from falcon_process_eventq for MCDI events */ void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event) @@ -1512,6 +1532,19 @@ int efx_mcdi_reset(struct efx_nic *efx, enum reset_type method) { int rc; + /* If MCDI is down, we can't handle_assertion */ + if (method == RESET_TYPE_MCDI_TIMEOUT) { + rc = pci_reset_function(efx->pci_dev); + if (rc) + return rc; + /* Re-enable polled MCDI completion */ + if (efx->mcdi) { + struct efx_mcdi_iface *mcdi = efx_mcdi(efx); + mcdi->mode = MCDI_MODE_POLL; + } + return 0; + } + /* Recover from a failed assertion pre-reset */ rc = efx_mcdi_handle_assertion(efx); if (rc) diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index 52931aebf3c3..56465f7465a2 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -28,9 +28,16 @@ enum efx_mcdi_state { MCDI_STATE_COMPLETED, }; +/** + * enum efx_mcdi_mode - MCDI transaction mode + * @MCDI_MODE_POLL: poll for MCDI completion, until timeout + * @MCDI_MODE_EVENTS: wait for an mcdi_event. On timeout, poll once + * @MCDI_MODE_FAIL: we think MCDI is dead, so fail-fast all calls + */ enum efx_mcdi_mode { MCDI_MODE_POLL, MCDI_MODE_EVENTS, + MCDI_MODE_FAIL, }; /** @@ -104,6 +111,12 @@ struct efx_mcdi_data { u32 fn_flags; }; +static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) +{ + EFX_BUG_ON_PARANOID(!efx->mcdi); + return &efx->mcdi->iface; +} + #ifdef CONFIG_SFC_MCDI_MON static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx) { diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 8a400a0595eb..5bdae8ed7c57 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -972,6 +972,8 @@ struct efx_mtd_partition { * (for Falcon architecture) * @finish_flush: Clean up after flushing the DMA queues (for Falcon * architecture) + * @prepare_flr: Prepare for an FLR + * @finish_flr: Clean up after an FLR * @describe_stats: Describe statistics for ethtool * @update_stats: Update statistics not provided by event handling. * Either argument may be %NULL. @@ -1100,6 +1102,8 @@ struct efx_nic_type { int (*fini_dmaq)(struct efx_nic *efx); void (*prepare_flush)(struct efx_nic *efx); void (*finish_flush)(struct efx_nic *efx); + void (*prepare_flr)(struct efx_nic *efx); + void (*finish_flr)(struct efx_nic *efx); size_t (*describe_stats)(struct efx_nic *efx, u8 *names); size_t (*update_stats)(struct efx_nic *efx, u64 *full_stats, struct rtnl_link_stats64 *core_stats); diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index a001fae1a8d7..d3ad8ed8d901 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -757,6 +757,7 @@ static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx) int efx_nic_flush_queues(struct efx_nic *efx); void siena_prepare_flush(struct efx_nic *efx); int efx_farch_fini_dmaq(struct efx_nic *efx); +void efx_farch_finish_flr(struct efx_nic *efx); void siena_finish_flush(struct efx_nic *efx); void falcon_start_nic_stats(struct efx_nic *efx); void falcon_stop_nic_stats(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 23f3a6f7737a..50ffefed492c 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -921,6 +921,8 @@ const struct efx_nic_type siena_a0_nic_type = { .fini_dmaq = efx_farch_fini_dmaq, .prepare_flush = siena_prepare_flush, .finish_flush = siena_finish_flush, + .prepare_flr = efx_port_dummy_op_void, + .finish_flr = efx_farch_finish_flr, .describe_stats = siena_describe_nic_stats, .update_stats = siena_update_nic_stats, .start_stats = efx_mcdi_mac_start_stats, -- GitLab From 5ed0a8e667090003fdf7b750296fcfb248349502 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 16 Apr 2014 11:35:54 -0700 Subject: [PATCH 338/797] staging: delete rtl8187se wireless driver There is a "real" driver for this hardware now in drivers/net/ so remove the staging version as it's not needed anymore. Reported-by: Xose Vazquez Perez Cc: Larry Finger Cc: John W. Linville" Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/rtl8187se/Kconfig | 10 - drivers/staging/rtl8187se/Makefile | 38 - drivers/staging/rtl8187se/Module.symvers | 0 drivers/staging/rtl8187se/TODO | 13 - drivers/staging/rtl8187se/ieee80211/dot11d.c | 189 - drivers/staging/rtl8187se/ieee80211/dot11d.h | 71 - .../staging/rtl8187se/ieee80211/ieee80211.h | 1496 ------- .../rtl8187se/ieee80211/ieee80211_crypt.c | 240 -- .../rtl8187se/ieee80211/ieee80211_crypt.h | 86 - .../ieee80211/ieee80211_crypt_ccmp.c | 455 -- .../ieee80211/ieee80211_crypt_tkip.c | 740 ---- .../rtl8187se/ieee80211/ieee80211_crypt_wep.c | 277 -- .../rtl8187se/ieee80211/ieee80211_module.c | 203 - .../rtl8187se/ieee80211/ieee80211_rx.c | 1486 ------- .../rtl8187se/ieee80211/ieee80211_softmac.c | 2711 ------------ .../ieee80211/ieee80211_softmac_wx.c | 567 --- .../rtl8187se/ieee80211/ieee80211_tx.c | 591 --- .../rtl8187se/ieee80211/ieee80211_wx.c | 713 ---- drivers/staging/rtl8187se/r8180.h | 640 --- drivers/staging/rtl8187se/r8180_93cx6.h | 54 - drivers/staging/rtl8187se/r8180_core.c | 3775 ----------------- drivers/staging/rtl8187se/r8180_dm.c | 1139 ----- drivers/staging/rtl8187se/r8180_dm.h | 23 - drivers/staging/rtl8187se/r8180_hw.h | 588 --- drivers/staging/rtl8187se/r8180_rtl8225.h | 34 - drivers/staging/rtl8187se/r8180_rtl8225z2.c | 811 ---- drivers/staging/rtl8187se/r8180_wx.c | 1409 ------ drivers/staging/rtl8187se/r8180_wx.h | 21 - drivers/staging/rtl8187se/r8185b_init.c | 1464 ------- 31 files changed, 19847 deletions(-) delete mode 100644 drivers/staging/rtl8187se/Kconfig delete mode 100644 drivers/staging/rtl8187se/Makefile delete mode 100644 drivers/staging/rtl8187se/Module.symvers delete mode 100644 drivers/staging/rtl8187se/TODO delete mode 100644 drivers/staging/rtl8187se/ieee80211/dot11d.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/dot11d.h delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211.h delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_module.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c delete mode 100644 drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c delete mode 100644 drivers/staging/rtl8187se/r8180.h delete mode 100644 drivers/staging/rtl8187se/r8180_93cx6.h delete mode 100644 drivers/staging/rtl8187se/r8180_core.c delete mode 100644 drivers/staging/rtl8187se/r8180_dm.c delete mode 100644 drivers/staging/rtl8187se/r8180_dm.h delete mode 100644 drivers/staging/rtl8187se/r8180_hw.h delete mode 100644 drivers/staging/rtl8187se/r8180_rtl8225.h delete mode 100644 drivers/staging/rtl8187se/r8180_rtl8225z2.c delete mode 100644 drivers/staging/rtl8187se/r8180_wx.c delete mode 100644 drivers/staging/rtl8187se/r8180_wx.h delete mode 100644 drivers/staging/rtl8187se/r8185b_init.c diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index ea5efb426f75..22365f140bec 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -40,8 +40,6 @@ source "drivers/staging/olpc_dcon/Kconfig" source "drivers/staging/panel/Kconfig" -source "drivers/staging/rtl8187se/Kconfig" - source "drivers/staging/rtl8192u/Kconfig" source "drivers/staging/rtl8192e/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 86e020c2ad0d..fbe84ed2d048 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_COMEDI) += comedi/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_PANEL) += panel/ -obj-$(CONFIG_R8187SE) += rtl8187se/ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig deleted file mode 100644 index ff8d41ebca36..000000000000 --- a/drivers/staging/rtl8187se/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config R8187SE - tristate "RealTek RTL8187SE Wireless LAN NIC driver" - depends on PCI && WLAN - depends on m - select WIRELESS_EXT - select WEXT_PRIV - select EEPROM_93CX6 - select CRYPTO - ---help--- - If built as a module, it will be called r8187se.ko. diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile deleted file mode 100644 index 91d1aa2830c9..000000000000 --- a/drivers/staging/rtl8187se/Makefile +++ /dev/null @@ -1,38 +0,0 @@ - -#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y -#ccflags-y += -std=gnu89 -#ccflags-y += -O2 -#CC = gcc - -ccflags-y := -DSW_ANTE -ccflags-y += -DTX_TRACK -ccflags-y += -DHIGH_POWER -ccflags-y += -DSW_DIG -ccflags-y += -DRATE_ADAPT - -#enable it for legacy power save, disable it for leisure power save -ccflags-y += -DENABLE_LPS - - -#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y - -r8187se-y := \ - r8180_core.o \ - r8180_wx.o \ - r8180_rtl8225z2.o \ - r8185b_init.o \ - r8180_dm.o \ - ieee80211/dot11d.o \ - ieee80211/ieee80211_softmac.o \ - ieee80211/ieee80211_rx.o \ - ieee80211/ieee80211_tx.o \ - ieee80211/ieee80211_wx.o \ - ieee80211/ieee80211_module.o \ - ieee80211/ieee80211_softmac_wx.o \ - ieee80211/ieee80211_crypt.o \ - ieee80211/ieee80211_crypt_tkip.o \ - ieee80211/ieee80211_crypt_ccmp.o \ - ieee80211/ieee80211_crypt_wep.o - -obj-$(CONFIG_R8187SE) += r8187se.o - diff --git a/drivers/staging/rtl8187se/Module.symvers b/drivers/staging/rtl8187se/Module.symvers deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO deleted file mode 100644 index 704949a9da0d..000000000000 --- a/drivers/staging/rtl8187se/TODO +++ /dev/null @@ -1,13 +0,0 @@ -TODO: -- prepare private ieee80211 stack for merge with rtl8192su's version: - - add hwsec_active flag to struct ieee80211_device - - add bHwSec flag to cb_desc structure -- switch to use shared "librtl" instead of private ieee80211 stack -- switch to use LIB80211 -- switch to use MAC80211 -- use kernel coding style -- checkpatch.pl fixes -- sparse fixes -- integrate with drivers/net/wireless/rtl818x - -Please send any patches to Greg Kroah-Hartman . diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c deleted file mode 100644 index 4483c2c0307c..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/dot11d.c +++ /dev/null @@ -1,189 +0,0 @@ -#include "dot11d.h" - -void Dot11d_Init(struct ieee80211_device *ieee) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); - - pDot11dInfo->bEnabled = 0; - - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - RESET_CIE_WATCHDOG(ieee); - - netdev_info(ieee->dev, "Dot11d_Init()\n"); -} - -/* Reset to the state as we are just entering a regulatory domain. */ -void Dot11d_Reset(struct ieee80211_device *ieee) -{ - u32 i; - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); - - /* Clear old channel map */ - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - /* Set new channel map */ - for (i = 1; i <= 11; i++) - (pDot11dInfo->channel_map)[i] = 1; - - for (i = 12; i <= 14; i++) - (pDot11dInfo->channel_map)[i] = 2; - - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; - RESET_CIE_WATCHDOG(ieee); -} - -/* - * Description: - * Update country IE from Beacon or Probe Response and configure PHY for - * operation in the regulatory domain. - * - * TODO: - * Configure Tx power. - * - * Assumption: - * 1. IS_DOT11D_ENABLE() is TRUE. - * 2. Input IE is an valid one. - */ -void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - u8 i, j, NumTriples, MaxChnlNum; - u8 index, MaxTxPowerInDbm; - PCHNL_TXPOWER_TRIPLE pTriple; - - if ((CoutryIeLen - 3)%3 != 0) { - netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); - Dot11d_Reset(dev); - return; - } - - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - MaxChnlNum = 0; - NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */ - pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3); - for (i = 0; i < NumTriples; i++) { - if (MaxChnlNum >= pTriple->FirstChnl) { - /* - * It is not in a monotonically increasing order, - * so stop processing. - */ - netdev_info(dev->dev, - "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); - Dot11d_Reset(dev); - return; - } - if (MAX_CHANNEL_NUMBER < - (pTriple->FirstChnl + pTriple->NumChnls)) { - /* - * It is not a valid set of channel id, - * so stop processing - */ - netdev_info(dev->dev, - "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); - Dot11d_Reset(dev); - return; - } - - for (j = 0; j < pTriple->NumChnls; j++) { - index = pTriple->FirstChnl + j; - pDot11dInfo->channel_map[index] = 1; - MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm; - pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm; - MaxChnlNum = pTriple->FirstChnl + j; - } - - pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3); - } -#if 1 - netdev_info(dev->dev, "Channel List:"); - for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) - if (pDot11dInfo->channel_map[i] > 0) - netdev_info(dev->dev, " %d", i); - netdev_info(dev->dev, "\n"); -#endif - - UPDATE_CIE_SRC(dev, pTaddr); - - pDot11dInfo->CountryIeLen = CoutryIeLen; - memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); - pDot11dInfo->State = DOT11D_STATE_LEARNED; -} - -u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - u8 MaxTxPwrInDbm = 255; - - if (MAX_CHANNEL_NUMBER < Channel) { - netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"); - return MaxTxPwrInDbm; - } - if (pDot11dInfo->channel_map[Channel]) - MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; - - return MaxTxPwrInDbm; -} - - -void DOT11D_ScanComplete(struct ieee80211_device *dev) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - - switch (pDot11dInfo->State) { - case DOT11D_STATE_LEARNED: - pDot11dInfo->State = DOT11D_STATE_DONE; - break; - - case DOT11D_STATE_DONE: - if (GET_CIE_WATCHDOG(dev) == 0) { - /* Reset country IE if previous one is gone. */ - Dot11d_Reset(dev); - } - break; - case DOT11D_STATE_NONE: - break; - } -} - -int IsLegalChannel(struct ieee80211_device *dev, u8 channel) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - - if (MAX_CHANNEL_NUMBER < channel) { - netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n"); - return 0; - } - if (pDot11dInfo->channel_map[channel] > 0) - return 1; - return 0; -} - -int ToLegalChannel(struct ieee80211_device *dev, u8 channel) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - u8 default_chn = 0; - u32 i = 0; - - for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) { - if (pDot11dInfo->channel_map[i] > 0) { - default_chn = i; - break; - } - } - - if (MAX_CHANNEL_NUMBER < channel) { - netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n"); - return default_chn; - } - - if (pDot11dInfo->channel_map[channel] > 0) - return channel; - - return default_chn; -} diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h deleted file mode 100644 index f996691307bf..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/dot11d.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __INC_DOT11D_H -#define __INC_DOT11D_H - -#include "ieee80211.h" - -/* #define ENABLE_DOT11D */ - -/* #define DOT11D_MAX_CHNL_NUM 83 */ - -typedef struct _CHNL_TXPOWER_TRIPLE { - u8 FirstChnl; - u8 NumChnls; - u8 MaxTxPowerInDbm; -} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; - -typedef enum _DOT11D_STATE { - DOT11D_STATE_NONE = 0, - DOT11D_STATE_LEARNED, - DOT11D_STATE_DONE, -} DOT11D_STATE; - -typedef struct _RT_DOT11D_INFO { - /* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */ - - bool bEnabled; /* dot11MultiDomainCapabilityEnabled */ - - u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */ - u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */ - u8 CountryIeWatchdog; - - u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */ - /* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */ - /* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */ - u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; - - DOT11D_STATE State; -} RT_DOT11D_INFO, *PRT_DOT11D_INFO; - -#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0) -#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5]) -#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) - -#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled -#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) - -#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) -#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) - -#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ - (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ - FALSE : \ - (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) - -#define CIE_WATCHDOG_TH 1 -#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog -#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 -#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) - -#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) - -void Dot11d_Init(struct ieee80211_device *dev); -void Dot11d_Reset(struct ieee80211_device *dev); -void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe); -u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel); -void DOT11D_ScanComplete(struct ieee80211_device *dev); -int IsLegalChannel(struct ieee80211_device *dev, u8 channel); -int ToLegalChannel(struct ieee80211_device *dev, u8 channel); - -#endif /* #ifndef __INC_DOT11D_H */ diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h deleted file mode 100644 index d1763b7b8f27..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ /dev/null @@ -1,1496 +0,0 @@ -/* - * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 - * remains copyright by the original authors - * - * Portions of the merged code are based on Host AP (software wireless - * LAN access point) driver for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * Copyright (c) 2004, Intel Corporation - * - * Modified for Realtek's wi-fi cards by Andrea Merello - * - * - * 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. See README and COPYING for - * more details. - */ -#ifndef IEEE80211_H -#define IEEE80211_H -#include /* ETH_ALEN */ -#include /* ARRAY_SIZE */ -#include -#include -#include -#include -#include -#include -#include - -#define KEY_TYPE_NA 0x0 -#define KEY_TYPE_WEP40 0x1 -#define KEY_TYPE_TKIP 0x2 -#define KEY_TYPE_CCMP 0x4 -#define KEY_TYPE_WEP104 0x5 - -#define aSifsTime 10 - -#define MGMT_QUEUE_NUM 5 - - -#define IEEE_CMD_SET_WPA_PARAM 1 -#define IEEE_CMD_SET_WPA_IE 2 -#define IEEE_CMD_SET_ENCRYPTION 3 -#define IEEE_CMD_MLME 4 - -#define IEEE_PARAM_WPA_ENABLED 1 -#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 -#define IEEE_PARAM_DROP_UNENCRYPTED 3 -#define IEEE_PARAM_PRIVACY_INVOKED 4 -#define IEEE_PARAM_AUTH_ALGS 5 -#define IEEE_PARAM_IEEE_802_1X 6 -//It should consistent with the driver_XXX.c -// David, 2006.9.26 -#define IEEE_PARAM_WPAX_SELECT 7 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_PROTO_WPA 1 -#define IEEE_PROTO_RSN 2 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_WPAX_USEGROUP 0 -#define IEEE_WPAX_WEP40 1 -#define IEEE_WPAX_TKIP 2 -#define IEEE_WPAX_WRAP 3 -#define IEEE_WPAX_CCMP 4 -#define IEEE_WPAX_WEP104 5 - -#define IEEE_KEY_MGMT_IEEE8021X 1 -#define IEEE_KEY_MGMT_PSK 2 - - - -#define IEEE_MLME_STA_DEAUTH 1 -#define IEEE_MLME_STA_DISASSOC 2 - - -#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 -#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 -#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 - - -#define IEEE_CRYPT_ALG_NAME_LEN 16 - -extern int ieee80211_crypto_tkip_init(void); -extern void ieee80211_crypto_tkip_exit(void); - -//by amy for ps -typedef struct ieee_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[0]; - } wpa_ie; - struct{ - int command; - int reason_code; - } mlme; - struct { - u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[0]; - } crypt; - - } u; -}ieee_param; - - -#define MSECS(t) msecs_to_jiffies(t) -#define msleep_interruptible_rtl msleep_interruptible - -#define IEEE80211_DATA_LEN 2304 -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ - -#define IEEE80211_3ADDR_LEN 24 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_FCS_LEN 4 -#define IEEE80211_HLEN IEEE80211_4ADDR_LEN -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - -/* Frame control field constants */ -#define IEEE80211_FCTL_DSTODS 0x0300 //added by david -#define IEEE80211_FCTL_WEP 0x4000 - -/* debug macros */ - -#ifdef CONFIG_IEEE80211_DEBUG -extern u32 ieee80211_debug_level; -#define IEEE80211_DEBUG(level, fmt, args...) \ -do { if (ieee80211_debug_level & (level)) \ - printk(KERN_DEBUG "ieee80211: %c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0) -#else -#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) -#endif /* CONFIG_IEEE80211_DEBUG */ - -/* - * To use the debug system; - * - * If you are defining a new debug classification, simply add it to the #define - * list here in the form of: - * - * #define IEEE80211_DL_xxxx VALUE - * - * shifting value to the left one bit from the previous entry. xxxx should be - * the name of the classification (for example, WEP) - * - * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your - * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want - * to send output to that classification. - * - * To add your debug level to the list of levels seen when you perform - * - * % cat /proc/net/ipw/debug_level - * - * you simply need to add your entry to the ipw_debug_levels array. - * - * If you do not see debug_level in /proc/net/ipw then you do not have - * CONFIG_IEEE80211_DEBUG defined in your kernel configuration - * - */ - -#define IEEE80211_DL_INFO (1<<0) -#define IEEE80211_DL_WX (1<<1) -#define IEEE80211_DL_SCAN (1<<2) -#define IEEE80211_DL_STATE (1<<3) -#define IEEE80211_DL_MGMT (1<<4) -#define IEEE80211_DL_FRAG (1<<5) -#define IEEE80211_DL_EAP (1<<6) -#define IEEE80211_DL_DROP (1<<7) - -#define IEEE80211_DL_TX (1<<8) -#define IEEE80211_DL_RX (1<<9) - -#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) -#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) -#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) - -#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) -#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) -//#define IEEE_DEBUG_SCAN IEEE80211_WARNING -#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) -#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) -#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) -#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) -#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) -#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) -#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) -#include -#include /* ARPHRD_ETHER */ - -#ifndef WIRELESS_SPY -#define WIRELESS_SPY // enable iwspy support -#endif -#include // new driver API - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ - -#ifndef ETH_P_80211_RAW -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) -#endif - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct ieee80211_snap_hdr { - - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ - -} __attribute__ ((packed)); - -#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) - -#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) - -#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) -#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ) - -#define WLAN_CAPABILITY_BSS (1<<0) -#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) - -#define IEEE80211_STATMASK_SIGNAL (1<<0) -#define IEEE80211_STATMASK_RSSI (1<<1) -#define IEEE80211_STATMASK_NOISE (1<<2) -#define IEEE80211_STATMASK_RATE (1<<3) -#define IEEE80211_STATMASK_WEMASK 0x7 - - -#define IEEE80211_CCK_MODULATION (1<<0) -#define IEEE80211_OFDM_MODULATION (1<<1) - -#define IEEE80211_24GHZ_BAND (1<<0) -#define IEEE80211_52GHZ_BAND (1<<1) - -#define IEEE80211_CCK_RATE_LEN 4 -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_LEN 8 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) -#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) -#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) -#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) -#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) -#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) -#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) -#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) -#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) -#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) -#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) -#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) - -#define IEEE80211_CCK_RATES_MASK 0x0000000F -#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ - IEEE80211_CCK_RATE_2MB_MASK) -#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ - IEEE80211_CCK_RATE_5MB_MASK | \ - IEEE80211_CCK_RATE_11MB_MASK) - -#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 -#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ - IEEE80211_OFDM_RATE_12MB_MASK | \ - IEEE80211_OFDM_RATE_24MB_MASK) -#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ - IEEE80211_OFDM_RATE_9MB_MASK | \ - IEEE80211_OFDM_RATE_18MB_MASK | \ - IEEE80211_OFDM_RATE_36MB_MASK | \ - IEEE80211_OFDM_RATE_48MB_MASK | \ - IEEE80211_OFDM_RATE_54MB_MASK) -#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ - IEEE80211_CCK_DEFAULT_RATES_MASK) - -#define IEEE80211_NUM_OFDM_RATES 8 -#define IEEE80211_NUM_CCK_RATES 4 -#define IEEE80211_OFDM_SHIFT_MASK_A 4 - -/* this is stolen and modified from the madwifi driver*/ -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_DATA 0x08 -#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 -#define IEEE80211_FC0_SUBTYPE_QOS 0x80 - -#define IEEE80211_QOS_HAS_SEQ(fc) \ - (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ - (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) - -/* this is stolen from ipw2200 driver */ -#define IEEE_IBSS_MAC_HASH_SIZE 31 -struct ieee_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num[17]; - u16 frag_num[17]; - unsigned long packet_time[17]; - struct list_head list; -}; - -/* NOTE: This data is for statistical purposes; not all hardware provides this - * information for frames received. Not setting these will not cause - * any adverse affects. */ -struct ieee80211_rx_stats { - u32 mac_time[2]; - u8 signalstrength; - s8 rssi; - u8 signal; - u8 noise; - u16 rate; /* in 100 kbps */ - u8 received_channel; - u8 control; - u8 mask; - u8 freq; - u16 len; - u8 nic_type; -}; - -/* IEEE 802.11 requires that STA supports concurrent reception of at least - * three fragmented frames. This define can be increased to support more - * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ -#define IEEE80211_FRAG_CACHE_LEN 4 - -struct ieee80211_frag_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int last_frag; - struct sk_buff *skb; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; -}; - -struct ieee80211_stats { - unsigned int tx_unicast_frames; - unsigned int tx_multicast_frames; - unsigned int tx_fragments; - unsigned int tx_unicast_octets; - unsigned int tx_multicast_octets; - unsigned int tx_deferred_transmissions; - unsigned int tx_single_retry_frames; - unsigned int tx_multiple_retry_frames; - unsigned int tx_retry_limit_exceeded; - unsigned int tx_discards; - unsigned int rx_unicast_frames; - unsigned int rx_multicast_frames; - unsigned int rx_fragments; - unsigned int rx_unicast_octets; - unsigned int rx_multicast_octets; - unsigned int rx_fcs_errors; - unsigned int rx_discards_no_buffer; - unsigned int tx_discards_wrong_sa; - unsigned int rx_discards_undecryptable; - unsigned int rx_message_in_msg_fragments; - unsigned int rx_message_in_bad_msg_fragments; -}; - -struct ieee80211_device; - -#include "ieee80211_crypt.h" - -#define SEC_KEY_1 (1<<0) -#define SEC_KEY_2 (1<<1) -#define SEC_KEY_3 (1<<2) -#define SEC_KEY_4 (1<<3) -#define SEC_ACTIVE_KEY (1<<4) -#define SEC_AUTH_MODE (1<<5) -#define SEC_UNICAST_GROUP (1<<6) -#define SEC_LEVEL (1<<7) -#define SEC_ENABLED (1<<8) - -#define SEC_LEVEL_0 0 /* None */ -#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ -#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ -#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ -#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ - -#define WEP_KEYS 4 -#define WEP_KEY_LEN 13 - -#define WEP_KEY_LEN_MODIF 32 - -struct ieee80211_security { - u16 active_key:2, - enabled:1, - auth_mode:2, - auth_algo:4, - unicast_uses_group:1; - u8 key_sizes[WEP_KEYS]; - u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF]; - u8 level; - u16 flags; -} __attribute__ ((packed)); - - -/* - - 802.11 data frame from AP - - ,-------------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `-------------------------------------------------------------------' - -Total: 28-2340 bytes - -*/ - -/* Management Frame Information Element Types */ -enum { - MFIE_TYPE_SSID = 0, - MFIE_TYPE_RATES = 1, - MFIE_TYPE_FH_SET = 2, - MFIE_TYPE_DS_SET = 3, - MFIE_TYPE_CF_SET = 4, - MFIE_TYPE_TIM = 5, - MFIE_TYPE_IBSS_SET = 6, - MFIE_TYPE_COUNTRY = 7, - MFIE_TYPE_CHALLENGE = 16, - MFIE_TYPE_ERP = 42, - MFIE_TYPE_RSN = 48, - MFIE_TYPE_RATES_EX = 50, - MFIE_TYPE_GENERIC = 221, -}; - -struct ieee80211_header_data { - __le16 frame_ctl; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; -}; - -struct ieee80211_hdr_4addr { - __le16 frame_ctl; - u16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - u16 seq_ctl; - u8 addr4[ETH_ALEN]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addrqos { - u16 frame_ctl; - u16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - u16 seq_ctl; - u16 qos_ctl; -} __attribute__ ((packed)); - -struct ieee80211_hdr_4addrqos { - u16 frame_ctl; - u16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - u16 seq_ctl; - u8 addr4[ETH_ALEN]; - u16 qos_ctl; -} __attribute__ ((packed)); - -struct ieee80211_info_element_hdr { - u8 id; - u8 len; -} __attribute__ ((packed)); - -struct ieee80211_info_element { - u8 id; - u8 len; - u8 data[0]; -} __attribute__ ((packed)); - -struct ieee80211_authentication { - struct ieee80211_header_data header; - u16 algorithm; - u16 transaction; - u16 status; - //struct ieee80211_info_element_hdr info_element; -} __attribute__ ((packed)); - -struct ieee80211_disassoc_frame { - struct ieee80211_hdr_3addr header; - u16 reasoncode; -} __attribute__ ((packed)); - -struct ieee80211_probe_request { - struct ieee80211_header_data header; - /* struct ieee80211_info_element info_element; */ -} __attribute__ ((packed)); - -struct ieee80211_probe_response { - struct ieee80211_header_data header; - u32 time_stamp[2]; - u16 beacon_interval; - u16 capability; - struct ieee80211_info_element info_element; -} __attribute__ ((packed)); - -struct ieee80211_assoc_request_frame { - struct ieee80211_hdr_3addr header; - u16 capability; - u16 listen_interval; - //u8 current_ap[ETH_ALEN]; - struct ieee80211_info_element_hdr info_element; -} __attribute__ ((packed)); - -struct ieee80211_assoc_response_frame { - struct ieee80211_hdr_3addr header; - u16 capability; - u16 status; - u16 aid; - struct ieee80211_info_element info_element; /* supported rates */ -} __attribute__ ((packed)); - -struct ieee80211_txb { - u8 nr_frags; - u8 encrypted; - u16 reserved; - u16 frag_size; - u16 payload_size; - struct sk_buff *fragments[0]; -}; - -/* SWEEP TABLE ENTRIES NUMBER */ -#define MAX_SWEEP_TAB_ENTRIES 42 -#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 - -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_RATES_EX_LENGTH ((u8)16) - -#define MAX_NETWORK_COUNT 128 - -#define MAX_CHANNEL_NUMBER 165 - -#define IEEE80211_SOFTMAC_SCAN_TIME 100 /* (HZ / 2) */ -#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) - -#define CRC_LENGTH 4U - -#define MAX_WPA_IE_LEN 64 - -#define NETWORK_EMPTY_ESSID (1 << 0) -#define NETWORK_HAS_OFDM (1 << 1) -#define NETWORK_HAS_CCK (1 << 2) - -struct ieee80211_wmm_ac_param { - u8 ac_aci_acm_aifsn; - u8 ac_ecwmin_ecwmax; - u16 ac_txop_limit; -}; - -struct ieee80211_wmm_ts_info { - u8 ac_dir_tid; - u8 ac_up_psb; - u8 reserved; -} __attribute__ ((packed)); - -struct ieee80211_wmm_tspec_elem { - struct ieee80211_wmm_ts_info ts_info; - u16 norm_msdu_size; - u16 max_msdu_size; - u32 min_serv_inter; - u32 max_serv_inter; - u32 inact_inter; - u32 suspen_inter; - u32 serv_start_time; - u32 min_data_rate; - u32 mean_data_rate; - u32 peak_data_rate; - u32 max_burst_size; - u32 delay_bound; - u32 min_phy_rate; - u16 surp_band_allow; - u16 medium_time; -}__attribute__((packed)); - -enum eap_type { - EAP_PACKET = 0, - EAPOL_START, - EAPOL_LOGOFF, - EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT -}; - -static const char *eap_types[] = { - [EAP_PACKET] = "EAP-Packet", - [EAPOL_START] = "EAPOL-Start", - [EAPOL_LOGOFF] = "EAPOL-Logoff", - [EAPOL_KEY] = "EAPOL-Key", - [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" -}; - -static inline const char *eap_get_type(int type) -{ - return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; -} - -struct eapol { - u8 snap[6]; - u16 ethertype; - u8 version; - u8 type; - u16 length; -} __attribute__ ((packed)); - -struct ieee80211_softmac_stats { - unsigned int rx_ass_ok; - unsigned int rx_ass_err; - unsigned int rx_probe_rq; - unsigned int tx_probe_rs; - unsigned int tx_beacons; - unsigned int rx_auth_rq; - unsigned int rx_auth_rs_ok; - unsigned int rx_auth_rs_err; - unsigned int tx_auth_rq; - unsigned int no_auth_rs; - unsigned int no_ass_rs; - unsigned int tx_ass_rq; - unsigned int rx_ass_rq; - unsigned int tx_probe_rq; - unsigned int reassoc; - unsigned int swtxstop; - unsigned int swtxawake; -}; - -#define BEACON_PROBE_SSID_ID_POSITION 12 - -/* - * These are the data types that can make up management packets - * - u16 auth_algorithm; - u16 auth_sequence; - u16 beacon_interval; - u16 capability; - u8 current_ap[ETH_ALEN]; - u16 listen_interval; - struct { - u16 association_id:14, reserved:2; - } __attribute__ ((packed)); - u32 time_stamp[2]; - u16 reason; - u16 status; -*/ - -#define IEEE80211_DEFAULT_TX_ESSID "Penguin" -#define IEEE80211_DEFAULT_BASIC_RATE 10 - -enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; -#define MAX_SP_Len (WMM_all_frame << 4) -#define IEEE80211_QOS_TID 0x0f -#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) - -#define MAX_IE_LEN 0xFF //+YJ,080625 - -struct rtl8187se_channel_list { - u8 channel[MAX_CHANNEL_NUMBER + 1]; - u8 len; -}; - -//by amy for ps -#define IEEE80211_WATCH_DOG_TIME 2000 -//by amy for ps -//by amy for antenna -#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m -//by amy for antenna - -#define IEEE80211_DTIM_MBCAST 4 -#define IEEE80211_DTIM_UCAST 2 -#define IEEE80211_DTIM_VALID 1 -#define IEEE80211_DTIM_INVALID 0 - -#define IEEE80211_PS_DISABLED 0 -#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST -#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST -#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID -//added by David for QoS 2006/6/30 -//#define WMM_Hang_8187 -#ifdef WMM_Hang_8187 -#undef WMM_Hang_8187 -#endif - -#define WME_AC_BE 0x00 -#define WME_AC_BK 0x01 -#define WME_AC_VI 0x02 -#define WME_AC_VO 0x03 -#define WME_ACI_MASK 0x03 -#define WME_AIFSN_MASK 0x03 -#define WME_AC_PRAM_LEN 16 - -//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1)) -#define UP2AC(up) ( \ - ((up) < 1) ? WME_AC_BE : \ - ((up) < 3) ? WME_AC_BK : \ - ((up) < 4) ? WME_AC_BE : \ - ((up) < 6) ? WME_AC_VI : \ - WME_AC_VO) -//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue -#define AC2UP(_ac) ( \ - ((_ac) == WME_AC_VO) ? 6 : \ - ((_ac) == WME_AC_VI) ? 5 : \ - ((_ac) == WME_AC_BK) ? 1 : \ - 0) - -#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ -struct ether_header { - u8 ether_dhost[ETHER_ADDR_LEN]; - u8 ether_shost[ETHER_ADDR_LEN]; - u16 ether_type; -} __attribute__((packed)); - -#ifndef ETHERTYPE_PAE -#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ -#endif -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x0800 /* IP protocol */ -#endif - -struct ieee80211_network { - /* These entries are used to identify a unique network */ - u8 bssid[ETH_ALEN]; - u8 channel; - /* Ensure null-terminated for any debug msgs */ - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; - - /* These are network statistics */ - struct ieee80211_rx_stats stats; - u16 capability; - u8 rates[MAX_RATES_LENGTH]; - u8 rates_len; - u8 rates_ex[MAX_RATES_EX_LENGTH]; - u8 rates_ex_len; - unsigned long last_scanned; - u8 mode; - u8 flags; - u32 last_associate; - u32 time_stamp[2]; - u16 beacon_interval; - u16 listen_interval; - u16 atim_window; - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - u8 dtim_period; - u8 dtim_data; - u32 last_dtim_sta_time[2]; - struct list_head list; - //appeded for QoS - u8 wmm_info; - struct ieee80211_wmm_ac_param wmm_param[4]; - u8 QoS_Enable; - u8 SignalStrength; -//by amy 080312 - u8 HighestOperaRate; -//by amy 080312 - u8 Turbo_Enable;//enable turbo mode, added by thomas - u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; -}; - -enum ieee80211_state { - - /* the card is not linked at all */ - IEEE80211_NOLINK = 0, - - /* IEEE80211_ASSOCIATING* are for BSS client mode - * the driver shall not perform RX filtering unless - * the state is LINKED. - * The driver shall just check for the state LINKED and - * defaults to NOLINK for ALL the other states (including - * LINKED_SCANNING) - */ - - /* the association procedure will start (wq scheduling)*/ - IEEE80211_ASSOCIATING, - IEEE80211_ASSOCIATING_RETRY, - - /* the association procedure is sending AUTH request*/ - IEEE80211_ASSOCIATING_AUTHENTICATING, - - /* the association procedure has successfully authenticated - * and is sending association request - */ - IEEE80211_ASSOCIATING_AUTHENTICATED, - - /* the link is ok. the card associated to a BSS or linked - * to a ibss cell or acting as an AP and creating the bss - */ - IEEE80211_LINKED, - - /* same as LINKED, but the driver shall apply RX filter - * rules as we are in NO_LINK mode. As the card is still - * logically linked, but it is doing a syncro site survey - * then it will be back to LINKED state. - */ - IEEE80211_LINKED_SCANNING, - -}; - -#define DEFAULT_MAX_SCAN_AGE (15 * HZ) -#define DEFAULT_FTS 2346 - -#define CFG_IEEE80211_RESERVE_FCS (1<<0) -#define CFG_IEEE80211_COMPUTE_FCS (1<<1) - -typedef struct tx_pending_t{ - int frag; - struct ieee80211_txb *txb; -}tx_pending_t; - -enum { - COUNTRY_CODE_FCC = 0, - COUNTRY_CODE_IC = 1, - COUNTRY_CODE_ETSI = 2, - COUNTRY_CODE_SPAIN = 3, - COUNTRY_CODE_FRANCE = 4, - COUNTRY_CODE_MKK = 5, - COUNTRY_CODE_MKK1 = 6, - COUNTRY_CODE_ISRAEL = 7, - COUNTRY_CODE_TELEC = 8, - COUNTRY_CODE_GLOBAL_DOMAIN = 9, - COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10 -}; - -struct ieee80211_device { - struct net_device *dev; - - /* Bookkeeping structures */ - struct net_device_stats stats; - struct ieee80211_stats ieee_stats; - struct ieee80211_softmac_stats softmac_stats; - - /* Probe / Beacon management */ - struct list_head network_free_list; - struct list_head network_list; - struct ieee80211_network *networks; - int scans; - int scan_age; - - int iw_mode; /* operating mode (IW_MODE_*) */ - - spinlock_t lock; - spinlock_t wpax_suitlist_lock; - - int tx_headroom; /* Set to size of any additional room needed at front - * of allocated Tx SKBs */ - u32 config; - - /* WEP and other encryption related settings at the device level */ - int open_wep; /* Set to 1 to allow unencrypted frames */ - - int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes */ - - /* If the host performs {en,de}cryption, then set to 1 */ - int host_encrypt; - int host_decrypt; - int ieee802_1x; /* is IEEE 802.1X used */ - - /* WPA data */ - int wpa_enabled; - int drop_unencrypted; - int tkip_countermeasures; - int privacy_invoked; - size_t wpa_ie_len; - u8 *wpa_ie; - - u8 ap_mac_addr[6]; - u16 pairwise_key_type; - u16 broadcast_key_type; - - struct list_head crypt_deinit_list; - struct ieee80211_crypt_data *crypt[WEP_KEYS]; - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ - struct timer_list crypt_deinit_timer; - - int bcrx_sta_key; /* use individual keys to override default keys even - * with RX of broad/multicast frames */ - - /* Fragmentation structures */ - /* each stream contains an entry */ - struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; - unsigned int frag_next_idx[17]; - u16 fts; /* Fragmentation Threshold */ - - /* This stores infos for the current network. - * Either the network we are associated in INFRASTRUCTURE - * or the network that we are creating in MASTER mode. - * ad-hoc is a mixture ;-). - * Note that in infrastructure mode, even when not associated, - * fields bssid and essid may be valid (if wpa_set and essid_set - * are true) as thy carry the value set by the user via iwconfig - */ - struct ieee80211_network current_network; - - - enum ieee80211_state state; - - int short_slot; - int mode; /* A, B, G */ - int modulation; /* CCK, OFDM */ - int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ - int abg_true; /* ABG flag */ - - /* used for forcing the ibss workqueue to terminate - * without wait for the syncro scan to terminate - */ - short sync_scan_hurryup; - - void * pDot11dInfo; - bool bGlobalDomain; - - // For Liteon Ch12~13 passive scan - u8 MinPassiveChnlNum; - u8 IbssStartChnl; - - int rate; /* current rate */ - int basic_rate; - //FIXME: please callback, see if redundant with softmac_features - short active_scan; - - /* this contains flags for selectively enable softmac support */ - u16 softmac_features; - - /* if the sequence control field is not filled by HW */ - u16 seq_ctrl[5]; - - /* association procedure transaction sequence number */ - u16 associate_seq; - - /* AID for RTXed association responses */ - u16 assoc_id; - - /* power save mode related*/ - short ps; - short sta_sleep; - int ps_timeout; - struct tasklet_struct ps_task; - u32 ps_th; - u32 ps_tl; - - short raw_tx; - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - short queue_stop; - short scanning; - short proto_started; - - struct semaphore wx_sem; - struct semaphore scan_sem; - - spinlock_t mgmt_tx_lock; - spinlock_t beacon_lock; - - short beacon_txing; - - short wap_set; - short ssid_set; - - u8 wpax_type_set; //{added by David, 2006.9.28} - u32 wpax_type_notify; //{added by David, 2006.9.26} - - /* QoS related flag */ - char init_wmmparam_flag; - - /* for discarding duplicated packets in IBSS */ - struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; - - /* for discarding duplicated packets in BSS */ - u16 last_rxseq_num[17]; /* rx seq previous per-tid */ - u16 last_rxfrag_num[17];/* tx frag previous per-tid */ - unsigned long last_packet_time[17]; - - /* for PS mode */ - unsigned long last_rx_ps_time; - - /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ - struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; - int mgmt_queue_head; - int mgmt_queue_tail; - - - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - struct tx_pending_t tx_pending; - - /* used if IEEE_SOFTMAC_ASSOCIATE is set */ - struct timer_list associate_timer; - - /* used if IEEE_SOFTMAC_BEACONS is set */ - struct timer_list beacon_timer; - - struct work_struct associate_complete_wq; -// struct work_struct associate_retry_wq; - struct work_struct associate_procedure_wq; -// struct work_struct softmac_scan_wq; - struct work_struct wx_sync_scan_wq; - struct work_struct wmm_param_update_wq; - struct work_struct ps_request_tx_ack_wq;//for ps -// struct work_struct hw_wakeup_wq; -// struct work_struct hw_sleep_wq; -// struct work_struct watch_dog_wq; - bool bInactivePs; - bool actscanning; - bool beinretry; - u16 ListenInterval; - unsigned long NumRxDataInPeriod; //YJ,add,080828 - unsigned long NumRxBcnInPeriod; //YJ,add,080828 - unsigned long NumRxOkTotal; - unsigned long NumRxUnicast;//YJ,add,080828,for keep alive - bool bHwRadioOff; - struct delayed_work softmac_scan_wq; - struct delayed_work associate_retry_wq; - struct delayed_work hw_wakeup_wq; - struct delayed_work hw_sleep_wq;//+by amy 080324 - struct delayed_work watch_dog_wq; - struct delayed_work sw_antenna_wq; - struct delayed_work start_ibss_wq; -//by amy for rate adaptive 080312 - struct delayed_work rate_adapter_wq; -//by amy for rate adaptive - struct delayed_work hw_dig_wq; - struct delayed_work tx_pw_wq; - -//Added for RF power on power off by lizhaoming 080512 - struct delayed_work GPIOChangeRFWorkItem; - - struct workqueue_struct *wq; - - /* Callback functions */ - void (*set_security)(struct net_device *dev, - struct ieee80211_security *sec); - - /* Used to TX data frame by using txb structs. - * this is not used if in the softmac_features - * is set the flag IEEE_SOFTMAC_TX_QUEUE - */ - int (*hard_start_xmit)(struct ieee80211_txb *txb, - struct net_device *dev); - - int (*reset_port)(struct net_device *dev); - - /* Softmac-generated frames (management) are TXed via this - * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is - * not set. As some cards may have different HW queues that - * one might want to use for data and management frames - * the option to have two callbacks might be useful. - * This function can't sleep. - */ - int (*softmac_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev); - - /* used instead of hard_start_xmit (not softmac_hard_start_xmit) - * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set - * then also management frames are sent via this callback. - * This function can't sleep. - */ - void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct net_device *dev,int rate); - - /* stops the HW queue for DATA frames. Useful to avoid - * waste time to TX data frame when we are reassociating - * This function can sleep. - */ - void (*data_hard_stop)(struct net_device *dev); - - /* OK this is complementar to data_poll_hard_stop */ - void (*data_hard_resume)(struct net_device *dev); - - /* ask to the driver to retune the radio . - * This function can sleep. the driver should ensure - * the radio has been switched before return. - */ - void (*set_chan)(struct net_device *dev,short ch); - - /* These are not used if the ieee stack takes care of - * scanning (IEEE_SOFTMAC_SCAN feature set). - * In this case only the set_chan is used. - * - * The syncro version is similar to the start_scan but - * does not return until all channels has been scanned. - * this is called in user context and should sleep, - * it is called in a work_queue when switching to ad-hoc mode - * or in behalf of iwlist scan when the card is associated - * and root user ask for a scan. - * the function stop_scan should stop both the syncro and - * background scanning and can sleep. - * The function start_scan should initiate the background - * scanning and can't sleep. - */ - void (*scan_syncro)(struct net_device *dev); - void (*start_scan)(struct net_device *dev); - void (*stop_scan)(struct net_device *dev); - - /* indicate the driver that the link state is changed - * for example it may indicate the card is associated now. - * Driver might be interested in this to apply RX filter - * rules or simply light the LINK led - */ - void (*link_change)(struct net_device *dev); - - /* these two function indicates to the HW when to start - * and stop to send beacons. This is used when the - * IEEE_SOFTMAC_BEACONS is not set. For now the - * stop_send_bacons is NOT guaranteed to be called only - * after start_send_beacons. - */ - void (*start_send_beacons) (struct net_device *dev); - void (*stop_send_beacons) (struct net_device *dev); - - /* power save mode related */ - void (*sta_wake_up) (struct net_device *dev); - void (*ps_request_tx_ack) (struct net_device *dev); - void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl); - short (*ps_is_queue_empty) (struct net_device *dev); - - /* QoS related */ - //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param); - //void (*wmm_param_update) (struct ieee80211_device *ieee); - - /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_ieee80211 */ - u8 priv[0]; -}; - -#define IEEE_A (1<<0) -#define IEEE_B (1<<1) -#define IEEE_G (1<<2) -#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) - -/* Generate a 802.11 header */ - -/* Uses the channel change callback directly - * instead of [start/stop] scan callbacks - */ -#define IEEE_SOFTMAC_SCAN (1<<2) - -/* Perform authentication and association handshake */ -#define IEEE_SOFTMAC_ASSOCIATE (1<<3) - -/* Generate probe requests */ -#define IEEE_SOFTMAC_PROBERQ (1<<4) - -/* Generate response to probe requests */ -#define IEEE_SOFTMAC_PROBERS (1<<5) - -/* The ieee802.11 stack will manages the netif queue - * wake/stop for the driver, taking care of 802.11 - * fragmentation. See softmac.c for details. */ -#define IEEE_SOFTMAC_TX_QUEUE (1<<7) - -/* Uses only the softmac_data_hard_start_xmit - * even for TX management frames. - */ -#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) - -/* Generate beacons. The stack will enqueue beacons - * to the card - */ -#define IEEE_SOFTMAC_BEACONS (1<<6) - - - -static inline void *ieee80211_priv(struct net_device *dev) -{ - return ((struct ieee80211_device *)netdev_priv(dev))->priv; -} - -static inline int ieee80211_is_empty_essid(const char *essid, int essid_len) -{ - /* Single white space is for Linksys APs */ - if (essid_len == 1 && essid[0] == ' ') - return 1; - - /* Otherwise, if the entire essid is 0, we assume it is hidden */ - while (essid_len) { - essid_len--; - if (essid[essid_len] != '\0') - return 0; - } - - return 1; -} - -static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, - int mode) -{ - /* - * It is possible for both access points and our device to support - * combinations of modes, so as long as there is one valid combination - * of ap/device supported modes, then return success - * - */ - if ((mode & IEEE_A) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_52GHZ_BAND)) - return 1; - - if ((mode & IEEE_G) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - if ((mode & IEEE_B) && - (ieee->modulation & IEEE80211_CCK_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - return 0; -} - -static inline int ieee80211_get_hdrlen(u16 fc) -{ - int hdrlen = 24; - - switch (WLAN_FC_GET_TYPE(fc)) { - case IEEE80211_FTYPE_DATA: - if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = 30; /* Addr4 */ - if(IEEE80211_QOS_HAS_SEQ(fc)) - hdrlen += 2; /* QOS ctrl*/ - break; - case IEEE80211_FTYPE_CTL: - switch (WLAN_FC_GET_STYPE(fc)) { - case IEEE80211_STYPE_CTS: - case IEEE80211_STYPE_ACK: - hdrlen = 10; - break; - default: - hdrlen = 16; - break; - } - break; - } - - return hdrlen; -} - - - -/* ieee80211.c */ -extern void free_ieee80211(struct net_device *dev); -extern struct net_device *alloc_ieee80211(int sizeof_priv); - -extern int ieee80211_set_encryption(struct ieee80211_device *ieee); - -/* ieee80211_tx.c */ - -extern int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, - struct sk_buff *frag, int hdr_len); - -extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev); -extern void ieee80211_txb_free(struct ieee80211_txb *); - - -/* ieee80211_rx.c */ -extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats); -extern void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats); - -/* ieee80211_wx.c */ -extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra); -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); -/* ieee80211_softmac.c */ -extern short ieee80211_is_54g(const struct ieee80211_network *net); -extern short ieee80211_is_shortslot(const struct ieee80211_network *net); -extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, - u16 type, u16 stype); -extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, - struct ieee80211_network *net); - -extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, - struct ieee80211_device *ieee); -extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); -extern void ieee80211_start_bss(struct ieee80211_device *ieee); -extern void ieee80211_start_master_bss(struct ieee80211_device *ieee); -extern void ieee80211_start_ibss(struct ieee80211_device *ieee); -extern void ieee80211_softmac_init(struct ieee80211_device *ieee); -extern void ieee80211_softmac_free(struct ieee80211_device *ieee); -extern void ieee80211_associate_abort(struct ieee80211_device *ieee); -extern void ieee80211_disassociate(struct ieee80211_device *ieee); -extern void ieee80211_stop_scan(struct ieee80211_device *ieee); -extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); -extern void ieee80211_check_all_nets(struct ieee80211_device *ieee); -extern void ieee80211_start_protocol(struct ieee80211_device *ieee); -extern void ieee80211_stop_protocol(struct ieee80211_device *ieee); -extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); -extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee); -extern void ieee80211_reset_queue(struct ieee80211_device *ieee); -extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); -extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); -extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); -extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee); -extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, - struct iw_point *p); -extern void notify_wx_assoc_event(struct ieee80211_device *ieee); -extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); -extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, - u8 asRsn); -extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee); - -//Add for RF power on power off by lizhaoming 080512 -extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, - u8 asRsn); - -/* ieee80211_crypt_ccmp&tkip&wep.c */ -extern void ieee80211_tkip_null(void); -extern void ieee80211_wep_null(void); -extern void ieee80211_ccmp_null(void); -/* ieee80211_softmac_wx.c */ - -extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *ext); - -extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra); - -extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); - -extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee); - -extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, - short pwr); - -extern const long ieee80211_wlan_frequencies[]; - -extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) -{ - ieee->scans++; -} - -extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) -{ - return ieee->scans; -} - -static inline const char *escape_essid(const char *essid, u8 essid_len) { - static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - const char *s = essid; - char *d = escaped; - - if (ieee80211_is_empty_essid(essid, essid_len)) { - memcpy(escaped, "", sizeof("")); - return escaped; - } - - essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); - while (essid_len--) { - if (*s == '\0') { - *d++ = '\\'; - *d++ = '0'; - s++; - } else { - *d++ = *s++; - } - } - *d = '\0'; - return escaped; -} -#endif /* IEEE80211_H */ diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c deleted file mode 100644 index 101f0c0cdb0a..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * Host AP crypto routines - * - * Copyright (c) 2002-2003, Jouni Malinen - * Portions Copyright (C) 2004, 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. See README and COPYING for - * more details. - * - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -//#include -#include -#include -#include -#include - -#include "ieee80211.h" - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("HostAP crypto"); -MODULE_LICENSE("GPL"); - -struct ieee80211_crypto_alg { - struct list_head list; - struct ieee80211_crypto_ops *ops; -}; - - -struct ieee80211_crypto { - struct list_head algs; - spinlock_t lock; -}; - -static struct ieee80211_crypto *hcrypt; - -void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force) -{ - struct list_head *ptr, *n; - struct ieee80211_crypt_data *entry; - - for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; - ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct ieee80211_crypt_data, list); - - if (atomic_read(&entry->refcnt) != 0 && !force) - continue; - - list_del(ptr); - - if (entry->ops) - entry->ops->deinit(entry->priv); - kfree(entry); - } -} - -void ieee80211_crypt_deinit_handler(unsigned long data) -{ - struct ieee80211_device *ieee = (struct ieee80211_device *)data; - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - ieee80211_crypt_deinit_entries(ieee, 0); - if (!list_empty(&ieee->crypt_deinit_list)) { - pr_debug("entries remaining in delayed crypt deletion list\n"); - ieee->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&ieee->crypt_deinit_timer); - } - spin_unlock_irqrestore(&ieee->lock, flags); - -} - -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt) -{ - struct ieee80211_crypt_data *tmp; - unsigned long flags; - - if (*crypt == NULL) - return; - - tmp = *crypt; - *crypt = NULL; - - /* must not run ops->deinit() while there may be pending encrypt or - * decrypt operations. Use a list of delayed deinits to avoid needing - * locking. */ - - spin_lock_irqsave(&ieee->lock, flags); - list_add(&tmp->list, &ieee->crypt_deinit_list); - if (!timer_pending(&ieee->crypt_deinit_timer)) { - ieee->crypt_deinit_timer.expires = jiffies + HZ; - add_timer(&ieee->crypt_deinit_timer); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) -{ - unsigned long flags; - struct ieee80211_crypto_alg *alg; - - if (hcrypt == NULL) - return -1; - - alg = kzalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) - return -ENOMEM; - - alg->ops = ops; - - spin_lock_irqsave(&hcrypt->lock, flags); - list_add(&alg->list, &hcrypt->algs); - spin_unlock_irqrestore(&hcrypt->lock, flags); - - pr_debug("registered algorithm '%s'\n", ops->name); - - return 0; -} - -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) -{ - unsigned long flags; - struct list_head *ptr; - struct ieee80211_crypto_alg *del_alg = NULL; - - if (hcrypt == NULL) - return -1; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; - if (alg->ops == ops) { - list_del(&alg->list); - del_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (del_alg) { - pr_debug("unregistered algorithm '%s'\n", ops->name); - kfree(del_alg); - } - - return del_alg ? 0 : -1; -} - - -struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name) -{ - unsigned long flags; - struct list_head *ptr; - struct ieee80211_crypto_alg *found_alg = NULL; - - if (hcrypt == NULL) - return NULL; - - spin_lock_irqsave(&hcrypt->lock, flags); - for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; - if (strcmp(alg->ops->name, name) == 0) { - found_alg = alg; - break; - } - } - spin_unlock_irqrestore(&hcrypt->lock, flags); - - if (found_alg) - return found_alg->ops; - else - return NULL; -} - - -static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } -static void ieee80211_crypt_null_deinit(void *priv) {} - -static struct ieee80211_crypto_ops ieee80211_crypt_null = { - .name = "NULL", - .init = ieee80211_crypt_null_init, - .deinit = ieee80211_crypt_null_deinit, - .encrypt_mpdu = NULL, - .decrypt_mpdu = NULL, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = NULL, - .get_key = NULL, - .extra_prefix_len = 0, - .extra_postfix_len = 0, - .owner = THIS_MODULE, -}; - - -int ieee80211_crypto_init(void) -{ - int ret = -ENOMEM; - - hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); - if (!hcrypt) - goto out; - - INIT_LIST_HEAD(&hcrypt->algs); - spin_lock_init(&hcrypt->lock); - - ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null); - if (ret < 0) { - kfree(hcrypt); - hcrypt = NULL; - } -out: - return ret; -} - - -void ieee80211_crypto_deinit(void) -{ - struct list_head *ptr, *n; - struct ieee80211_crypto_alg *alg = NULL; - - if (hcrypt == NULL) - return; - - list_for_each_safe(ptr, n, &hcrypt->algs) { - alg = list_entry(ptr, struct ieee80211_crypto_alg, list); - if (alg) { - list_del(ptr); - pr_debug("unregistered algorithm '%s' (deinit)\n", - alg->ops->name); - kfree(alg); - } - } - kfree(hcrypt); -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h deleted file mode 100644 index 0b4ea431982d..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Original code based on Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * - * - * Copyright (c) 2004, 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. See README and COPYING for - * more details. - */ - -/* - * This file defines the interface to the ieee80211 crypto module. - */ -#ifndef IEEE80211_CRYPT_H -#define IEEE80211_CRYPT_H - -#include - -struct ieee80211_crypto_ops { - const char *name; - - /* init new crypto context (e.g., allocate private data space, - * select IV, etc.); returns NULL on failure or pointer to allocated - * private data on success */ - void * (*init)(int keyidx); - - /* deinitialize crypto context and free allocated private data */ - void (*deinit)(void *priv); - - /* encrypt/decrypt return < 0 on error or >= 0 on success. The return - * value from decrypt_mpdu is passed as the keyidx value for - * decrypt_msdu. skb must have enough head and tail room for the - * encryption; if not, error will be returned; these functions are - * called for all MPDUs (i.e., fragments). - */ - int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv); - - /* These functions are called for full MSDUs, i.e. full frames. - * These can be NULL if full MSDU operations are not needed. */ - int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); - int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, - void *priv); - - int (*set_key)(void *key, int len, u8 *seq, void *priv); - int (*get_key)(void *key, int len, u8 *seq, void *priv); - - /* procfs handler for printing out key information and possible - * statistics */ - char * (*print_stats)(char *p, void *priv); - - /* maximum number of bytes added by encryption; encrypt buf is - * allocated with extra_prefix_len bytes, copy of in_buf, and - * extra_postfix_len; encrypt need not use all this space, but - * the result must start at the beginning of the buffer and correct - * length must be returned */ - int extra_prefix_len, extra_postfix_len; - - struct module *owner; -}; - -struct ieee80211_crypt_data { - struct list_head list; /* delayed deletion list */ - struct ieee80211_crypto_ops *ops; - void *priv; - atomic_t refcnt; -}; - -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); -struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name); -void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); -void ieee80211_crypt_deinit_handler(unsigned long); -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt); - -#endif diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c deleted file mode 100644 index 4fe253818630..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Host AP crypt: host-based CCMP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: CCMP"); -MODULE_LICENSE("GPL"); - - -#define AES_BLOCK_LEN 16 -#define CCMP_HDR_LEN 8 -#define CCMP_MIC_LEN 8 -#define CCMP_TK_LEN 16 -#define CCMP_PN_LEN 6 - -struct ieee80211_ccmp_data { - u8 key[CCMP_TK_LEN]; - int key_set; - - u8 tx_pn[CCMP_PN_LEN]; - u8 rx_pn[CCMP_PN_LEN]; - - u32 dot11RSNAStatsCCMPFormatErrors; - u32 dot11RSNAStatsCCMPReplays; - u32 dot11RSNAStatsCCMPDecryptErrors; - - int key_idx; - - struct crypto_tfm *tfm; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN], - tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN]; - u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; -}; - -static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, - const u8 pt[16], u8 ct[16]) -{ - crypto_cipher_encrypt_one((void *)tfm, ct, pt); -} - -static void *ieee80211_ccmp_init(int key_idx) -{ - struct ieee80211_ccmp_data *priv; - - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - priv->key_idx = key_idx; - - priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tfm)) { - pr_debug("could not allocate crypto API aes\n"); - priv->tfm = NULL; - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tfm) - crypto_free_cipher((void *)priv->tfm); - kfree(priv); - } - - return NULL; -} - - -static void ieee80211_ccmp_deinit(void *priv) -{ - struct ieee80211_ccmp_data *_priv = priv; - - if (_priv && _priv->tfm) - crypto_free_cipher((void *)_priv->tfm); - kfree(priv); -} - - -static inline void xor_block(u8 *b, u8 *a, size_t len) -{ - int i; - for (i = 0; i < len; i++) - b[i] ^= a[i]; -} - -static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct ieee80211_hdr_4addr *hdr, - u8 *pn, size_t dlen, u8 *b0, u8 *auth, - u8 *s0) -{ - u8 *pos, qc = 0; - size_t aad_len; - u16 fc; - int a4_included, qc_included; - u8 aad[2 * AES_BLOCK_LEN]; - - fc = le16_to_cpu(hdr->frame_ctl); - a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); - /* - qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && - (WLAN_FC_GET_STYPE(fc) & 0x08)); - */ - qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && - (WLAN_FC_GET_STYPE(fc) & 0x80)); - aad_len = 22; - if (a4_included) - aad_len += 6; - if (qc_included) { - pos = (u8 *) &hdr->addr4; - if (a4_included) - pos += 6; - qc = *pos & 0x0f; - aad_len += 2; - } - /* CCM Initial Block: - * Flag (Include authentication header, M=3 (8-octet MIC), - * L=1 (2-octet Dlen)) - * Nonce: 0x00 | A2 | PN - * Dlen */ - b0[0] = 0x59; - b0[1] = qc; - memcpy(b0 + 2, hdr->addr2, ETH_ALEN); - memcpy(b0 + 8, pn, CCMP_PN_LEN); - b0[14] = (dlen >> 8) & 0xff; - b0[15] = dlen & 0xff; - - /* AAD: - * FC with bits 4..6 and 11..13 masked to zero; 14 is always one - * A1 | A2 | A3 - * SC with bits 4..15 (seq#) masked to zero - * A4 (if present) - * QC (if present) - */ - pos = (u8 *) hdr; - aad[0] = 0; /* aad_len >> 8 */ - aad[1] = aad_len & 0xff; - aad[2] = pos[0] & 0x8f; - aad[3] = pos[1] & 0xc7; - memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN); - pos = (u8 *) &hdr->seq_ctl; - aad[22] = pos[0] & 0x0f; - aad[23] = 0; /* all bits masked */ - memset(aad + 24, 0, 8); - if (a4_included) - memcpy(aad + 24, hdr->addr4, ETH_ALEN); - if (qc_included) { - aad[a4_included ? 30 : 24] = qc; - /* rest of QC masked */ - } - - /* Start with the first block and AAD */ - ieee80211_ccmp_aes_encrypt(tfm, b0, auth); - xor_block(auth, aad, AES_BLOCK_LEN); - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); - xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); - b0[0] &= 0x07; - b0[14] = b0[15] = 0; - ieee80211_ccmp_aes_encrypt(tfm, b0, s0); -} - -static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_ccmp_data *key = priv; - int data_len, i; - u8 *pos; - struct ieee80211_hdr_4addr *hdr; - int blocks, last, len; - u8 *mic; - u8 *b0 = key->tx_b0; - u8 *b = key->tx_b; - u8 *e = key->tx_e; - u8 *s0 = key->tx_s0; - - if (skb_headroom(skb) < CCMP_HDR_LEN || - skb_tailroom(skb) < CCMP_MIC_LEN || - skb->len < hdr_len) - return -1; - - data_len = skb->len - hdr_len; - pos = skb_push(skb, CCMP_HDR_LEN); - memmove(pos, pos + CCMP_HDR_LEN, hdr_len); - pos += hdr_len; - - i = CCMP_PN_LEN - 1; - while (i >= 0) { - key->tx_pn[i]++; - if (key->tx_pn[i] != 0) - break; - i--; - } - - *pos++ = key->tx_pn[5]; - *pos++ = key->tx_pn[4]; - *pos++ = 0; - *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = key->tx_pn[3]; - *pos++ = key->tx_pn[2]; - *pos++ = key->tx_pn[1]; - *pos++ = key->tx_pn[0]; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - mic = skb_put(skb, CCMP_MIC_LEN); - - ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); - - blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Authentication */ - xor_block(b, pos, len); - ieee80211_ccmp_aes_encrypt(key->tfm, b, b); - /* Encryption, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); - xor_block(pos, e, len); - pos += len; - } - - for (i = 0; i < CCMP_MIC_LEN; i++) - mic[i] = b[i] ^ s0[i]; - - return 0; -} - - -static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_ccmp_data *key = priv; - u8 keyidx, *pos; - struct ieee80211_hdr_4addr *hdr; - u8 pn[6]; - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; - u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; - u8 *b0 = key->rx_b0; - u8 *b = key->rx_b; - u8 *a = key->rx_a; - int i, blocks, last, len; - - if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { - key->dot11RSNAStatsCCMPFormatErrors++; - return -1; - } - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - pr_debug("received packet without ExtIV flag from %pM\n", - hdr->addr2); - } - key->dot11RSNAStatsCCMPFormatErrors++; - return -2; - } - keyidx >>= 6; - if (key->key_idx != keyidx) { - pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n", - key->key_idx, keyidx, priv); - return -6; - } - if (!key->key_set) { - if (net_ratelimit()) { - pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n", - hdr->addr2, keyidx); - } - return -3; - } - - pn[0] = pos[7]; - pn[1] = pos[6]; - pn[2] = pos[5]; - pn[3] = pos[4]; - pn[4] = pos[1]; - pn[5] = pos[0]; - pos += 8; - - if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { - if (net_ratelimit()) { - pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n", - hdr->addr2, key->rx_pn, pn); - } - key->dot11RSNAStatsCCMPReplays++; - return -4; - } - - ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b); - xor_block(mic, b, CCMP_MIC_LEN); - - blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last = data_len % AES_BLOCK_LEN; - - for (i = 1; i <= blocks; i++) { - len = (i == blocks && last) ? last : AES_BLOCK_LEN; - /* Decrypt, with counter */ - b0[14] = (i >> 8) & 0xff; - b0[15] = i & 0xff; - ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); - xor_block(pos, b, len); - /* Authentication */ - xor_block(a, pos, len); - ieee80211_ccmp_aes_encrypt(key->tfm, a, a); - pos += len; - } - - if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { - if (net_ratelimit()) - pr_debug("decrypt failed: STA=%pM\n", hdr->addr2); - - key->dot11RSNAStatsCCMPDecryptErrors++; - return -5; - } - - memcpy(key->rx_pn, pn, CCMP_PN_LEN); - - /* Remove hdr and MIC */ - memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len); - skb_pull(skb, CCMP_HDR_LEN); - skb_trim(skb, skb->len - CCMP_MIC_LEN); - - return keyidx; -} - - -static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_ccmp_data *data = priv; - int keyidx; - struct crypto_tfm *tfm = data->tfm; - - keyidx = data->key_idx; - memset(data, 0, sizeof(*data)); - data->key_idx = keyidx; - data->tfm = tfm; - if (len == CCMP_TK_LEN) { - memcpy(data->key, key, CCMP_TK_LEN); - data->key_set = 1; - if (seq) { - data->rx_pn[0] = seq[5]; - data->rx_pn[1] = seq[4]; - data->rx_pn[2] = seq[3]; - data->rx_pn[3] = seq[2]; - data->rx_pn[4] = seq[1]; - data->rx_pn[5] = seq[0]; - } - crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN); - } else if (len == 0) - data->key_set = 0; - else - return -1; - - return 0; -} - - -static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_ccmp_data *data = priv; - - if (len < CCMP_TK_LEN) - return -1; - - if (!data->key_set) - return 0; - memcpy(key, data->key, CCMP_TK_LEN); - - if (seq) { - seq[0] = data->tx_pn[5]; - seq[1] = data->tx_pn[4]; - seq[2] = data->tx_pn[3]; - seq[3] = data->tx_pn[2]; - seq[4] = data->tx_pn[1]; - seq[5] = data->tx_pn[0]; - } - - return CCMP_TK_LEN; -} - - -static char *ieee80211_ccmp_print_stats(char *p, void *priv) -{ - struct ieee80211_ccmp_data *ccmp = priv; - p += sprintf(p, - "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n", - ccmp->key_idx, ccmp->key_set, - ccmp->tx_pn, ccmp->rx_pn, - ccmp->dot11RSNAStatsCCMPFormatErrors, - ccmp->dot11RSNAStatsCCMPReplays, - ccmp->dot11RSNAStatsCCMPDecryptErrors); - - return p; -} - -void ieee80211_ccmp_null(void) -{ - return; -} -static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { - .name = "CCMP", - .init = ieee80211_ccmp_init, - .deinit = ieee80211_ccmp_deinit, - .encrypt_mpdu = ieee80211_ccmp_encrypt, - .decrypt_mpdu = ieee80211_ccmp_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = ieee80211_ccmp_set_key, - .get_key = ieee80211_ccmp_get_key, - .print_stats = ieee80211_ccmp_print_stats, - .extra_prefix_len = CCMP_HDR_LEN, - .extra_postfix_len = CCMP_MIC_LEN, - .owner = THIS_MODULE, -}; - - -int ieee80211_crypto_ccmp_init(void) -{ - return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); -} - - -void ieee80211_crypto_ccmp_exit(void) -{ - ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c deleted file mode 100644 index 6c1acc5dfba7..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * Host AP crypt: host-based TKIP encryption implementation for Host AP driver - * - * Copyright (c) 2003-2004, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#include -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: TKIP"); -MODULE_LICENSE("GPL"); - - -struct ieee80211_tkip_data { -#define TKIP_KEY_LEN 32 - u8 key[TKIP_KEY_LEN]; - int key_set; - - u32 tx_iv32; - u16 tx_iv16; - u16 tx_ttak[5]; - int tx_phase1_done; - - u32 rx_iv32; - u16 rx_iv16; - u16 rx_ttak[5]; - int rx_phase1_done; - u32 rx_iv32_new; - u16 rx_iv16_new; - - u32 dot11RSNAStatsTKIPReplays; - u32 dot11RSNAStatsTKIPICVErrors; - u32 dot11RSNAStatsTKIPLocalMICFailures; - - int key_idx; - - struct crypto_blkcipher *rx_tfm_arc4; - struct crypto_hash *rx_tfm_michael; - struct crypto_blkcipher *tx_tfm_arc4; - struct crypto_hash *tx_tfm_michael; - struct crypto_tfm *tfm_arc4; - struct crypto_tfm *tfm_michael; - - /* scratch buffers for virt_to_page() (crypto API) */ - u8 rx_hdr[16], tx_hdr[16]; -}; - -static void *ieee80211_tkip_init(int key_idx) -{ - struct ieee80211_tkip_data *priv; - - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - priv->key_idx = key_idx; - - priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tx_tfm_arc4)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " - "crypto API arc4\n"); - priv->tx_tfm_arc4 = NULL; - goto fail; - } - - priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); - priv->tx_tfm_michael = NULL; - goto fail; - } - - priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->rx_tfm_arc4)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " - "crypto API arc4\n"); - priv->rx_tfm_arc4 = NULL; - goto fail; - } - - priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " - "crypto API michael_mic\n"); - priv->rx_tfm_michael = NULL; - goto fail; - } - - return priv; - -fail: - if (priv) { - if (priv->tx_tfm_michael) - crypto_free_hash(priv->tx_tfm_michael); - if (priv->tx_tfm_arc4) - crypto_free_blkcipher(priv->tx_tfm_arc4); - if (priv->rx_tfm_michael) - crypto_free_hash(priv->rx_tfm_michael); - if (priv->rx_tfm_arc4) - crypto_free_blkcipher(priv->rx_tfm_arc4); - kfree(priv); - } - - return NULL; -} - - -static void ieee80211_tkip_deinit(void *priv) -{ - struct ieee80211_tkip_data *_priv = priv; - - if (_priv) { - if (_priv->tx_tfm_michael) - crypto_free_hash(_priv->tx_tfm_michael); - if (_priv->tx_tfm_arc4) - crypto_free_blkcipher(_priv->tx_tfm_arc4); - if (_priv->rx_tfm_michael) - crypto_free_hash(_priv->rx_tfm_michael); - if (_priv->rx_tfm_arc4) - crypto_free_blkcipher(_priv->rx_tfm_arc4); - } - kfree(priv); -} - - -static inline u16 RotR1(u16 val) -{ - return (val >> 1) | (val << 15); -} - - -static inline u8 Lo8(u16 val) -{ - return val & 0xff; -} - - -static inline u8 Hi8(u16 val) -{ - return val >> 8; -} - - -static inline u16 Lo16(u32 val) -{ - return val & 0xffff; -} - - -static inline u16 Hi16(u32 val) -{ - return val >> 16; -} - - -static inline u16 Mk16(u8 hi, u8 lo) -{ - return lo | (((u16) hi) << 8); -} - - -static inline u16 Mk16_le(u16 *v) -{ - return le16_to_cpu(*v); -} - - -static const u16 Sbox[256] = { - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - - -static inline u16 _S_(u16 v) -{ - u16 t = Sbox[Hi8(v)]; - return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8)); -} - -#define PHASE1_LOOP_COUNT 8 - -static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32) -{ - int i, j; - - /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */ - TTAK[0] = Lo16(IV32); - TTAK[1] = Hi16(IV32); - TTAK[2] = Mk16(TA[1], TA[0]); - TTAK[3] = Mk16(TA[3], TA[2]); - TTAK[4] = Mk16(TA[5], TA[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j])); - TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j])); - TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j])); - TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j])); - TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i; - } -} - - -static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, - u16 IV16) -{ - /* Make temporary area overlap WEP seed so that the final copy can be - * avoided on little endian hosts. */ - u16 *PPK = (u16 *) &WEPSeed[4]; - - /* Step 1 - make copy of TTAK and bring in TSC */ - PPK[0] = TTAK[0]; - PPK[1] = TTAK[1]; - PPK[2] = TTAK[2]; - PPK[3] = TTAK[3]; - PPK[4] = TTAK[4]; - PPK[5] = TTAK[4] + IV16; - - /* Step 2 - 96-bit bijective mixing using S-box */ - PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0])); - PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2])); - PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4])); - PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6])); - PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8])); - PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10])); - - PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12])); - PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14])); - PPK[2] += RotR1(PPK[1]); - PPK[3] += RotR1(PPK[2]); - PPK[4] += RotR1(PPK[3]); - PPK[5] += RotR1(PPK[4]); - - /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value - * WEPSeed[0..2] is transmitted as WEP IV */ - WEPSeed[0] = Hi8(IV16); - WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F; - WEPSeed[2] = Lo8(IV16); - WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1); - -#ifdef __BIG_ENDIAN - { - int i; - for (i = 0; i < 6; i++) - PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8); - } -#endif -} - -static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4}; - int len; - u8 *pos; - struct ieee80211_hdr_4addr *hdr; - u8 rc4key[16], *icv; - u32 crc; - struct scatterlist sg; - int ret; - - ret = 0; - if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - - if (!tkey->tx_phase1_done) { - tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, - tkey->tx_iv32); - tkey->tx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); - - len = skb->len - hdr_len; - pos = skb_push(skb, 8); - memmove(pos, pos + 8, hdr_len); - pos += hdr_len; - - *pos++ = rc4key[0]; - *pos++ = rc4key[1]; - *pos++ = rc4key[2]; - *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */; - *pos++ = tkey->tx_iv32 & 0xff; - *pos++ = (tkey->tx_iv32 >> 8) & 0xff; - *pos++ = (tkey->tx_iv32 >> 16) & 0xff; - *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - - icv = skb_put(skb, 4); - crc = ~crc32_le(~0, pos, len); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); - sg_init_one(&sg, pos, len + 4); - ret = crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); - - tkey->tx_iv16++; - if (tkey->tx_iv16 == 0) { - tkey->tx_phase1_done = 0; - tkey->tx_iv32++; - } - return ret; -} - -static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 }; - u8 keyidx, *pos; - u32 iv32; - u16 iv16; - struct ieee80211_hdr_4addr *hdr; - u8 icv[4]; - u32 crc; - struct scatterlist sg; - u8 rc4key[16]; - int plen; - - if (skb->len < hdr_len + 8 + 4) - return -1; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - pos = skb->data + hdr_len; - keyidx = pos[3]; - if (!(keyidx & (1 << 5))) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet without ExtIV" - " flag from %pM\n", hdr->addr2); - } - return -2; - } - keyidx >>= 6; - if (tkey->key_idx != keyidx) { - printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame " - "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv); - return -6; - } - if (!tkey->key_set) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: received packet from %pM" - " with keyid=%d that does not have a configured" - " key\n", hdr->addr2, keyidx); - } - return -3; - } - iv16 = (pos[0] << 8) | pos[2]; - iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); - pos += 8; - - if (iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" - " previous TSC %08x%04x received TSC " - "%08x%04x\n", hdr->addr2, - tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); - } - tkey->dot11RSNAStatsTKIPReplays++; - return -4; - } - - if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { - tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); - tkey->rx_phase1_done = 1; - } - tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); - - plen = skb->len - hdr_len - 12; - crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); - sg_init_one(&sg, pos, plen + 4); - if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { - if (net_ratelimit()) { - printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from %pM\n", - hdr->addr2); - } - return -7; - } - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - if (memcmp(icv, pos + plen, 4) != 0) { - if (iv32 != tkey->rx_iv32) { - /* Previously cached Phase1 result was already lost, so - * it needs to be recalculated for the next packet. */ - tkey->rx_phase1_done = 0; - } - if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: ICV error detected: STA=" - "%pM\n", hdr->addr2); - } - tkey->dot11RSNAStatsTKIPICVErrors++; - return -5; - } - - /* Update real counters only after Michael MIC verification has - * completed */ - tkey->rx_iv32_new = iv32; - tkey->rx_iv16_new = iv16; - - /* Remove IV and ICV */ - memmove(skb->data + 8, skb->data, hdr_len); - skb_pull(skb, 8); - skb_trim(skb, skb->len - 4); - - return keyidx; -} - -static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr, - u8 *data, size_t data_len, u8 *mic) -{ - struct hash_desc desc; - struct scatterlist sg[2]; - - if (tfm_michael == NULL) { - printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); - return -1; - } - - sg_init_table(sg, 2); - sg_set_buf(&sg[0], hdr, 16); - sg_set_buf(&sg[1], data, data_len); - - if (crypto_hash_setkey(tfm_michael, key, 8)) - return -1; - - desc.tfm = tfm_michael; - desc.flags = 0; - return crypto_hash_digest(&desc, sg, data_len + 16, mic); -} - -static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) -{ - struct ieee80211_hdr_4addr *hdr11; - - hdr11 = (struct ieee80211_hdr_4addr *)skb->data; - switch (le16_to_cpu(hdr11->frame_ctl) & - (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - case IEEE80211_FCTL_FROMDS: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ - break; - case 0: - memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ - memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ - break; - } - - hdr[12] = 0; /* priority */ - - hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */ -} - - -static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, - void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - u8 *pos; - struct ieee80211_hdr_4addr *hdr; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - - if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { - printk(KERN_DEBUG "Invalid packet for Michael MIC add " - "(tailroom=%d hdr_len=%d skb->len=%d)\n", - skb_tailroom(skb), hdr_len, skb->len); - return -1; - } - - michael_mic_hdr(skb, tkey->tx_hdr); - - if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) - tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - - pos = skb_put(skb, 8); - - if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) - return -1; - - return 0; -} - -static void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr_4addr *hdr, - int keyidx) -{ - union iwreq_data wrqu; - struct iw_michaelmicfailure ev; - - /* TODO: needed parameters: count, keyid, key type, TSC */ - memset(&ev, 0, sizeof(ev)); - ev.flags = keyidx & IW_MICFAILURE_KEY_ID; - if (hdr->addr1[0] & 0x01) - ev.flags |= IW_MICFAILURE_GROUP; - else - ev.flags |= IW_MICFAILURE_PAIRWISE; - ev.src_addr.sa_family = ARPHRD_ETHER; - memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = sizeof(ev); - wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); -} - -static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - u8 mic[8]; - struct ieee80211_hdr_4addr *hdr; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - - if (!tkey->key_set) - return -1; - - michael_mic_hdr(skb, tkey->rx_hdr); - if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) - tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - - if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) - return -1; - - if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct ieee80211_hdr_4addr *hdr; - hdr = (struct ieee80211_hdr_4addr *)skb->data; - printk(KERN_DEBUG "%s: Michael MIC verification failed for " - "MSDU from %pM keyidx=%d\n", - skb->dev ? skb->dev->name : "N/A", hdr->addr2, - keyidx); - if (skb->dev) - ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); - tkey->dot11RSNAStatsTKIPLocalMICFailures++; - return -1; - } - - /* Update TSC counters for RX now that the packet verification has - * completed. */ - tkey->rx_iv32 = tkey->rx_iv32_new; - tkey->rx_iv16 = tkey->rx_iv16_new; - - skb_trim(skb, skb->len - 8); - - return 0; -} - - -static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - int keyidx; - struct crypto_hash *tfm = tkey->tx_tfm_michael; - struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4; - struct crypto_hash *tfm3 = tkey->rx_tfm_michael; - struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4; - - keyidx = tkey->key_idx; - memset(tkey, 0, sizeof(*tkey)); - tkey->key_idx = keyidx; - - tkey->tx_tfm_michael = tfm; - tkey->tx_tfm_arc4 = tfm2; - tkey->rx_tfm_michael = tfm3; - tkey->rx_tfm_arc4 = tfm4; - - if (len == TKIP_KEY_LEN) { - memcpy(tkey->key, key, TKIP_KEY_LEN); - tkey->key_set = 1; - tkey->tx_iv16 = 1; /* TSC is initialized to 1 */ - if (seq) { - tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) | - (seq[3] << 8) | seq[2]; - tkey->rx_iv16 = (seq[1] << 8) | seq[0]; - } - } else if (len == 0) - tkey->key_set = 0; - else - return -1; - - return 0; -} - - -static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct ieee80211_tkip_data *tkey = priv; - - if (len < TKIP_KEY_LEN) - return -1; - - if (!tkey->key_set) - return 0; - memcpy(key, tkey->key, TKIP_KEY_LEN); - - if (seq) { - /* Return the sequence number of the last transmitted frame. */ - u16 iv16 = tkey->tx_iv16; - u32 iv32 = tkey->tx_iv32; - if (iv16 == 0) - iv32--; - iv16--; - seq[0] = tkey->tx_iv16; - seq[1] = tkey->tx_iv16 >> 8; - seq[2] = tkey->tx_iv32; - seq[3] = tkey->tx_iv32 >> 8; - seq[4] = tkey->tx_iv32 >> 16; - seq[5] = tkey->tx_iv32 >> 24; - } - - return TKIP_KEY_LEN; -} - - -static char *ieee80211_tkip_print_stats(char *p, void *priv) -{ - struct ieee80211_tkip_data *tkip = priv; - p += sprintf(p, "key[%d] alg=TKIP key_set=%d " - "tx_pn=%02x%02x%02x%02x%02x%02x " - "rx_pn=%02x%02x%02x%02x%02x%02x " - "replays=%d icv_errors=%d local_mic_failures=%d\n", - tkip->key_idx, tkip->key_set, - (tkip->tx_iv32 >> 24) & 0xff, - (tkip->tx_iv32 >> 16) & 0xff, - (tkip->tx_iv32 >> 8) & 0xff, - tkip->tx_iv32 & 0xff, - (tkip->tx_iv16 >> 8) & 0xff, - tkip->tx_iv16 & 0xff, - (tkip->rx_iv32 >> 24) & 0xff, - (tkip->rx_iv32 >> 16) & 0xff, - (tkip->rx_iv32 >> 8) & 0xff, - tkip->rx_iv32 & 0xff, - (tkip->rx_iv16 >> 8) & 0xff, - tkip->rx_iv16 & 0xff, - tkip->dot11RSNAStatsTKIPReplays, - tkip->dot11RSNAStatsTKIPICVErrors, - tkip->dot11RSNAStatsTKIPLocalMICFailures); - return p; -} - - -static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { - .name = "TKIP", - .init = ieee80211_tkip_init, - .deinit = ieee80211_tkip_deinit, - .encrypt_mpdu = ieee80211_tkip_encrypt, - .decrypt_mpdu = ieee80211_tkip_decrypt, - .encrypt_msdu = ieee80211_michael_mic_add, - .decrypt_msdu = ieee80211_michael_mic_verify, - .set_key = ieee80211_tkip_set_key, - .get_key = ieee80211_tkip_get_key, - .print_stats = ieee80211_tkip_print_stats, - .extra_prefix_len = 4 + 4, /* IV + ExtIV */ - .extra_postfix_len = 8 + 4, /* MIC + ICV */ - .owner = THIS_MODULE, -}; - - -int ieee80211_crypto_tkip_init(void) -{ - return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); -} - - -void ieee80211_crypto_tkip_exit(void) -{ - ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); -} - - -void ieee80211_tkip_null(void) -{ -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c deleted file mode 100644 index f25367224941..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Host AP crypt: host-based WEP encryption implementation for Host AP driver - * - * Copyright (c) 2002-2004, Jouni Malinen - * - * 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. See README and COPYING for - * more details. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -#include -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: WEP"); -MODULE_LICENSE("GPL"); - -struct prism2_wep_data { - u32 iv; -#define WEP_KEY_LEN 13 - u8 key[WEP_KEY_LEN + 1]; - u8 key_len; - u8 key_idx; - struct crypto_blkcipher *tx_tfm; - struct crypto_blkcipher *rx_tfm; -}; - -static void *prism2_wep_init(int keyidx) -{ - struct prism2_wep_data *priv; - - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); - if (priv == NULL) - goto fail; - priv->key_idx = keyidx; - priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tx_tfm)) { - pr_debug("could not allocate crypto API arc4\n"); - priv->tx_tfm = NULL; - goto fail; - } - priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->rx_tfm)) { - pr_debug("could not allocate crypto API arc4\n"); - priv->rx_tfm = NULL; - goto fail; - } - - /* start WEP IV from a random value */ - get_random_bytes(&priv->iv, 4); - - return priv; - -fail: - if (priv) { - if (priv->tx_tfm) - crypto_free_blkcipher(priv->tx_tfm); - if (priv->rx_tfm) - crypto_free_blkcipher(priv->rx_tfm); - kfree(priv); - } - - return NULL; -} - -static void prism2_wep_deinit(void *priv) -{ - struct prism2_wep_data *_priv = priv; - - if (_priv) { - if (_priv->tx_tfm) - crypto_free_blkcipher(_priv->tx_tfm); - if (_priv->rx_tfm) - crypto_free_blkcipher(_priv->rx_tfm); - } - - kfree(priv); -} - -/* Perform WEP encryption on given skb that has at least 4 bytes of headroom - * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted, - * so the payload length increases with 8 bytes. - * - * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) - */ -static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - struct blkcipher_desc desc = { .tfm = wep->tx_tfm }; - u32 klen, len; - u8 key[WEP_KEY_LEN + 3]; - u8 *pos; - u32 crc; - u8 *icv; - struct scatterlist sg; - - if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) - return -1; - - len = skb->len - hdr_len; - pos = skb_push(skb, 4); - memmove(pos, pos + 4, hdr_len); - pos += hdr_len; - - klen = 3 + wep->key_len; - - wep->iv++; - - /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key - * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N) - * can be used to speedup attacks, so avoid using them. */ - if ((wep->iv & 0xff00) == 0xff00) { - u8 B = (wep->iv >> 16) & 0xff; - if (B >= 3 && B < klen) - wep->iv += 0x0100; - } - - /* Prepend 24-bit IV to RC4 key and TX frame */ - *pos++ = key[0] = (wep->iv >> 16) & 0xff; - *pos++ = key[1] = (wep->iv >> 8) & 0xff; - *pos++ = key[2] = wep->iv & 0xff; - *pos++ = wep->key_idx << 6; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Append little-endian CRC32 and encrypt it to produce ICV */ - crc = ~crc32_le(~0, pos, len); - icv = skb_put(skb, 4); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - crypto_blkcipher_setkey(wep->tx_tfm, key, klen); - sg_init_one(&sg, pos, len + 4); - - return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); -} - -/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of - * the frame: IV (4 bytes), encrypted payload (including SNAP header), - * ICV (4 bytes). len includes both IV and ICV. - * - * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on - * failure. If frame is OK, IV and ICV will be removed. - */ -static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) -{ - struct prism2_wep_data *wep = priv; - struct blkcipher_desc desc = { .tfm = wep->rx_tfm }; - u32 klen, plen; - u8 key[WEP_KEY_LEN + 3]; - u8 keyidx, *pos; - u32 crc; - u8 icv[4]; - struct scatterlist sg; - - if (skb->len < hdr_len + 8) - return -1; - - pos = skb->data + hdr_len; - key[0] = *pos++; - key[1] = *pos++; - key[2] = *pos++; - keyidx = *pos++ >> 6; - if (keyidx != wep->key_idx) - return -1; - - klen = 3 + wep->key_len; - - /* Copy rest of the WEP key (the secret part) */ - memcpy(key + 3, wep->key, wep->key_len); - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - plen = skb->len - hdr_len - 8; - - crypto_blkcipher_setkey(wep->rx_tfm, key, klen); - sg_init_one(&sg, pos, plen + 4); - - if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) - return -7; - - crc = ~crc32_le(~0, pos, plen); - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - if (memcmp(icv, pos + plen, 4) != 0) { - /* ICV mismatch - drop frame */ - return -2; - } - - /* Remove IV and ICV */ - memmove(skb->data + 4, skb->data, hdr_len); - skb_pull(skb, 4); - skb_trim(skb, skb->len - 4); - return 0; -} - -static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < 0 || len > WEP_KEY_LEN) - return -1; - - memcpy(wep->key, key, len); - wep->key_len = len; - - return 0; -} - -static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) -{ - struct prism2_wep_data *wep = priv; - - if (len < wep->key_len) - return -1; - - memcpy(key, wep->key, wep->key_len); - - return wep->key_len; -} - -static char *prism2_wep_print_stats(char *p, void *priv) -{ - struct prism2_wep_data *wep = priv; - p += sprintf(p, "key[%d] alg=WEP len=%d\n", - wep->key_idx, wep->key_len); - return p; -} - -static struct ieee80211_crypto_ops ieee80211_crypt_wep = { - .name = "WEP", - .init = prism2_wep_init, - .deinit = prism2_wep_deinit, - .encrypt_mpdu = prism2_wep_encrypt, - .decrypt_mpdu = prism2_wep_decrypt, - .encrypt_msdu = NULL, - .decrypt_msdu = NULL, - .set_key = prism2_wep_set_key, - .get_key = prism2_wep_get_key, - .print_stats = prism2_wep_print_stats, - .extra_prefix_len = 4, /* IV */ - .extra_postfix_len = 4, /* ICV */ - .owner = THIS_MODULE, -}; - -int ieee80211_crypto_wep_init(void) -{ - return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); -} - -void ieee80211_crypto_wep_exit(void) -{ - ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); -} - -void ieee80211_wep_null(void) -{ - return; -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c deleted file mode 100644 index 07a1fbb6678e..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c +++ /dev/null @@ -1,203 +0,0 @@ -/******************************************************************************* - - Copyright(c) 2004 Intel Corporation. All rights reserved. - - Portions of this file are based on the WEP enablement code provided by the - Host AP project hostap-drivers v0.1.3 - Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - - Copyright (c) 2002-2003, Jouni Malinen - - 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. - - 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., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - -MODULE_DESCRIPTION("802.11 data/management/control stack"); -MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation "); -MODULE_LICENSE("GPL"); - -#define DRV_NAME "ieee80211" - -static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) -{ - if (ieee->networks) - return 0; - - ieee->networks = kcalloc( - MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), - GFP_KERNEL); - if (!ieee->networks) - return -ENOMEM; - - return 0; -} - -static inline void ieee80211_networks_free(struct ieee80211_device *ieee) -{ - if (!ieee->networks) - return; - kfree(ieee->networks); - ieee->networks = NULL; -} - -static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee) -{ - int i; - - INIT_LIST_HEAD(&ieee->network_free_list); - INIT_LIST_HEAD(&ieee->network_list); - for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ieee->networks[i].list, &ieee->network_free_list); -} - - -struct net_device *alloc_ieee80211(int sizeof_priv) -{ - struct ieee80211_device *ieee; - struct net_device *dev; - int i, err; - - IEEE80211_DEBUG_INFO("Initializing...\n"); - - dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); - if (!dev) { - IEEE80211_ERROR("Unable to network device.\n"); - goto failed; - } - ieee = netdev_priv(dev); - - ieee->dev = dev; - - err = ieee80211_networks_allocate(ieee); - if (err) { - IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", - err); - goto failed; - } - ieee80211_networks_initialize(ieee); - - /* Default fragmentation threshold is maximum payload size */ - ieee->fts = DEFAULT_FTS; - ieee->scan_age = DEFAULT_MAX_SCAN_AGE; - ieee->open_wep = 1; - - /* Default to enabling full open WEP with host based encrypt/decrypt */ - ieee->host_encrypt = 1; - ieee->host_decrypt = 1; - ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ - - INIT_LIST_HEAD(&ieee->crypt_deinit_list); - init_timer(&ieee->crypt_deinit_timer); - ieee->crypt_deinit_timer.data = (unsigned long)ieee; - ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler; - - spin_lock_init(&ieee->lock); - spin_lock_init(&ieee->wpax_suitlist_lock); - - ieee->wpax_type_set = 0; - ieee->wpa_enabled = 0; - ieee->tkip_countermeasures = 0; - ieee->drop_unencrypted = 0; - ieee->privacy_invoked = 0; - ieee->ieee802_1x = 1; - ieee->raw_tx = 0; - - ieee80211_softmac_init(ieee); - - for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) - INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } -//These function were added to load crypte module autoly - ieee80211_tkip_null(); - ieee80211_wep_null(); - ieee80211_ccmp_null(); - return dev; - - failed: - if (dev) - free_netdev(dev); - return NULL; -} - - -void free_ieee80211(struct net_device *dev) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - - int i; - struct list_head *p, *q; - - - ieee80211_softmac_free(ieee); - del_timer_sync(&ieee->crypt_deinit_timer); - ieee80211_crypt_deinit_entries(ieee, 1); - - for (i = 0; i < WEP_KEYS; i++) { - struct ieee80211_crypt_data *crypt = ieee->crypt[i]; - if (crypt) { - if (crypt->ops) - crypt->ops->deinit(crypt->priv); - kfree(crypt); - ieee->crypt[i] = NULL; - } - } - - ieee80211_networks_free(ieee); - - for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) { - list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) { - kfree(list_entry(p, struct ieee_ibss_seq, list)); - list_del(p); - } - } - - - free_netdev(dev); -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c deleted file mode 100644 index b522b57a2691..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c +++ /dev/null @@ -1,1486 +0,0 @@ -/* - * Original code based Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3 - hostap.o module, common routines - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * Copyright (c) 2004, 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. See README and COPYING for - * more details. - ****************************************************************************** - - Few modifications for Realtek's Wi-Fi drivers by - Andrea Merello - - A special thanks goes to Realtek for their support ! - -******************************************************************************/ - - -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" -#include "dot11d.h" -static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) -{ - struct ieee80211_hdr_4addr *hdr = - (struct ieee80211_hdr_4addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); - - skb->dev = ieee->dev; - skb_reset_mac_header(skb); - skb_pull(skb, ieee80211_get_hdrlen(fc)); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = __constant_htons(ETH_P_80211_RAW); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -static struct ieee80211_frag_entry * -ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq, - unsigned int frag, u8 tid, u8 *src, u8 *dst) -{ - struct ieee80211_frag_entry *entry; - int i; - - for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) { - entry = &ieee->frag_cache[tid][i]; - if (entry->skb != NULL && - time_after(jiffies, entry->first_frag_time + 2 * HZ)) { - IEEE80211_DEBUG_FRAG( - "expiring fragment cache entry " - "seq=%u last_frag=%u\n", - entry->seq, entry->last_frag); - dev_kfree_skb_any(entry->skb); - entry->skb = NULL; - } - - if (entry->skb != NULL && entry->seq == seq && - (entry->last_frag + 1 == frag || frag == -1) && - memcmp(entry->src_addr, src, ETH_ALEN) == 0 && - memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) - return entry; - } - - return NULL; -} - -/* Called only as a tasklet (software IRQ) */ -static struct sk_buff * -ieee80211_frag_cache_get(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *hdr) -{ - struct sk_buff *skb = NULL; - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); - unsigned int frag = WLAN_GET_SEQ_FRAG(sc); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct ieee80211_frag_entry *entry; - struct ieee80211_hdr_3addrqos *hdr_3addrqos; - struct ieee80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID; - tid = UP2AC(tid); - tid++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - if (frag == 0) { - /* Reserve enough space to fit maximum frame length */ - skb = dev_alloc_skb(ieee->dev->mtu + - sizeof(struct ieee80211_hdr_4addr) + - 8 /* LLC */ + - 2 /* alignment */ + - 8 /* WEP */ + - ETH_ALEN /* WDS */ + - (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */); - if (skb == NULL) - return NULL; - - entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; - ieee->frag_next_idx[tid]++; - if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN) - ieee->frag_next_idx[tid] = 0; - - if (entry->skb != NULL) - dev_kfree_skb_any(entry->skb); - - entry->first_frag_time = jiffies; - entry->seq = seq; - entry->last_frag = frag; - entry->skb = skb; - memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); - memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); - } else { - /* received a fragment of a frame for which the head fragment - * should have already been received */ - entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2, - hdr->addr1); - if (entry != NULL) { - entry->last_frag = frag; - skb = entry->skb; - } - } - - return skb; -} - - -/* Called only as a tasklet (software IRQ) */ -static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *hdr) -{ - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct ieee80211_frag_entry *entry; - struct ieee80211_hdr_3addrqos *hdr_3addrqos; - struct ieee80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID; - tid = UP2AC(tid); - tid++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID; - tid = UP2AC(tid); - tid++; - } else { - tid = 0; - } - - entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2, - hdr->addr1); - - if (entry == NULL) { - IEEE80211_DEBUG_FRAG( - "could not invalidate fragment cache " - "entry (seq=%u)\n", seq); - return -1; - } - - entry->skb = NULL; - return 0; -} - - - -/* ieee80211_rx_frame_mgtmt - * - * Responsible for handling management control frames - * - * Called by ieee80211_rx */ -static inline int -ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype) -{ - struct ieee80211_hdr_4addr *hdr; - - // cheat the the hdr type - hdr = (struct ieee80211_hdr_4addr *)skb->data; - - /* On the struct stats definition there is written that - * this is not mandatory.... but seems that the probe - * response parser uses it - */ - rx_stats->len = skb->len; - ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data, - rx_stats); - - if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) { - dev_kfree_skb_any(skb); - return 0; - } - - ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype); - - dev_kfree_skb_any(skb); - - return 0; - -} - - - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ - -/* Called by ieee80211_rx_frame_decrypt */ -static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, - struct sk_buff *skb, size_t hdrlen) -{ - struct net_device *dev = ieee->dev; - u16 fc, ethertype; - struct ieee80211_hdr_4addr *hdr; - u8 *pos; - - if (skb->len < 24) - return 0; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - fc = le16_to_cpu(hdr->frame_ctl); - - /* check that the frame is unicast frame to us */ - if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_TODS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && - memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { - /* ToDS frame with own addr BSSID and DA */ - } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_FROMDS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - /* FromDS frame with own addr as DA */ - } else - return 0; - - if (skb->len < 24 + 8) - return 0; - - /* check for port access entity Ethernet type */ -// pos = skb->data + 24; - pos = skb->data + hdrlen; - ethertype = (pos[6] << 8) | pos[7]; - if (ethertype == ETH_P_PAE) - return 1; - - return 0; -} - -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ -static inline int -ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) -{ - struct ieee80211_hdr_4addr *hdr; - int res, hdrlen; - - if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) - return 0; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); - -#ifdef CONFIG_IEEE80211_CRYPT_TKIP - if (ieee->tkip_countermeasures && - strcmp(crypt->ops->name, "TKIP") == 0) { - if (net_ratelimit()) { - netdev_dbg(ieee->dev, - "TKIP countermeasures: dropped received packet from %pM\n", - ieee->dev->name, hdr->addr2); - } - return -1; - } -#endif - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - IEEE80211_DEBUG_DROP( - "decryption failed (SA=%pM" - ") res=%d\n", hdr->addr2, res); - if (res == -2) - IEEE80211_DEBUG_DROP("Decryption failed ICV " - "mismatch (key %d)\n", - skb->data[hdrlen + 3] >> 6); - ieee->ieee_stats.rx_discards_undecryptable++; - return -1; - } - - return res; -} - - -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ -static inline int -ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee, - struct sk_buff *skb, int keyidx, - struct ieee80211_crypt_data *crypt) -{ - struct ieee80211_hdr_4addr *hdr; - int res, hdrlen; - - if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) - return 0; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_dbg(ieee->dev, - "MSDU decryption/MIC verification failed (SA=%pM keyidx=%d)\n", - hdr->addr2, keyidx); - return -1; - } - - return 0; -} - - -/* this function is stolen from ipw2200 driver*/ -#define IEEE_PACKET_RETRY_TIME (5*HZ) -static int is_duplicate_packet(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header) -{ - u16 fc = le16_to_cpu(header->frame_ctl); - u16 sc = le16_to_cpu(header->seq_ctl); - u16 seq = WLAN_GET_SEQ_SEQ(sc); - u16 frag = WLAN_GET_SEQ_FRAG(sc); - u16 *last_seq, *last_frag; - unsigned long *last_time; - struct ieee80211_hdr_3addrqos *hdr_3addrqos; - struct ieee80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - //TO2DS and QoS - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID; - tid = UP2AC(tid); - tid++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS - hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID; - tid = UP2AC(tid); - tid++; - } else { // no QoS - tid = 0; - } - switch (ieee->iw_mode) { - case IW_MODE_ADHOC: - { - struct list_head *p; - struct ieee_ibss_seq *entry = NULL; - u8 *mac = header->addr2; - int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; - - list_for_each(p, &ieee->ibss_mac_hash[index]) { - entry = list_entry(p, struct ieee_ibss_seq, list); - if (!memcmp(entry->mac, mac, ETH_ALEN)) - break; - } - // if (memcmp(entry->mac, mac, ETH_ALEN)){ - if (p == &ieee->ibss_mac_hash[index]) { - entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); - if (!entry) - return 0; - - memcpy(entry->mac, mac, ETH_ALEN); - entry->seq_num[tid] = seq; - entry->frag_num[tid] = frag; - entry->packet_time[tid] = jiffies; - list_add(&entry->list, &ieee->ibss_mac_hash[index]); - return 0; - } - last_seq = &entry->seq_num[tid]; - last_frag = &entry->frag_num[tid]; - last_time = &entry->packet_time[tid]; - break; - } - - case IW_MODE_INFRA: - last_seq = &ieee->last_rxseq_num[tid]; - last_frag = &ieee->last_rxfrag_num[tid]; - last_time = &ieee->last_packet_time[tid]; - - break; - default: - return 0; - } - -// if(tid != 0) { -// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl); -// } - if ((*last_seq == seq) && - time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { - if (*last_frag == frag) { - //printk(KERN_WARNING "[1] go drop!\n"); - goto drop; - - } - if (*last_frag + 1 != frag) - /* out-of-order fragment */ - //printk(KERN_WARNING "[2] go drop!\n"); - goto drop; - } else - *last_seq = seq; - - *last_frag = frag; - *last_time = jiffies; - return 0; - -drop: -// BUG_ON(!(fc & IEEE80211_FCTL_RETRY)); -// printk("DUP\n"); - - return 1; -} - - -/* All received frames are sent to this function. @skb contains the frame in - * IEEE 802.11 format, i.e., in the format it was sent over air. - * This function is called only as a tasklet (software IRQ). */ -int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) -{ - struct net_device *dev = ieee->dev; - //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct ieee80211_hdr_4addr *hdr; - - size_t hdrlen; - u16 fc, type, stype, sc; - struct net_device_stats *stats; - unsigned int frag; - u8 *payload; - u16 ethertype; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - struct ieee80211_crypt_data *crypt = NULL; - int keyidx = 0; - - // cheat the the hdr type - hdr = (struct ieee80211_hdr_4addr *)skb->data; - stats = &ieee->stats; - - if (skb->len < 10) { - netdev_info(ieee->dev, "SKB length < 10\n"); - goto rx_dropped; - } - - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctl); - - frag = WLAN_GET_SEQ_FRAG(sc); - -//YJ,add,080828,for keep alive - if ((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS) { - if (!memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) - ieee->NumRxUnicast++; - } else { - if (!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) - ieee->NumRxUnicast++; - } -//YJ,add,080828,for keep alive,end - - hdrlen = ieee80211_get_hdrlen(fc); - - - if (ieee->iw_mode == IW_MODE_MONITOR) { - ieee80211_monitor_rx(ieee, skb, rx_stats); - stats->rx_packets++; - stats->rx_bytes += skb->len; - return 1; - } - - if (ieee->host_decrypt) { - int idx = 0; - if (skb->len >= hdrlen + 3) - idx = skb->data[hdrlen + 3] >> 6; - crypt = ieee->crypt[idx]; - - /* allow NULL decrypt to indicate an station specific override - * for default encryption */ - if (crypt && (crypt->ops == NULL || - crypt->ops->decrypt_mpdu == NULL)) - crypt = NULL; - - if (!crypt && (fc & IEEE80211_FCTL_WEP)) { - /* This seems to be triggered by some (multicast?) - * frames from other than current BSS, so just drop the - * frames silently instead of filling system log with - * these reports. */ - IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=%pM)\n", - hdr->addr2); - ieee->ieee_stats.rx_discards_undecryptable++; - goto rx_dropped; - } - } - - if (skb->len < IEEE80211_DATA_HDR3_LEN) - goto rx_dropped; - - // if QoS enabled, should check the sequence for each of the AC - if (is_duplicate_packet(ieee, hdr)) - goto rx_dropped; - - - if (type == IEEE80211_FTYPE_MGMT) { - if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) - goto rx_dropped; - else - goto rx_exit; - } - - /* Data frame - extract src/dst addresses */ - switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_FROMDS: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr3, ETH_ALEN); - memcpy(bssid, hdr->addr2, ETH_ALEN); - break; - case IEEE80211_FCTL_TODS: - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr1, ETH_ALEN); - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - if (skb->len < IEEE80211_DATA_HDR4_LEN) - goto rx_dropped; - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr4, ETH_ALEN); - memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); - break; - case 0: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr3, ETH_ALEN); - break; - } - - - dev->last_rx = jiffies; - - - /* Nullfunc frames may have PS-bit set, so they must be passed to - * hostap_handle_sta_rx() before being dropped here. */ - if (stype != IEEE80211_STYPE_DATA && - stype != IEEE80211_STYPE_DATA_CFACK && - stype != IEEE80211_STYPE_DATA_CFPOLL && - stype != IEEE80211_STYPE_DATA_CFACKPOLL && - stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4 - ) { - if (stype != IEEE80211_STYPE_NULLFUNC) - IEEE80211_DEBUG_DROP( - "RX: dropped data frame " - "with no data (type=0x%02x, " - "subtype=0x%02x, len=%d)\n", - type, stype, skb->len); - goto rx_dropped; - } - if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) - goto rx_dropped; - - ieee->NumRxDataInPeriod++; - ieee->NumRxOkTotal++; - /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ - - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) - goto rx_dropped; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - - /* skb: hdr + (possibly fragmented) plaintext payload */ - // PR: FIXME: hostap has additional conditions in the "if" below: - // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { - int flen; - struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); - IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); - - if (!frag_skb) { - IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG, - "Rx cannot get skb from fragment " - "cache (morefrag=%d seq=%u frag=%u)\n", - (fc & IEEE80211_FCTL_MOREFRAGS) != 0, - WLAN_GET_SEQ_SEQ(sc), frag); - goto rx_dropped; - } - flen = skb->len; - if (frag != 0) - flen -= hdrlen; - - if (frag_skb->tail + flen > frag_skb->end) { - netdev_warn(ieee->dev, - "host decrypted and reassembled frame did not fit skb\n"); - ieee80211_frag_cache_invalidate(ieee, hdr); - goto rx_dropped; - } - - if (frag == 0) { - /* copy first fragment (including full headers) into - * beginning of the fragment cache skb */ - memcpy(skb_put(frag_skb, flen), skb->data, flen); - } else { - /* append frame payload to the end of the fragment - * cache skb */ - memcpy(skb_put(frag_skb, flen), skb->data + hdrlen, - flen); - } - dev_kfree_skb_any(skb); - skb = NULL; - - if (fc & IEEE80211_FCTL_MOREFRAGS) { - /* more fragments expected - leave the skb in fragment - * cache for now; it will be delivered to upper layers - * after all fragments have been received */ - goto rx_exit; - } - - /* this was the last fragment and the frame will be - * delivered, so remove skb from fragment cache */ - skb = frag_skb; - hdr = (struct ieee80211_hdr_4addr *)skb->data; - ieee80211_frag_cache_invalidate(ieee, hdr); - } - - /* skb: hdr + (possible reassembled) full MSDU payload; possibly still - * encrypted/authenticated */ - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) - goto rx_dropped; - - hdr = (struct ieee80211_hdr_4addr *)skb->data; - if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { - if (/*ieee->ieee802_1x &&*/ - ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - -#ifdef CONFIG_IEEE80211_DEBUG - /* pass unencrypted EAPOL frames even if encryption is - * configured */ - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); -#endif - } else { - IEEE80211_DEBUG_DROP( - "encryption configured, but RX " - "frame not encrypted (SA=%pM)\n", - hdr->addr2); - goto rx_dropped; - } - } - -#ifdef CONFIG_IEEE80211_DEBUG - if (crypt && !(fc & IEEE80211_FCTL_WEP) && - ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); - } -#endif - - if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep && - !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - IEEE80211_DEBUG_DROP( - "dropped unencrypted RX data " - "frame from %pM" - " (drop_unencrypted=1)\n", - hdr->addr2); - goto rx_dropped; - } -/* - if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n"); - } -*/ - /* skb: hdr + (possible reassembled) full plaintext payload */ - payload = skb->data + hdrlen; - ethertype = (payload[6] << 8) | payload[7]; - - - /* convert hdr + possible LLC headers into Ethernet header */ - if (skb->len - hdrlen >= 8 && - ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType */ - skb_pull(skb, hdrlen + SNAP_SIZE); - memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); - } else { - u16 len; - /* Leave Ethernet header part of hdr and full payload */ - skb_pull(skb, hdrlen); - len = htons(skb->len); - memcpy(skb_push(skb, 2), &len, 2); - memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); - } - - - stats->rx_packets++; - stats->rx_bytes += skb->len; - - if (skb) { - skb->protocol = eth_type_trans(skb, dev); - memset(skb->cb, 0, sizeof(skb->cb)); - skb->dev = dev; - skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ - ieee->last_rx_ps_time = jiffies; - netif_rx(skb); - } - - rx_exit: - return 1; - - rx_dropped: - stats->rx_dropped++; - - /* Returning 0 indicates to caller that we have not handled the SKB-- - * so it is still allocated and can be used again by underlying - * hardware as a DMA target */ - return 0; -} - -#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 - -static inline int ieee80211_is_ofdm_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_OFDM_RATE_6MB: - case IEEE80211_OFDM_RATE_9MB: - case IEEE80211_OFDM_RATE_12MB: - case IEEE80211_OFDM_RATE_18MB: - case IEEE80211_OFDM_RATE_24MB: - case IEEE80211_OFDM_RATE_36MB: - case IEEE80211_OFDM_RATE_48MB: - case IEEE80211_OFDM_RATE_54MB: - return 1; - } - return 0; -} - -static inline int ieee80211_SignalStrengthTranslate(int CurrSS) -{ - int RetSS; - - // Step 1. Scale mapping. - if (CurrSS >= 71 && CurrSS <= 100) - RetSS = 90 + ((CurrSS - 70) / 3); - else if (CurrSS >= 41 && CurrSS <= 70) - RetSS = 78 + ((CurrSS - 40) / 3); - else if (CurrSS >= 31 && CurrSS <= 40) - RetSS = 66 + (CurrSS - 30); - else if (CurrSS >= 21 && CurrSS <= 30) - RetSS = 54 + (CurrSS - 20); - else if (CurrSS >= 5 && CurrSS <= 20) - RetSS = 42 + (((CurrSS - 5) * 2) / 3); - else if (CurrSS == 4) - RetSS = 36; - else if (CurrSS == 3) - RetSS = 27; - else if (CurrSS == 2) - RetSS = 18; - else if (CurrSS == 1) - RetSS = 9; - else - RetSS = CurrSS; - - //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); - - // Step 2. Smoothing. - - //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS)); - - return RetSS; -} - -static inline void -ieee80211_extract_country_ie(struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - struct ieee80211_network *network, u8 *addr2) -{ - if (IS_DOT11D_ENABLE(ieee)) { - if (info_element->len != 0) { - memcpy(network->CountryIeBuf, info_element->data, info_element->len); - network->CountryIeLen = info_element->len; - - if (!IS_COUNTRY_IE_VALID(ieee)) - Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data); - } - - // - // 070305, rcnjko: I update country IE watch dog here because - // some AP (e.g. Cisco 1242) don't include country IE in their - // probe response frame. - // - if (IS_EQUAL_CIE_SRC(ieee, addr2)) - UPDATE_CIE_WATCHDOG(ieee); - } - -} - -/* SignalStrengthIndex is 0-100 */ -static int ieee80211_TranslateToDbm(unsigned char SignalStrengthIndex) -{ - unsigned char SignalPower; // in dBm. - - // Translate to dBm (x=0.5y-95). - SignalPower = (int)SignalStrengthIndex * 7 / 10; - SignalPower -= 95; - - return SignalPower; -} -inline int ieee80211_network_init( - struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats) -{ -#ifdef CONFIG_IEEE80211_DEBUG - char rates_str[64]; - char *p; -#endif - struct ieee80211_info_element *info_element; - u16 left; - u8 i; - short offset; - u8 curRate = 0, hOpRate = 0, curRate_ex = 0; - - /* Pull out fixed field data */ - memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); - network->capability = beacon->capability; - network->last_scanned = jiffies; - network->time_stamp[0] = beacon->time_stamp[0]; - network->time_stamp[1] = beacon->time_stamp[1]; - network->beacon_interval = beacon->beacon_interval; - /* Where to pull this? beacon->listen_interval;*/ - network->listen_interval = 0x0A; - network->rates_len = network->rates_ex_len = 0; - network->last_associate = 0; - network->ssid_len = 0; - network->flags = 0; - network->atim_window = 0; - network->QoS_Enable = 0; -//by amy 080312 - network->HighestOperaRate = 0; -//by amy 080312 - network->Turbo_Enable = 0; - network->CountryIeLen = 0; - memset(network->CountryIeBuf, 0, MAX_IE_LEN); - - if (stats->freq == IEEE80211_52GHZ_BAND) { - /* for A band (No DS info) */ - network->channel = stats->received_channel; - } else - network->flags |= NETWORK_HAS_CCK; - - network->wpa_ie_len = 0; - network->rsn_ie_len = 0; - - info_element = &beacon->info_element; - left = stats->len - ((void *)info_element - (void *)beacon); - while (left >= sizeof(struct ieee80211_info_element_hdr)) { - if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) { - IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n", - info_element->len + sizeof(struct ieee80211_info_element), - left); - return 1; - } - - switch (info_element->id) { - case MFIE_TYPE_SSID: - if (ieee80211_is_empty_essid(info_element->data, - info_element->len)) { - network->flags |= NETWORK_EMPTY_ESSID; - break; - } - - network->ssid_len = min(info_element->len, - (u8)IW_ESSID_MAX_SIZE); - memcpy(network->ssid, info_element->data, network->ssid_len); - if (network->ssid_len < IW_ESSID_MAX_SIZE) - memset(network->ssid + network->ssid_len, 0, - IW_ESSID_MAX_SIZE - network->ssid_len); - - IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n", - network->ssid, network->ssid_len); - break; - - case MFIE_TYPE_RATES: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_len = min(info_element->len, MAX_RATES_LENGTH); - for (i = 0; i < network->rates_len; i++) { - network->rates[i] = info_element->data[i]; - curRate = network->rates[i] & 0x7f; - if (hOpRate < curRate) - hOpRate = curRate; -#ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]); -#endif - if (ieee80211_is_ofdm_rate(info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n", - rates_str, network->rates_len); - break; - - case MFIE_TYPE_RATES_EX: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH); - for (i = 0; i < network->rates_ex_len; i++) { - network->rates_ex[i] = info_element->data[i]; - curRate_ex = network->rates_ex[i] & 0x7f; - if (hOpRate < curRate_ex) - hOpRate = curRate_ex; -#ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]); -#endif - if (ieee80211_is_ofdm_rate(info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n", - rates_str, network->rates_ex_len); - break; - - case MFIE_TYPE_DS_SET: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n", - info_element->data[0]); - if (stats->freq == IEEE80211_24GHZ_BAND) - network->channel = info_element->data[0]; - break; - - case MFIE_TYPE_FH_SET: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n"); - break; - - case MFIE_TYPE_CF_SET: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n"); - break; - - case MFIE_TYPE_TIM: - - if (info_element->len < 4) - break; - - network->dtim_period = info_element->data[1]; - - if (ieee->state != IEEE80211_LINKED) - break; - - network->last_dtim_sta_time[0] = jiffies; - network->last_dtim_sta_time[1] = stats->mac_time[1]; - - network->dtim_data = IEEE80211_DTIM_VALID; - - if (info_element->data[0] != 0) - break; - - if (info_element->data[2] & 1) - network->dtim_data |= IEEE80211_DTIM_MBCAST; - - offset = (info_element->data[2] >> 1)*2; - - //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id); - - /* add and modified for ps 2008.1.22 */ - if (ieee->assoc_id < 8*offset || - ieee->assoc_id > 8*(offset + info_element->len - 3)) { - break; - } - - offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ; - - // printk("offset:%x data:%x, ucast:%d\n", offset, - // info_element->data[3+offset] , - // info_element->data[3+offset] & (1<<(ieee->assoc_id%8))); - - if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) - network->dtim_data |= IEEE80211_DTIM_UCAST; - - break; - - case MFIE_TYPE_IBSS_SET: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n"); - break; - - case MFIE_TYPE_CHALLENGE: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n"); - break; - - case MFIE_TYPE_GENERIC: - //nic is 87B - IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", - info_element->len); - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x01) { - network->wpa_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->wpa_ie, info_element, - network->wpa_ie_len); - } - - if (info_element->len == 7 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x01 && - info_element->data[4] == 0x02) { - network->Turbo_Enable = 1; - } - if (1 == stats->nic_type) //nic 87 - break; - - if (info_element->len >= 5 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x02 && - info_element->data[4] == 0x00) { - //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]); - //WMM Information Element - network->wmm_info = info_element->data[6]; - network->QoS_Enable = 1; - } - - if (info_element->len >= 8 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x02 && - info_element->data[4] == 0x01) { - // Not care about version at present. - //WMM Information Element - //printk(KERN_WARNING "wmm info¶m updated: %x\n", info_element->data[6]); - network->wmm_info = info_element->data[6]; - //WMM Parameter Element - memcpy(network->wmm_param, (u8 *)(info_element->data + 8), (info_element->len - 8)); - network->QoS_Enable = 1; - } - break; - - case MFIE_TYPE_RSN: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n", - info_element->len); - network->rsn_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->rsn_ie, info_element, - network->rsn_ie_len); - break; - case MFIE_TYPE_COUNTRY: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", - info_element->len); -// printk("=====>Receive <%s> Country IE\n",network->ssid); - ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2); - break; - default: - IEEE80211_DEBUG_SCAN("unsupported IE %d\n", - info_element->id); - break; - } - - left -= sizeof(struct ieee80211_info_element_hdr) + - info_element->len; - info_element = (struct ieee80211_info_element *) - &info_element->data[info_element->len]; - } -//by amy 080312 - network->HighestOperaRate = hOpRate; -//by amy 080312 - network->mode = 0; - if (stats->freq == IEEE80211_52GHZ_BAND) - network->mode = IEEE_A; - else { - if (network->flags & NETWORK_HAS_OFDM) - network->mode |= IEEE_G; - if (network->flags & NETWORK_HAS_CCK) - network->mode |= IEEE_B; - } - - if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " - "network.\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid); - return 1; - } - - if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) - network->flags |= NETWORK_EMPTY_ESSID; - - stats->signal = ieee80211_TranslateToDbm(stats->signalstrength); - //stats->noise = stats->signal - stats->noise; - stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25; - memcpy(&network->stats, stats, sizeof(network->stats)); - - return 0; -} - -static inline int is_same_network(struct ieee80211_network *src, - struct ieee80211_network *dst, - struct ieee80211_device *ieee) -{ - /* A network is only a duplicate if the channel, BSSID, ESSID - * and the capability field (in particular IBSS and BSS) all match. - * We treat all with the same BSSID and channel - * as one network */ - return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap - //((src->ssid_len == dst->ssid_len) && - (src->channel == dst->channel) && - !memcmp(src->bssid, dst->bssid, ETH_ALEN) && - (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap - //!memcmp(src->ssid, dst->ssid, src->ssid_len) && - ((src->capability & WLAN_CAPABILITY_IBSS) == - (dst->capability & WLAN_CAPABILITY_IBSS)) && - ((src->capability & WLAN_CAPABILITY_BSS) == - (dst->capability & WLAN_CAPABILITY_BSS))); -} - -inline void update_network(struct ieee80211_network *dst, - struct ieee80211_network *src) -{ - unsigned char quality = src->stats.signalstrength; - unsigned char signal = 0; - unsigned char noise = 0; - if (dst->stats.signalstrength > 0) - quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6; - signal = ieee80211_TranslateToDbm(quality); - //noise = signal - src->stats.noise; - if (dst->stats.noise > 0) - noise = (dst->stats.noise * 5 + src->stats.noise)/6; - //if(strcmp(dst->ssid, "linksys_lzm000") == 0) -// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal); - memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); - dst->stats.signalstrength = quality; - dst->stats.signal = signal; -// printk("==================>stats.signal is %d\n",dst->stats.signal); - dst->stats.noise = noise; - - - dst->capability = src->capability; - memcpy(dst->rates, src->rates, src->rates_len); - dst->rates_len = src->rates_len; - memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); - dst->rates_ex_len = src->rates_ex_len; - dst->HighestOperaRate = src->HighestOperaRate; - //printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel); - - //YJ,add,080819,for hidden ap - if (src->ssid_len > 0) { - //if(src->ssid_len == 13) - // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid); - memset(dst->ssid, 0, dst->ssid_len); - dst->ssid_len = src->ssid_len; - memcpy(dst->ssid, src->ssid, src->ssid_len); - } - //YJ,add,080819,for hidden ap,end - - dst->channel = src->channel; - dst->mode = src->mode; - dst->flags = src->flags; - dst->time_stamp[0] = src->time_stamp[0]; - dst->time_stamp[1] = src->time_stamp[1]; - - dst->beacon_interval = src->beacon_interval; - dst->listen_interval = src->listen_interval; - dst->atim_window = src->atim_window; - dst->dtim_period = src->dtim_period; - dst->dtim_data = src->dtim_data; - dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0]; - dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1]; -// printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data); - memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); - dst->wpa_ie_len = src->wpa_ie_len; - memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); - dst->rsn_ie_len = src->rsn_ie_len; - - dst->last_scanned = jiffies; - /* dst->last_associate is not overwritten */ -// disable QoS process now, added by David 2006/7/25 -#if 1 - dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. -/* - if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter - memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN); - } -*/ - if (src->wmm_param[0].ac_aci_acm_aifsn || \ - src->wmm_param[1].ac_aci_acm_aifsn || \ - src->wmm_param[2].ac_aci_acm_aifsn || \ - src->wmm_param[3].ac_aci_acm_aifsn) { - memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); - } - dst->QoS_Enable = src->QoS_Enable; -#else - dst->QoS_Enable = 1;//for Rtl8187 simulation -#endif - dst->SignalStrength = src->SignalStrength; - dst->Turbo_Enable = src->Turbo_Enable; - dst->CountryIeLen = src->CountryIeLen; - memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); -} - - -inline void -ieee80211_process_probe_response(struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_rx_stats *stats) -{ - struct ieee80211_network network; - struct ieee80211_network *target; - struct ieee80211_network *oldest = NULL; -#ifdef CONFIG_IEEE80211_DEBUG - struct ieee80211_info_element *info_element = &beacon->info_element; -#endif - unsigned long flags; - short renew; - u8 wmm_info; - u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON) ? 1 : 0; //YJ,add,080819,for hidden ap - - memset(&network, 0, sizeof(struct ieee80211_network)); - - IEEE80211_DEBUG_SCAN( - "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", - escape_essid(info_element->data, info_element->len), - beacon->header.addr3, - (beacon->capability & (1<<0xf)) ? '1' : '0', - (beacon->capability & (1<<0xe)) ? '1' : '0', - (beacon->capability & (1<<0xd)) ? '1' : '0', - (beacon->capability & (1<<0xc)) ? '1' : '0', - (beacon->capability & (1<<0xb)) ? '1' : '0', - (beacon->capability & (1<<0xa)) ? '1' : '0', - (beacon->capability & (1<<0x9)) ? '1' : '0', - (beacon->capability & (1<<0x8)) ? '1' : '0', - (beacon->capability & (1<<0x7)) ? '1' : '0', - (beacon->capability & (1<<0x6)) ? '1' : '0', - (beacon->capability & (1<<0x5)) ? '1' : '0', - (beacon->capability & (1<<0x4)) ? '1' : '0', - (beacon->capability & (1<<0x3)) ? '1' : '0', - (beacon->capability & (1<<0x2)) ? '1' : '0', - (beacon->capability & (1<<0x1)) ? '1' : '0', - (beacon->capability & (1<<0x0)) ? '1' : '0'); - - if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", - escape_essid(info_element->data, - info_element->len), - beacon->header.addr3, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); - return; - } - - // For Asus EeePc request, - // (1) if wireless adapter receive get any 802.11d country code in AP beacon, - // wireless adapter should follow the country code. - // (2) If there is no any country code in beacon, - // then wireless adapter should do active scan from ch1~11 and - // passive scan from ch12~14 - if (ieee->bGlobalDomain) { - if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) { - // Case 1: Country code - if (IS_COUNTRY_IE_VALID(ieee)) { - if (!IsLegalChannel(ieee, network.channel)) { - printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel); - return; - } - } - // Case 2: No any country code. - else { - // Filter over channel ch12~14 - if (network.channel > 11) { - printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel); - return; - } - } - } else { - // Case 1: Country code - if (IS_COUNTRY_IE_VALID(ieee)) { - if (!IsLegalChannel(ieee, network.channel)) { - printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network.channel); - return; - } - } - // Case 2: No any country code. - else { - // Filter over channel ch12~14 - if (network.channel > 14) { - printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network.channel); - return; - } - } - } - } - /* The network parsed correctly -- so now we scan our known networks - * to see if we can find it in our list. - * - * NOTE: This search is definitely not optimized. Once its doing - * the "right thing" we'll optimize it for efficiency if - * necessary */ - - /* Search for this entry in the list and update it if it is - * already there. */ - - spin_lock_irqsave(&ieee->lock, flags); - - if (is_same_network(&ieee->current_network, &network, ieee)) { - wmm_info = ieee->current_network.wmm_info; - //YJ,add,080819,for hidden ap - if (is_beacon == 0) - network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags); - else if (ieee->state == IEEE80211_LINKED) - ieee->NumRxBcnInPeriod++; - //YJ,add,080819,for hidden ap,end - //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid); - update_network(&ieee->current_network, &network); - } - - list_for_each_entry(target, &ieee->network_list, list) { - if (is_same_network(target, &network, ieee)) - break; - if ((oldest == NULL) || - (target->last_scanned < oldest->last_scanned)) - oldest = target; - } - - /* If we didn't find a match, then get a new network slot to initialize - * with this beacon's information */ - if (&target->list == &ieee->network_list) { - if (list_empty(&ieee->network_free_list)) { - /* If there are no more slots, expire the oldest */ - list_del(&oldest->list); - target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " - "network list.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid); - } else { - /* Otherwise just pull from the free list */ - target = list_entry(ieee->network_free_list.next, - struct ieee80211_network, list); - list_del(ieee->network_free_list.next); - } - - -#ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", - escape_essid(network.ssid, - network.ssid_len), - network.bssid, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); -#endif - - memcpy(target, &network, sizeof(*target)); - list_add_tail(&target->list, &ieee->network_list); - } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); - - /* we have an entry and we are going to update it. But this entry may - * be already expired. In this case we do the same as we found a new - * net and call the new_net handler - */ - renew = !time_after(target->last_scanned + ieee->scan_age, jiffies); - //YJ,add,080819,for hidden ap - if (is_beacon == 0) - network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags); - //if(strncmp(network.ssid, "linksys-c",9) == 0) - // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags); - if (((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ - && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\ - || ((ieee->current_network.ssid_len == network.ssid_len) && (strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK)))) - renew = 1; - //YJ,add,080819,for hidden ap,end - update_network(target, &network); - } - - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats) -{ - switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { - - case IEEE80211_STYPE_BEACON: - IEEE80211_DEBUG_MGMT("received BEACON (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - IEEE80211_DEBUG_SCAN("Beacon\n"); - ieee80211_process_probe_response( - ieee, (struct ieee80211_probe_response *)header, stats); - break; - - case IEEE80211_STYPE_PROBE_RESP: - IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - IEEE80211_DEBUG_SCAN("Probe response\n"); - ieee80211_process_probe_response( - ieee, (struct ieee80211_probe_response *)header, stats); - break; - } -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c deleted file mode 100644 index 03eb164798cd..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ /dev/null @@ -1,2711 +0,0 @@ -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Few lines might be stolen from other part of the ieee80211 - * stack. Copyright who own it's copyright - * - * WPA code stolen from the ipw2200 driver. - * Copyright who own it's copyright. - * - * released under the GPL - */ - -#include "ieee80211.h" - -#include -#include -#include -#include -#include -#include - -#include "dot11d.h" - -short ieee80211_is_54g(const struct ieee80211_network *net) -{ - return (net->rates_ex_len > 0) || (net->rates_len > 4); -} - -short ieee80211_is_shortslot(const struct ieee80211_network *net) -{ - return net->capability & WLAN_CAPABILITY_SHORT_SLOT; -} - -/* returns the total length needed for placing the RATE MFIE - * tag and the EXTENDED RATE MFIE tag if needed. - * It encludes two bytes per tag for the tag itself and its len - */ -static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) -{ - unsigned int rate_len = 0; - - if (ieee->modulation & IEEE80211_CCK_MODULATION) - rate_len = IEEE80211_CCK_RATE_LEN + 2; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION) - - rate_len += IEEE80211_OFDM_RATE_LEN + 2; - - return rate_len; -} - -/* place the MFIE rate, tag to the memory (double) poised. - * Then it updates the pointer so that it points after the new MFIE tag added. - */ -static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - *tag++ = MFIE_TYPE_RATES; - *tag++ = 4; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; - } - - /* We may add an option for custom rates that specific HW might support */ - *tag_p = tag; -} - -static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION) { - *tag++ = MFIE_TYPE_RATES_EX; - *tag++ = 8; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; - - } - /* We may add an option for custom rates that specific HW might support */ - *tag_p = tag; -} - -static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; /* 0 */ - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0x50; - *tag++ = 0xf2; - *tag++ = 0x02; /* 5 */ - *tag++ = 0x00; - *tag++ = 0x01; -#ifdef SUPPORT_USPD - if (ieee->current_network.wmm_info & 0x80) - *tag++ = 0x0f|MAX_SP_Len; - else - *tag++ = MAX_SP_Len; -#else - *tag++ = MAX_SP_Len; -#endif - *tag_p = tag; -} - -static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - *tag++ = MFIE_TYPE_GENERIC; /* 0 */ - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0xe0; - *tag++ = 0x4c; - *tag++ = 0x01; /* 5 */ - *tag++ = 0x02; - *tag++ = 0x11; - *tag++ = 0x00; - *tag_p = tag; - printk(KERN_ALERT "This is enable turbo mode IE process\n"); -} - -static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - int nh; - nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM; - - ieee->mgmt_queue_head = nh; - ieee->mgmt_queue_ring[nh] = skb; -} - -static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) -{ - struct sk_buff *ret; - - if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head) - return NULL; - - ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; - - ieee->mgmt_queue_tail = - (ieee->mgmt_queue_tail + 1) % MGMT_QUEUE_NUM; - - return ret; -} - -static void init_mgmt_queue(struct ieee80211_device *ieee) -{ - ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; -} - -void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); - -inline void softmac_mgmt_xmit(struct sk_buff *skb, - struct ieee80211_device *ieee) -{ - unsigned long flags; - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *) skb->data; - - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd param 0, no mgmt lock required */ - ieee80211_sta_wakeup(ieee, 0); - - if (single) { - if (ieee->queue_stop) { - enqueue_mgmt(ieee, skb); - } else { - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->dev->trans_start = jiffies; - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - } else { - spin_unlock_irqrestore(&ieee->lock, flags); - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); - - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->dev->trans_start = jiffies; - ieee->softmac_hard_start_xmit(skb, ieee->dev); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); - } -} - -inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, - struct ieee80211_device *ieee) -{ - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *) skb->data; - - if (single) { - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->dev->trans_start = jiffies; - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate); - } else { - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->dev->trans_start = jiffies; - ieee->softmac_hard_start_xmit(skb, ieee->dev); - } -} - -inline struct sk_buff * -ieee80211_disassociate_skb(struct ieee80211_network *beacon, - struct ieee80211_device *ieee, u8 asRsn) -{ - struct sk_buff *skb; - struct ieee80211_disassoc_frame *disass; - - skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame)); - if (!skb) - return NULL; - - disass = (struct ieee80211_disassoc_frame *) skb_put(skb, sizeof(struct ieee80211_disassoc_frame)); - disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC); - disass->header.duration_id = 0; - - memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); - - disass->reasoncode = asRsn; - return skb; -} - -void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn) -{ - struct ieee80211_network *beacon = &ieee->current_network; - struct sk_buff *skb; - skb = ieee80211_disassociate_skb(beacon, ieee, asRsn); - if (skb) - softmac_mgmt_xmit(skb, ieee); -} - -inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) -{ - unsigned int len, rate_len; - u8 *tag; - struct sk_buff *skb; - struct ieee80211_probe_request *req; - - len = ieee->current_network.ssid_len; - - rate_len = ieee80211_MFIE_rate_len(ieee); - - skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + - 2 + len + rate_len); - if (!skb) - return NULL; - - req = (struct ieee80211_probe_request *) skb_put(skb, sizeof(struct ieee80211_probe_request)); - req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - req->header.duration_id = 0; /* FIXME: is this OK ? */ - - memset(req->header.addr1, 0xff, ETH_ALEN); - memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memset(req->header.addr3, 0xff, ETH_ALEN); - - tag = (u8 *) skb_put(skb, len + 2 + rate_len); - - *tag++ = MFIE_TYPE_SSID; - *tag++ = len; - memcpy(tag, ieee->current_network.ssid, len); - tag += len; - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - - return skb; -} - -struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); - -static void ieee80211_send_beacon(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - - skb = ieee80211_get_beacon_(ieee); - - if (skb) { - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_beacons++; - dev_kfree_skb_any(skb); - } - - ieee->beacon_timer.expires = jiffies + - (MSECS(ieee->current_network.beacon_interval - 5)); - - if (ieee->beacon_txing) - add_timer(&ieee->beacon_timer); -} - - -static void ieee80211_send_beacon_cb(unsigned long _ieee) -{ - struct ieee80211_device *ieee = - (struct ieee80211_device *) _ieee; - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - ieee80211_send_beacon(ieee); - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - -static void ieee80211_send_probe(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - - skb = ieee80211_probe_req(ieee); - if (skb) { - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_probe_rq++; - } -} - -static void ieee80211_send_probe_requests(struct ieee80211_device *ieee) -{ - if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) { - ieee80211_send_probe(ieee); - ieee80211_send_probe(ieee); - } -} - -/* this performs syncro scan blocking the caller until all channels - * in the allowed channel map has been checked. - */ -static void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) -{ - short ch = 0; - u8 channel_map[MAX_CHANNEL_NUMBER+1]; - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); - down(&ieee->scan_sem); - - while (1) { - do { - ch++; - if (ch > MAX_CHANNEL_NUMBER) - goto out; /* scan completed */ - - } while (!channel_map[ch]); - /* this function can be called in two situations - * 1- We have switched to ad-hoc mode and we are - * performing a complete syncro scan before conclude - * there are no interesting cell and to create a - * new one. In this case the link state is - * IEEE80211_NOLINK until we found an interesting cell. - * If so the ieee8021_new_net, called by the RX path - * will set the state to IEEE80211_LINKED, so we stop - * scanning - * 2- We are linked and the root uses run iwlist scan. - * So we switch to IEEE80211_LINKED_SCANNING to remember - * that we are still logically linked (not interested in - * new network events, despite for updating the net list, - * but we are temporarily 'unlinked' as the driver shall - * not filter RX frames and the channel is changing. - * So the only situation in witch are interested is to check - * if the state become LINKED because of the #1 situation - */ - - if (ieee->state == IEEE80211_LINKED) - goto out; - - ieee->set_chan(ieee->dev, ch); - if (channel_map[ch] == 1) - ieee80211_send_probe_requests(ieee); - - /* this prevent excessive time wait when we - * need to wait for a syncro scan to end.. - */ - if (ieee->sync_scan_hurryup) - goto out; - - msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME); - } -out: - ieee->sync_scan_hurryup = 0; - up(&ieee->scan_sem); - if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); -} - -void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee) -{ - int ch; - unsigned int watch_dog = 0; - u8 channel_map[MAX_CHANNEL_NUMBER+1]; - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); - down(&ieee->scan_sem); - ch = ieee->current_network.channel; - - while (1) { - /* this function can be called in two situations - * 1- We have switched to ad-hoc mode and we are - * performing a complete syncro scan before conclude - * there are no interesting cell and to create a - * new one. In this case the link state is - * IEEE80211_NOLINK until we found an interesting cell. - * If so the ieee8021_new_net, called by the RX path - * will set the state to IEEE80211_LINKED, so we stop - * scanning - * 2- We are linked and the root uses run iwlist scan. - * So we switch to IEEE80211_LINKED_SCANNING to remember - * that we are still logically linked (not interested in - * new network events, despite for updating the net list, - * but we are temporarily 'unlinked' as the driver shall - * not filter RX frames and the channel is changing. - * So the only situation in witch are interested is to check - * if the state become LINKED because of the #1 situation - */ - if (ieee->state == IEEE80211_LINKED) - goto out; - - if (channel_map[ieee->current_network.channel] > 0) - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - if (channel_map[ieee->current_network.channel] == 1) - ieee80211_send_probe_requests(ieee); - - msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME); - - do { - if (watch_dog++ >= MAX_CHANNEL_NUMBER) - goto out; /* scan completed */ - - ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER; - } while (!channel_map[ieee->current_network.channel]); - } -out: - ieee->actscanning = false; - up(&ieee->scan_sem); - if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); -} - -static void ieee80211_softmac_scan_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); - static short watchdog; - u8 channel_map[MAX_CHANNEL_NUMBER+1]; - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); - down(&ieee->scan_sem); - - do { - ieee->current_network.channel = - (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; - if (watchdog++ > MAX_CHANNEL_NUMBER) - goto out; /* no good chans */ - } while (!channel_map[ieee->current_network.channel]); - - if (ieee->scanning == 0) { - printk("error out, scanning = 0\n"); - goto out; - } - ieee->set_chan(ieee->dev, ieee->current_network.channel); - if (channel_map[ieee->current_network.channel] == 1) - ieee80211_send_probe_requests(ieee); - - queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); - up(&ieee->scan_sem); - return; -out: - ieee->actscanning = false; - watchdog = 0; - ieee->scanning = 0; - up(&ieee->scan_sem); - - if (IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); - return; -} - -static void ieee80211_beacons_start(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - - ieee->beacon_txing = 1; - ieee80211_send_beacon(ieee); - - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - -static void ieee80211_beacons_stop(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - - ieee->beacon_txing = 0; - del_timer_sync(&ieee->beacon_timer); - - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) -{ - if (ieee->stop_send_beacons) - ieee->stop_send_beacons(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - ieee80211_beacons_stop(ieee); -} - -void ieee80211_start_send_beacons(struct ieee80211_device *ieee) -{ - if (ieee->start_send_beacons) - ieee->start_send_beacons(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - ieee80211_beacons_start(ieee); -} - -static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) -{ - down(&ieee->scan_sem); - - if (ieee->scanning == 1) { - ieee->scanning = 0; - cancel_delayed_work(&ieee->softmac_scan_wq); - } - - up(&ieee->scan_sem); -} - -void ieee80211_stop_scan(struct ieee80211_device *ieee) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee80211_softmac_stop_scan(ieee); - else - ieee->stop_scan(ieee->dev); -} - -/* called with ieee->lock held */ -void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) -{ - if (IS_DOT11D_ENABLE(ieee)) { - if (IS_COUNTRY_IE_VALID(ieee)) - RESET_CIE_WATCHDOG(ieee); - } - - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { - if (ieee->scanning == 0) { - ieee->scanning = 1; -#if 1 - queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0); -#endif - } - }else - ieee->start_scan(ieee->dev); -} - -/* called with wx_sem held */ -void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) -{ - if (IS_DOT11D_ENABLE(ieee)) { - if (IS_COUNTRY_IE_VALID(ieee)) - RESET_CIE_WATCHDOG(ieee); - } - ieee->sync_scan_hurryup = 0; - - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee80211_softmac_scan_syncro(ieee); - else - ieee->scan_syncro(ieee->dev); -} - -inline struct sk_buff * -ieee80211_authentication_req(struct ieee80211_network *beacon, - struct ieee80211_device *ieee, int challengelen) -{ - struct sk_buff *skb; - struct ieee80211_authentication *auth; - - skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen); - - if (!skb) - return NULL; - - auth = (struct ieee80211_authentication *) - skb_put(skb, sizeof(struct ieee80211_authentication)); - - auth->header.frame_ctl = IEEE80211_STYPE_AUTH; - if (challengelen) - auth->header.frame_ctl |= IEEE80211_FCTL_WEP; - - auth->header.duration_id = 0x013a; /* FIXME */ - - memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); - - auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - - auth->transaction = cpu_to_le16(ieee->associate_seq); - ieee->associate_seq++; - - auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); - - return skb; -} - -static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee, - u8 *dest) -{ - u8 *tag; - int beacon_size; - struct ieee80211_probe_response *beacon_buf; - struct sk_buff *skb; - int encrypt; - int atim_len, erp_len; - struct ieee80211_crypt_data *crypt; - - char *ssid = ieee->current_network.ssid; - int ssid_len = ieee->current_network.ssid_len; - int rate_len = ieee->current_network.rates_len+2; - int rate_ex_len = ieee->current_network.rates_ex_len; - int wpa_ie_len = ieee->wpa_ie_len; - if (rate_ex_len > 0) - rate_ex_len += 2; - - if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS) - atim_len = 4; - else - atim_len = 0; - - if (ieee80211_is_54g(&ieee->current_network)) - erp_len = 3; - else - erp_len = 0; - - beacon_size = sizeof(struct ieee80211_probe_response)+ - ssid_len - +3 /* channel */ - +rate_len - +rate_ex_len - +atim_len - +wpa_ie_len - +erp_len; - - skb = dev_alloc_skb(beacon_size); - - if (!skb) - return NULL; - - beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, beacon_size); - - memcpy(beacon_buf->header.addr1, dest, ETH_ALEN); - memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); - - beacon_buf->header.duration_id = 0; /* FIXME */ - beacon_buf->beacon_interval = - cpu_to_le16(ieee->current_network.beacon_interval); - beacon_buf->capability = - cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); - - if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) - beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - crypt = ieee->crypt[ieee->tx_keyidx]; - - encrypt = ieee->host_encrypt && crypt && crypt->ops && - ((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len); - - if (encrypt) - beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - - beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); - - beacon_buf->info_element.id = MFIE_TYPE_SSID; - beacon_buf->info_element.len = ssid_len; - - tag = (u8 *) beacon_buf->info_element.data; - - memcpy(tag, ssid, ssid_len); - - tag += ssid_len; - - *(tag++) = MFIE_TYPE_RATES; - *(tag++) = rate_len - 2; - memcpy(tag, ieee->current_network.rates, rate_len-2); - tag += rate_len - 2; - - *(tag++) = MFIE_TYPE_DS_SET; - *(tag++) = 1; - *(tag++) = ieee->current_network.channel; - - if (atim_len) { - *(tag++) = MFIE_TYPE_IBSS_SET; - *(tag++) = 2; - *((u16 *)(tag)) = cpu_to_le16(ieee->current_network.atim_window); - tag += 2; - } - - if (erp_len) { - *(tag++) = MFIE_TYPE_ERP; - *(tag++) = 1; - *(tag++) = 0; - } - - if (rate_ex_len) { - *(tag++) = MFIE_TYPE_RATES_EX; - *(tag++) = rate_ex_len-2; - memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2); - tag += rate_ex_len - 2; - } - - if (wpa_ie_len) { - if (ieee->iw_mode == IW_MODE_ADHOC) { - /* as Windows will set pairwise key same as the group - * key which is not allowed in Linux, so set this for - * IOT issue. - */ - memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); - } - - memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); - } - skb->dev = ieee->dev; - return skb; -} - -static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee, - u8 *dest) -{ - struct sk_buff *skb; - u8 *tag; - - struct ieee80211_crypt_data *crypt; - struct ieee80211_assoc_response_frame *assoc; - short encrypt; - - unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); - int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - assoc = (struct ieee80211_assoc_response_frame *) - skb_put(skb, sizeof(struct ieee80211_assoc_response_frame)); - - assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); - memcpy(assoc->header.addr1, dest, ETH_ALEN); - memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? - WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); - - if (ieee->short_slot) - assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - if (ieee->host_encrypt) - crypt = ieee->crypt[ieee->tx_keyidx]; - else - crypt = NULL; - - encrypt = (crypt && crypt->ops); - - if (encrypt) - assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - assoc->status = 0; - assoc->aid = cpu_to_le16(ieee->assoc_id); - if (ieee->assoc_id == 0x2007) - ieee->assoc_id = 0; - else - ieee->assoc_id++; - - tag = (u8 *) skb_put(skb, rate_len); - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - - return skb; -} - -static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee, - int status, u8 *dest) -{ - struct sk_buff *skb; - struct ieee80211_authentication *auth; - - skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1); - - if (!skb) - return NULL; - - skb->len = sizeof(struct ieee80211_authentication); - - auth = (struct ieee80211_authentication *)skb->data; - - auth->status = cpu_to_le16(status); - auth->transaction = cpu_to_le16(2); - auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); - - memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr1, dest, ETH_ALEN); - auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); - return skb; -} - -static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, short pwr) -{ - struct sk_buff *skb; - struct ieee80211_hdr_3addr *hdr; - - skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr)); - - if (!skb) - return NULL; - - hdr = (struct ieee80211_hdr_3addr *)skb_put(skb, sizeof(struct ieee80211_hdr_3addr)); - - memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); - - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA | - IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | - (pwr ? IEEE80211_FCTL_PM:0)); - - return skb; -} - -static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest) -{ - struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); - - if (buf) { - softmac_mgmt_xmit(buf, ieee); - dev_kfree_skb_any(buf); - } -} - -static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest) -{ - struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); - - if (buf) { - softmac_mgmt_xmit(buf, ieee); - dev_kfree_skb_any(buf); - } -} - -static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) -{ - struct sk_buff *buf = ieee80211_probe_resp(ieee, dest); - - if (buf) { - softmac_mgmt_xmit(buf, ieee); - dev_kfree_skb_any(buf); - } -} - -inline struct sk_buff * -ieee80211_association_req(struct ieee80211_network *beacon, - struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - - struct ieee80211_assoc_request_frame *hdr; - u8 *tag; - unsigned int wpa_len = beacon->wpa_ie_len; -#if 1 - /* for testing purpose */ - unsigned int rsn_len = beacon->rsn_ie_len; -#endif - unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); - unsigned int wmm_info_len = beacon->QoS_Enable?9:0; - unsigned int turbo_info_len = beacon->Turbo_Enable?9:0; - - u8 encry_proto = ieee->wpax_type_notify & 0xff; - - int len = 0; - - /* [0] Notify type of encryption: WPA/WPA2 - * [1] pair wise type - * [2] authen type - */ - if (ieee->wpax_type_set) { - if (IEEE_PROTO_WPA == encry_proto) { - rsn_len = 0; - } else if (IEEE_PROTO_RSN == encry_proto) { - wpa_len = 0; - } - } - len = sizeof(struct ieee80211_assoc_request_frame)+ - + beacon->ssid_len /* essid tagged val */ - + rate_len /* rates tagged val */ - + wpa_len - + rsn_len - + wmm_info_len - + turbo_info_len; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - hdr = (struct ieee80211_assoc_request_frame *) - skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)); - - hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ; - hdr->header.duration_id = 37; /* FIXME */ - memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); - memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN); /* for HW security */ - - hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS); - if (beacon->capability & WLAN_CAPABILITY_PRIVACY) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); - - if (ieee->short_slot) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - hdr->listen_interval = 0xa; /* FIXME */ - - hdr->info_element.id = MFIE_TYPE_SSID; - - hdr->info_element.len = beacon->ssid_len; - tag = skb_put(skb, beacon->ssid_len); - memcpy(tag, beacon->ssid, beacon->ssid_len); - - tag = skb_put(skb, rate_len); - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - - /* add rsn==0 condition for ap's mix security mode(wpa+wpa2) - * choose AES encryption as default algorithm while using mixed mode. - */ - - tag = skb_put(skb, ieee->wpa_ie_len); - memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); - - tag = skb_put(skb, wmm_info_len); - if (wmm_info_len) - ieee80211_WMM_Info(ieee, &tag); - - tag = skb_put(skb, turbo_info_len); - if (turbo_info_len) - ieee80211_TURBO_Info(ieee, &tag); - - return skb; -} - -void ieee80211_associate_abort(struct ieee80211_device *ieee) -{ - unsigned long flags; - spin_lock_irqsave(&ieee->lock, flags); - - ieee->associate_seq++; - - /* don't scan, and avoid to have the RX path possibly - * try again to associate. Even do not react to AUTH or - * ASSOC response. Just wait for the retry wq to be scheduled. - * Here we will check if there are good nets to associate - * with, so we retry or just get back to NO_LINK and scanning - */ - if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING) { - IEEE80211_DEBUG_MGMT("Authentication failed\n"); - ieee->softmac_stats.no_auth_rs++; - } else { - IEEE80211_DEBUG_MGMT("Association failed\n"); - ieee->softmac_stats.no_ass_rs++; - } - - ieee->state = IEEE80211_ASSOCIATING_RETRY; - - queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, IEEE80211_SOFTMAC_ASSOC_RETRY_TIME); - - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static void ieee80211_associate_abort_cb(unsigned long dev) -{ - ieee80211_associate_abort((struct ieee80211_device *) dev); -} - -static void ieee80211_associate_step1(struct ieee80211_device *ieee) -{ - struct ieee80211_network *beacon = &ieee->current_network; - struct sk_buff *skb; - - IEEE80211_DEBUG_MGMT("Stopping scan\n"); - ieee->softmac_stats.tx_auth_rq++; - skb = ieee80211_authentication_req(beacon, ieee, 0); - if (!skb) { - ieee80211_associate_abort(ieee); - } else { - ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING; - IEEE80211_DEBUG_MGMT("Sending authentication request\n"); - softmac_mgmt_xmit(skb, ieee); - /* BUGON when you try to add_timer twice, using mod_timer may - * be better. - */ - if (!timer_pending(&ieee->associate_timer)) { - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); - } - /* If call dev_kfree_skb_any,a warning will ocur.... - * KERNEL: assertion (!atomic_read(&skb->users)) failed at - * net/core/dev.c (1708) - */ - } -} - -static void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, - int chlen) -{ - u8 *c; - struct sk_buff *skb; - struct ieee80211_network *beacon = &ieee->current_network; - del_timer_sync(&ieee->associate_timer); - ieee->associate_seq++; - ieee->softmac_stats.tx_auth_rq++; - - skb = ieee80211_authentication_req(beacon, ieee, chlen+2); - if (!skb) - ieee80211_associate_abort(ieee); - else { - c = skb_put(skb, chlen+2); - *(c++) = MFIE_TYPE_CHALLENGE; - *(c++) = chlen; - memcpy(c, challenge, chlen); - - IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n"); - - ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr)); - - softmac_mgmt_xmit(skb, ieee); - if (!timer_pending(&ieee->associate_timer)) { - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); - } - dev_kfree_skb_any(skb); - } - kfree(challenge); -} - -static void ieee80211_associate_step2(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_network *beacon = &ieee->current_network; - - del_timer_sync(&ieee->associate_timer); - - IEEE80211_DEBUG_MGMT("Sending association request\n"); - ieee->softmac_stats.tx_ass_rq++; - skb = ieee80211_association_req(beacon, ieee); - if (!skb) - ieee80211_associate_abort(ieee); - else { - softmac_mgmt_xmit(skb, ieee); - if (!timer_pending(&ieee->associate_timer)) { - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); - } - } -} - -static void ieee80211_associate_complete_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); - - printk(KERN_INFO "Associated successfully\n"); - if (ieee80211_is_54g(&ieee->current_network) && - (ieee->modulation & IEEE80211_OFDM_MODULATION)) { - ieee->rate = 540; - printk(KERN_INFO"Using G rates\n"); - } else { - ieee->rate = 110; - printk(KERN_INFO"Using B rates\n"); - } - ieee->link_change(ieee->dev); - notify_wx_assoc_event(ieee); - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - netif_carrier_on(ieee->dev); -} - -static void ieee80211_associate_complete(struct ieee80211_device *ieee) -{ - del_timer_sync(&ieee->associate_timer); - - ieee->state = IEEE80211_LINKED; - IEEE80211_DEBUG_MGMT("Successfully associated\n"); - - queue_work(ieee->wq, &ieee->associate_complete_wq); -} - -static void ieee80211_associate_procedure_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq); - - ieee->sync_scan_hurryup = 1; - down(&ieee->wx_sem); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); - - ieee80211_stop_scan(ieee); - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - ieee->associate_seq = 1; - ieee80211_associate_step1(ieee); - - up(&ieee->wx_sem); -} - -inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, - struct ieee80211_network *net) -{ - u8 tmp_ssid[IW_ESSID_MAX_SIZE+1]; - int tmp_ssid_len = 0; - - short apset, ssidset, ssidbroad, apmatch, ssidmatch; - - /* we are interested in new new only if we are not associated - * and we are not associating / authenticating - */ - if (ieee->state != IEEE80211_NOLINK) - return; - - if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS)) - return; - - if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS)) - return; - - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { - /* if the user specified the AP MAC, we need also the essid - * This could be obtained by beacons or, if the network does not - * broadcast it, it can be put manually. - */ - apset = ieee->wap_set; - ssidset = ieee->ssid_set; - ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0'); - apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0); - - if (ieee->current_network.ssid_len != net->ssid_len) - ssidmatch = 0; - else - ssidmatch = (0 == strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len)); - - /* if the user set the AP check if match. - * if the network does not broadcast essid we check the user - * supplied ANY essid - * if the network does broadcast and the user does not set essid - * it is OK - * if the network does broadcast and the user did set essid - * chech if essid match - * (apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || - * (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) || - * if the ap is not set, check that the user set the bssid and - * the network does broadcast and that those two bssid matches - * (!apset && ssidset && ssidbroad && ssidmatch) - */ - if ((apset && apmatch && ((ssidset && ssidbroad && ssidmatch) || - (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) || - (!apset && ssidset && ssidbroad && ssidmatch)) { - /* if the essid is hidden replace it with the - * essid provided by the user. - */ - if (!ssidbroad) { - strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE); - tmp_ssid_len = ieee->current_network.ssid_len; - } - memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network)); - - if (!ssidbroad) { - strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE); - ieee->current_network.ssid_len = tmp_ssid_len; - } - printk(KERN_INFO"Linking with %s: channel is %d\n", ieee->current_network.ssid, ieee->current_network.channel); - - if (ieee->iw_mode == IW_MODE_INFRA) { - ieee->state = IEEE80211_ASSOCIATING; - ieee->beinretry = false; - queue_work(ieee->wq, &ieee->associate_procedure_wq); - } else { - if (ieee80211_is_54g(&ieee->current_network) && - (ieee->modulation & IEEE80211_OFDM_MODULATION)) { - ieee->rate = 540; - printk(KERN_INFO"Using G rates\n"); - } else { - ieee->rate = 110; - printk(KERN_INFO"Using B rates\n"); - } - ieee->state = IEEE80211_LINKED; - ieee->beinretry = false; - } - } - } -} - -void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) -{ - unsigned long flags; - struct ieee80211_network *target; - - spin_lock_irqsave(&ieee->lock, flags); - list_for_each_entry(target, &ieee->network_list, list) { - /* if the state become different that NOLINK means - * we had found what we are searching for - */ - if (ieee->state != IEEE80211_NOLINK) - break; - - if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) - ieee80211_softmac_new_net(ieee, target); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen) -{ - struct ieee80211_authentication *a; - u8 *t; - if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) { - IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); - return 0xcafe; - } - *challenge = NULL; - a = (struct ieee80211_authentication *) skb->data; - if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) { - t = skb->data + sizeof(struct ieee80211_authentication); - - if (*(t++) == MFIE_TYPE_CHALLENGE) { - *chlen = *(t++); - *challenge = kmemdup(t, *chlen, GFP_ATOMIC); - if (!*challenge) - return -ENOMEM; - } - } - return cpu_to_le16(a->status); -} - -static int auth_rq_parse(struct sk_buff *skb, u8 *dest) -{ - struct ieee80211_authentication *a; - - if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) { - IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len); - return -1; - } - a = (struct ieee80211_authentication *) skb->data; - - memcpy(dest, a->header.addr2, ETH_ALEN); - - if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) - return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; - - return WLAN_STATUS_SUCCESS; -} - -static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, - u8 *src) -{ - u8 *tag; - u8 *skbend; - u8 *ssid = NULL; - u8 ssidlen = 0; - - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *) skb->data; - - if (skb->len < sizeof(struct ieee80211_hdr_3addr)) - return -1; /* corrupted */ - - memcpy(src, header->addr2, ETH_ALEN); - - skbend = (u8 *)skb->data + skb->len; - - tag = skb->data + sizeof(struct ieee80211_hdr_3addr); - - while (tag+1 < skbend) { - if (*tag == 0) { - ssid = tag+2; - ssidlen = *(tag+1); - break; - } - tag++; /* point to the len field */ - tag = tag + *(tag); /* point to the last data byte of the tag */ - tag++; /* point to the next tag */ - } - - if (ssidlen == 0) - return 1; - - if (!ssid) - return 1; /* ssid not found in tagged param */ - - return (!strncmp(ssid, ieee->current_network.ssid, ssidlen)); - -} - -static int assoc_rq_parse(struct sk_buff *skb, u8 *dest) -{ - struct ieee80211_assoc_request_frame *a; - - if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - - sizeof(struct ieee80211_info_element))) { - - IEEE80211_DEBUG_MGMT("invalid len in auth request:%d\n", skb->len); - return -1; - } - - a = (struct ieee80211_assoc_request_frame *) skb->data; - - memcpy(dest, a->header.addr2, ETH_ALEN); - - return 0; -} - -static inline u16 assoc_parse(struct sk_buff *skb, int *aid) -{ - struct ieee80211_assoc_response_frame *a; - if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) { - IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); - return 0xcafe; - } - - a = (struct ieee80211_assoc_response_frame *) skb->data; - *aid = le16_to_cpu(a->aid) & 0x3fff; - return le16_to_cpu(a->status); -} - -static inline void ieee80211_rx_probe_rq(struct ieee80211_device *ieee, - struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - - ieee->softmac_stats.rx_probe_rq++; - if (probe_rq_parse(ieee, skb, dest)) { - ieee->softmac_stats.tx_probe_rs++; - ieee80211_resp_to_probe(ieee, dest); - } -} - -inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee, - struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - int status; - ieee->softmac_stats.rx_auth_rq++; - - status = auth_rq_parse(skb, dest); - if (status != -1) - ieee80211_resp_to_auth(ieee, status, dest); -} - -inline void -ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - - u8 dest[ETH_ALEN]; - - ieee->softmac_stats.rx_ass_rq++; - if (assoc_rq_parse(skb, dest) != -1) - ieee80211_resp_to_assoc_rq(ieee, dest); - - - printk(KERN_INFO"New client associated: %pM\n", dest); -} - -void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) -{ - struct sk_buff *buf = ieee80211_null_func(ieee, pwr); - - if (buf) - softmac_ps_mgmt_xmit(buf, ieee); -} - -static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, - u32 *time_l) -{ - int timeout = 0; - - u8 dtim; - dtim = ieee->current_network.dtim_data; - - if (!(dtim & IEEE80211_DTIM_VALID)) - return 0; - else - timeout = ieee->current_network.beacon_interval; - - ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; - - if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps)) - return 2; - - if (!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) - return 0; - - if (!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) - return 0; - - if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) && - (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) - return 0; - - if (time_l) { - *time_l = ieee->current_network.last_dtim_sta_time[0] - + MSECS((ieee->current_network.beacon_interval)); - } - - if (time_h) { - *time_h = ieee->current_network.last_dtim_sta_time[1]; - if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0]) - *time_h += 1; - } - - return 1; -} - -static inline void ieee80211_sta_ps(struct ieee80211_device *ieee) -{ - - u32 th, tl; - short sleep; - - unsigned long flags, flags2; - - spin_lock_irqsave(&ieee->lock, flags); - - if ((ieee->ps == IEEE80211_PS_DISABLED || - ieee->iw_mode != IW_MODE_INFRA || - ieee->state != IEEE80211_LINKED)) { - - /* #warning CHECK_LOCK_HERE */ - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - ieee80211_sta_wakeup(ieee, 1); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - - sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl); - /* 2 wake, 1 sleep, 0 do nothing */ - if (sleep == 0) - goto out; - - if (sleep == 1) { - if (ieee->sta_sleep == 1) - ieee->enter_sleep_state(ieee->dev, th, tl); - - else if (ieee->sta_sleep == 0) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - if (ieee->ps_is_queue_empty(ieee->dev)) { - ieee->sta_sleep = 2; - - ieee->ps_request_tx_ack(ieee->dev); - - ieee80211_sta_ps_send_null_frame(ieee, 1); - - ieee->ps_th = th; - ieee->ps_tl = tl; - } - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - } else if (sleep == 2) { - /* #warning CHECK_LOCK_HERE */ - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - - ieee80211_sta_wakeup(ieee, 1); - - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } -out: - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) -{ - if (ieee->sta_sleep == 0) { - if (nl) { - ieee->ps_request_tx_ack(ieee->dev); - ieee80211_sta_ps_send_null_frame(ieee, 0); - } - return; - } - - if (ieee->sta_sleep == 1) - ieee->sta_wake_up(ieee->dev); - - ieee->sta_sleep = 0; - - if (nl) { - ieee->ps_request_tx_ack(ieee->dev); - ieee80211_sta_ps_send_null_frame(ieee, 0); - } -} - -void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) -{ - unsigned long flags, flags2; - - spin_lock_irqsave(&ieee->lock, flags); - if (ieee->sta_sleep == 2) { - /* Null frame with PS bit set */ - if (success) { - ieee->sta_sleep = 1; - ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl); - } - /* if the card report not success we can't be sure the AP - * has not RXed so we can't assume the AP believe us awake - */ - } else { - if ((ieee->sta_sleep == 0) && !success) { - spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); - ieee80211_sta_ps_send_null_frame(ieee, 0); - spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); - } - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -inline int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, - u16 type, u16 stype) -{ - struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data; - u16 errcode; - u8 *challenge = NULL; - int chlen = 0; - int aid = 0; - struct ieee80211_assoc_response_frame *assoc_resp; - struct ieee80211_info_element *info_element; - - if (!ieee->proto_started) - return 0; - - if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && - ieee->iw_mode == IW_MODE_INFRA && - ieee->state == IEEE80211_LINKED)) - - tasklet_schedule(&ieee->ps_task); - - if (WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_PROBE_RESP && - WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_BEACON) - ieee->last_rx_ps_time = jiffies; - - switch (WLAN_FC_GET_STYPE(header->frame_control)) { - case IEEE80211_STYPE_ASSOC_RESP: - case IEEE80211_STYPE_REASSOC_RESP: - IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && - ieee->iw_mode == IW_MODE_INFRA) { - errcode = assoc_parse(skb, &aid); - if (0 == errcode) { - u16 left; - - ieee->state = IEEE80211_LINKED; - ieee->assoc_id = aid; - ieee->softmac_stats.rx_ass_ok++; - /* card type is 8187 */ - if (1 == rx_stats->nic_type) - goto associate_complete; - - assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data; - info_element = &assoc_resp->info_element; - left = skb->len - ((void *)info_element - (void *)assoc_resp); - - while (left >= sizeof(struct ieee80211_info_element_hdr)) { - if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) { - printk(KERN_WARNING "[re]associate response error!"); - return 1; - } - switch (info_element->id) { - case MFIE_TYPE_GENERIC: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len); - if (info_element->len >= 8 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x02 && - info_element->data[4] == 0x01) { - /* Not care about version at present. - * WMM Parameter Element. - */ - memcpy(ieee->current_network.wmm_param, (u8 *)(info_element->data\ - + 8), (info_element->len - 8)); - - if (((ieee->current_network.wmm_info^info_element->data[6])& \ - 0x0f) || (!ieee->init_wmmparam_flag)) { - /* refresh parameter element for current network - * update the register parameter for hardware. - */ - ieee->init_wmmparam_flag = 1; - queue_work(ieee->wq, &ieee->wmm_param_update_wq); - } - /* update info_element for current network */ - ieee->current_network.wmm_info = info_element->data[6]; - } - break; - default: - /* nothing to do at present!!! */ - break; - } - - left -= sizeof(struct ieee80211_info_element_hdr) + - info_element->len; - info_element = (struct ieee80211_info_element *) - &info_element->data[info_element->len]; - } - /* legacy AP, reset the AC_xx_param register */ - if (!ieee->init_wmmparam_flag) { - queue_work(ieee->wq, &ieee->wmm_param_update_wq); - ieee->init_wmmparam_flag = 1; /* indicate AC_xx_param upated since last associate */ - } -associate_complete: - ieee80211_associate_complete(ieee); - } else { - ieee->softmac_stats.rx_ass_err++; - IEEE80211_DEBUG_MGMT( - "Association response status code 0x%x\n", - errcode); - ieee80211_associate_abort(ieee); - } - } - break; - case IEEE80211_STYPE_ASSOC_REQ: - case IEEE80211_STYPE_REASSOC_REQ: - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->iw_mode == IW_MODE_MASTER) - - ieee80211_rx_assoc_rq(ieee, skb); - break; - case IEEE80211_STYPE_AUTH: - if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) { - if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING && - ieee->iw_mode == IW_MODE_INFRA){ - IEEE80211_DEBUG_MGMT("Received authentication response"); - - errcode = auth_parse(skb, &challenge, &chlen); - if (0 == errcode) { - if (ieee->open_wep || !challenge) { - ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED; - ieee->softmac_stats.rx_auth_rs_ok++; - - ieee80211_associate_step2(ieee); - } else { - ieee80211_rtl_auth_challenge(ieee, challenge, chlen); - } - } else { - ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x", errcode); - ieee80211_associate_abort(ieee); - } - - } else if (ieee->iw_mode == IW_MODE_MASTER) { - ieee80211_rx_auth_rq(ieee, skb); - } - } - break; - case IEEE80211_STYPE_PROBE_REQ: - if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && - ((ieee->iw_mode == IW_MODE_ADHOC || - ieee->iw_mode == IW_MODE_MASTER) && - ieee->state == IEEE80211_LINKED)) - - ieee80211_rx_probe_rq(ieee, skb); - break; - case IEEE80211_STYPE_DISASSOC: - case IEEE80211_STYPE_DEAUTH: - /* FIXME for now repeat all the association procedure - * both for disassociation and deauthentication - */ - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - (ieee->state == IEEE80211_LINKED) && - (ieee->iw_mode == IW_MODE_INFRA) && - (!memcmp(header->addr2, ieee->current_network.bssid, ETH_ALEN))) { - ieee->state = IEEE80211_ASSOCIATING; - ieee->softmac_stats.reassoc++; - - queue_work(ieee->wq, &ieee->associate_procedure_wq); - } - break; - default: - return -1; - break; - } - return 0; -} - -/* following are for a simpler TX queue management. - * Instead of using netif_[stop/wake]_queue the driver - * will uses these two function (plus a reset one), that - * will internally uses the kernel netif_* and takes - * care of the ieee802.11 fragmentation. - * So the driver receives a fragment per time and might - * call the stop function when it want without take care - * to have enough room to TX an entire packet. - * This might be useful if each fragment need it's own - * descriptor, thus just keep a total free memory > than - * the max fragmentation threshold is not enough.. If the - * ieee802.11 stack passed a TXB struct then you needed - * to keep N free descriptors where - * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD - * In this way you need just one and the 802.11 stack - * will take care of buffering fragments and pass them to - * to the driver later, when it wakes the queue. - */ - -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, - struct ieee80211_device *ieee) -{ - unsigned long flags; - int i; - - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd parm 0, no tx mgmt lock required */ - ieee80211_sta_wakeup(ieee, 0); - - for (i = 0; i < txb->nr_frags; i++) { - if (ieee->queue_stop) { - ieee->tx_pending.txb = txb; - ieee->tx_pending.frag = i; - goto exit; - } else { - ieee->softmac_data_hard_start_xmit( - txb->fragments[i], - ieee->dev, ieee->rate); - ieee->stats.tx_packets++; - ieee->stats.tx_bytes += txb->fragments[i]->len; - ieee->dev->trans_start = jiffies; - } - } - - ieee80211_txb_free(txb); - - exit: - spin_unlock_irqrestore(&ieee->lock, flags); -} - -/* called with ieee->lock acquired */ -static void ieee80211_resume_tx(struct ieee80211_device *ieee) -{ - int i; - for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) { - - if (ieee->queue_stop) { - ieee->tx_pending.frag = i; - return; - } else { - ieee->softmac_data_hard_start_xmit( - ieee->tx_pending.txb->fragments[i], - ieee->dev, ieee->rate); - ieee->stats.tx_packets++; - ieee->dev->trans_start = jiffies; - } - } - - ieee80211_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; -} - -void ieee80211_reset_queue(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - init_mgmt_queue(ieee); - if (ieee->tx_pending.txb) { - ieee80211_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; - } - ieee->queue_stop = 0; - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) -{ - unsigned long flags; - struct sk_buff *skb; - struct ieee80211_hdr_3addr *header; - - spin_lock_irqsave(&ieee->lock, flags); - if (!ieee->queue_stop) - goto exit; - - ieee->queue_stop = 0; - - if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) { - while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) { - header = (struct ieee80211_hdr_3addr *) skb->data; - - header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate); - dev_kfree_skb_any(skb); - } - } - if (!ieee->queue_stop && ieee->tx_pending.txb) - ieee80211_resume_tx(ieee); - - if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) { - ieee->softmac_stats.swtxawake++; - netif_wake_queue(ieee->dev); - } -exit: - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) -{ - if (!netif_queue_stopped(ieee->dev)) { - netif_stop_queue(ieee->dev); - ieee->softmac_stats.swtxstop++; - } - ieee->queue_stop = 1; -} - -inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) -{ - random_ether_addr(ieee->current_network.bssid); -} - -/* called in user context only */ -void ieee80211_start_master_bss(struct ieee80211_device *ieee) -{ - ieee->assoc_id = 1; - - if (ieee->current_network.ssid_len == 0) { - strncpy(ieee->current_network.ssid, - IEEE80211_DEFAULT_TX_ESSID, - IW_ESSID_MAX_SIZE); - - ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); - - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee->dev); - notify_wx_assoc_event(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); -} - -static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) -{ - if (ieee->raw_tx) { - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); - } -} - -static void ieee80211_start_ibss_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); - - /* iwconfig mode ad-hoc will schedule this and return - * on the other hand this will block further iwconfig SET - * operations because of the wx_sem hold. - * Anyway some most set operations set a flag to speed-up - * (abort) this wq (when syncro scanning) before sleeping - * on the semaphore - */ - - down(&ieee->wx_sem); - - if (ieee->current_network.ssid_len == 0) { - strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID); - ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - /* check if we have this cell in our network list */ - ieee80211_softmac_check_all_nets(ieee); - - if (ieee->state == IEEE80211_NOLINK) - ieee->current_network.channel = 10; - /* if not then the state is not linked. Maybe the user switched to - * ad-hoc mode just after being in monitor mode, or just after - * being very few time in managed mode (so the card have had no - * time to scan all the chans..) or we have just run up the iface - * after setting ad-hoc mode. So we have to give another try.. - * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tried to associate when - * we had just checked the ieee->state and we was going to start the - * scan) because in ibss mode the ieee80211_new_net function, when - * finds a good net, just set the ieee->state to IEEE80211_LINKED, - * so, at worst, we waste a bit of time to initiate an unneeded syncro - * scan, that will stop at the first round because it sees the state - * associated. - */ - if (ieee->state == IEEE80211_NOLINK) - ieee80211_start_scan_syncro(ieee); - - /* the network definitively is not here.. create a new cell */ - if (ieee->state == IEEE80211_NOLINK) { - printk("creating new IBSS cell\n"); - if (!ieee->wap_set) - ieee80211_randomize_cell(ieee); - - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - ieee->current_network.rates_len = 4; - - ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; - ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; - ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; - ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; - - } else - ieee->current_network.rates_len = 0; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION) { - ieee->current_network.rates_ex_len = 8; - - ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; - ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; - ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; - ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; - ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; - ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; - ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; - ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; - - ieee->rate = 540; - } else { - ieee->current_network.rates_ex_len = 0; - ieee->rate = 110; - } - - /* By default, WMM function will be disabled in IBSS mode */ - ieee->current_network.QoS_Enable = 0; - - ieee->current_network.atim_window = 0; - ieee->current_network.capability = WLAN_CAPABILITY_IBSS; - if (ieee->short_slot) - ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT; - } - - ieee->state = IEEE80211_LINKED; - ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee->link_change(ieee->dev); - - notify_wx_assoc_event(ieee); - - ieee80211_start_send_beacons(ieee); - printk(KERN_WARNING "after sending beacon packet!\n"); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); - - up(&ieee->wx_sem); -} - -inline void ieee80211_start_ibss(struct ieee80211_device *ieee) -{ - queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100); -} - -/* this is called only in user context, with wx_sem held */ -void ieee80211_start_bss(struct ieee80211_device *ieee) -{ - unsigned long flags; - /* Ref: 802.11d 11.1.3.3 - * STA shall not start a BSS unless properly formed Beacon frame - * including a Country IE. - */ - if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) { - if (!ieee->bGlobalDomain) - return; - } - /* check if we have already found the net we are interested in (if any). - * if not (we are disassociated and we are not - * in associating / authenticating phase) start the background scanning. - */ - ieee80211_softmac_check_all_nets(ieee); - - /* ensure no-one start an associating process (thus setting - * the ieee->state to ieee80211_ASSOCIATING) while we - * have just cheked it and we are going to enable scan. - * The ieee80211_new_net function is always called with - * lock held (from both ieee80211_softmac_check_all_nets and - * the rx path), so we cannot be in the middle of such function - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state == IEEE80211_NOLINK) { - ieee->actscanning = true; - ieee80211_rtl_start_scan(ieee); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -/* called only in userspace context */ -void ieee80211_disassociate(struct ieee80211_device *ieee) -{ - netif_carrier_off(ieee->dev); - - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) - ieee80211_reset_queue(ieee); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); - - if (IS_DOT11D_ENABLE(ieee)) - Dot11d_Reset(ieee); - - ieee->link_change(ieee->dev); - if (ieee->state == IEEE80211_LINKED) - notify_wx_assoc_event(ieee); - ieee->state = IEEE80211_NOLINK; - -} -static void ieee80211_associate_retry_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); - unsigned long flags; - down(&ieee->wx_sem); - if (!ieee->proto_started) - goto exit; - if (ieee->state != IEEE80211_ASSOCIATING_RETRY) - goto exit; - /* until we do not set the state to IEEE80211_NOLINK - * there are no possibility to have someone else trying - * to start an association procedure (we get here with - * ieee->state = IEEE80211_ASSOCIATING). - * When we set the state to IEEE80211_NOLINK it is possible - * that the RX path run an attempt to associate, but - * both ieee80211_softmac_check_all_nets and the - * RX path works with ieee->lock held so there are no - * problems. If we are still disassociated then start a scan. - * the lock here is necessary to ensure no one try to start - * an association procedure when we have just checked the - * state and we are going to start the scan. - */ - ieee->state = IEEE80211_NOLINK; - ieee->beinretry = true; - ieee80211_softmac_check_all_nets(ieee); - - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state == IEEE80211_NOLINK) { - ieee->beinretry = false; - ieee->actscanning = true; - ieee80211_rtl_start_scan(ieee); - } - if (ieee->state == IEEE80211_NOLINK) - notify_wx_assoc_event(ieee); - spin_unlock_irqrestore(&ieee->lock, flags); - -exit: - up(&ieee->wx_sem); -} - -struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee) -{ - u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - - struct sk_buff *skb = NULL; - struct ieee80211_probe_response *b; - - skb = ieee80211_probe_resp(ieee, broadcast_addr); - if (!skb) - return NULL; - - b = (struct ieee80211_probe_response *) skb->data; - b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON); - - return skb; -} - -struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_probe_response *b; - - skb = ieee80211_get_beacon_(ieee); - if (!skb) - return NULL; - - b = (struct ieee80211_probe_response *) skb->data; - b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - return skb; -} - -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee) -{ - ieee->sync_scan_hurryup = 1; - down(&ieee->wx_sem); - ieee80211_stop_protocol(ieee); - up(&ieee->wx_sem); -} - -void ieee80211_stop_protocol(struct ieee80211_device *ieee) -{ - if (!ieee->proto_started) - return; - - ieee->proto_started = 0; - - ieee80211_stop_send_beacons(ieee); - if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_LINKED)) - SendDisassociation(ieee, NULL, WLAN_REASON_DISASSOC_STA_HAS_LEFT); - - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - cancel_delayed_work(&ieee->start_ibss_wq); - ieee80211_stop_scan(ieee); - - ieee80211_disassociate(ieee); -} - -void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) -{ - ieee->sync_scan_hurryup = 0; - down(&ieee->wx_sem); - ieee80211_start_protocol(ieee); - up(&ieee->wx_sem); -} - -void ieee80211_start_protocol(struct ieee80211_device *ieee) -{ - short ch = 0; - int i = 0; - - if (ieee->proto_started) - return; - - ieee->proto_started = 1; - - if (ieee->current_network.channel == 0) { - do { - ch++; - if (ch > MAX_CHANNEL_NUMBER) - return; /* no channel found */ - - } while (!GET_DOT11D_INFO(ieee)->channel_map[ch]); - - ieee->current_network.channel = ch; - } - - if (ieee->current_network.beacon_interval == 0) - ieee->current_network.beacon_interval = 100; - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - ieee->init_wmmparam_flag = 0; /* reinitialize AC_xx_PARAM registers. */ - - /* if the user set the MAC of the ad-hoc cell and then - * switch to managed mode, shall we make sure that association - * attempts does not fail just because the user provide the essid - * and the nic is still checking for the AP MAC ?? - */ - switch (ieee->iw_mode) { - case IW_MODE_AUTO: - ieee->iw_mode = IW_MODE_INFRA; - /* not set break here intentionly */ - case IW_MODE_INFRA: - ieee80211_start_bss(ieee); - break; - - case IW_MODE_ADHOC: - ieee80211_start_ibss(ieee); - break; - - case IW_MODE_MASTER: - ieee80211_start_master_bss(ieee); - break; - - case IW_MODE_MONITOR: - ieee80211_start_monitor_mode(ieee); - break; - - default: - ieee->iw_mode = IW_MODE_INFRA; - ieee80211_start_bss(ieee); - break; - } -} - -#define DRV_NAME "Ieee80211" -void ieee80211_softmac_init(struct ieee80211_device *ieee) -{ - int i; - memset(&ieee->current_network, 0, sizeof(struct ieee80211_network)); - - ieee->state = IEEE80211_NOLINK; - ieee->sync_scan_hurryup = 0; - for (i = 0; i < 5; i++) - ieee->seq_ctrl[i] = 0; - - ieee->assoc_id = 0; - ieee->queue_stop = 0; - ieee->scanning = 0; - ieee->softmac_features = 0; /* so IEEE2100-like driver are happy */ - ieee->wap_set = 0; - ieee->ssid_set = 0; - ieee->proto_started = 0; - ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE; - ieee->rate = 3; - ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST; - ieee->sta_sleep = 0; - ieee->bInactivePs = false; - ieee->actscanning = false; - ieee->ListenInterval = 2; - ieee->NumRxDataInPeriod = 0; - ieee->NumRxBcnInPeriod = 0; - ieee->NumRxOkTotal = 0; - ieee->NumRxUnicast = 0; /* for keep alive */ - ieee->beinretry = false; - ieee->bHwRadioOff = false; - - init_mgmt_queue(ieee); - - ieee->tx_pending.txb = NULL; - - init_timer(&ieee->associate_timer); - ieee->associate_timer.data = (unsigned long)ieee; - ieee->associate_timer.function = ieee80211_associate_abort_cb; - - init_timer(&ieee->beacon_timer); - ieee->beacon_timer.data = (unsigned long) ieee; - ieee->beacon_timer.function = ieee80211_send_beacon_cb; - - ieee->wq = create_workqueue(DRV_NAME); - - INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *) ieee80211_start_ibss_wq); - INIT_WORK(&ieee->associate_complete_wq, (void *) ieee80211_associate_complete_wq); - INIT_WORK(&ieee->associate_procedure_wq, (void *) ieee80211_associate_procedure_wq); - INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *) ieee80211_softmac_scan_wq); - INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *) ieee80211_associate_retry_wq); - INIT_WORK(&ieee->wx_sync_scan_wq, (void *) ieee80211_wx_sync_scan_wq); - - sema_init(&ieee->wx_sem, 1); - sema_init(&ieee->scan_sem, 1); - - spin_lock_init(&ieee->mgmt_tx_lock); - spin_lock_init(&ieee->beacon_lock); - - tasklet_init(&ieee->ps_task, - (void(*)(unsigned long)) ieee80211_sta_ps, - (unsigned long)ieee); - ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); -} - -void ieee80211_softmac_free(struct ieee80211_device *ieee) -{ - down(&ieee->wx_sem); - - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - - /* add for RF power on power of */ - cancel_delayed_work(&ieee->GPIOChangeRFWorkItem); - - destroy_workqueue(ieee->wq); - kfree(ieee->pDot11dInfo); - up(&ieee->wx_sem); -} - -/* Start of WPA code. This is stolen from the ipw2200 driver */ -static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) -{ - /* This is called when wpa_supplicant loads and closes the driver - * interface. */ - printk("%s WPA\n", value ? "enabling" : "disabling"); - ieee->wpa_enabled = value; - return 0; -} - -static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, - int wpa_ie_len) -{ - /* make sure WPA is enabled */ - ieee80211_wpa_enable(ieee, 1); - - ieee80211_disassociate(ieee); -} - -static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, - int reason) -{ - int ret = 0; - - switch (command) { - case IEEE_MLME_STA_DEAUTH: - /* silently ignore */ - break; - - case IEEE_MLME_STA_DISASSOC: - ieee80211_disassociate(ieee); - break; - - default: - printk("Unknown MLME request: %d\n", command); - ret = -EOPNOTSUPP; - } - - return ret; -} - -static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, - struct ieee_param *param, int plen) -{ - u8 *buf; - - if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || - (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) - return -EINVAL; - - if (param->u.wpa_ie.len) { - buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, - GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = param->u.wpa_ie.len; - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - - ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); - return 0; -} - -#define AUTH_ALG_OPEN_SYSTEM 0x1 -#define AUTH_ALG_SHARED_KEY 0x2 - -static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) -{ - struct ieee80211_security sec = { - .flags = SEC_AUTH_MODE, - }; - int ret = 0; - - if (value & AUTH_ALG_SHARED_KEY) { - sec.auth_mode = WLAN_AUTH_SHARED_KEY; - ieee->open_wep = 0; - } else { - sec.auth_mode = WLAN_AUTH_OPEN; - ieee->open_wep = 1; - } - - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - else - ret = -EOPNOTSUPP; - - return ret; -} - -static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, - u32 value) -{ - int ret = 0; - unsigned long flags; - - switch (name) { - case IEEE_PARAM_WPA_ENABLED: - ret = ieee80211_wpa_enable(ieee, value); - break; - - case IEEE_PARAM_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures = value; - break; - - case IEEE_PARAM_DROP_UNENCRYPTED: { - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - struct ieee80211_security sec = { - .flags = SEC_ENABLED, - .enabled = value, - }; - ieee->drop_unencrypted = value; - /* We only change SEC_LEVEL for open mode. Others - * are set by ipw_wpa_set_encryption. - */ - if (!value) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_0; - } else { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - break; - } - - case IEEE_PARAM_PRIVACY_INVOKED: - ieee->privacy_invoked = value; - break; - case IEEE_PARAM_AUTH_ALGS: - ret = ieee80211_wpa_set_auth_algs(ieee, value); - break; - case IEEE_PARAM_IEEE_802_1X: - ieee->ieee802_1x = value; - break; - case IEEE_PARAM_WPAX_SELECT: - spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags); - ieee->wpax_type_set = 1; - ieee->wpax_type_notify = value; - spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags); - break; - default: - printk("Unknown WPA param: %d\n", name); - ret = -EOPNOTSUPP; - } - - return ret; -} - -/* implementation borrowed from hostap driver */ - -static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, - struct ieee_param *param, int param_len) -{ - int ret = 0; - - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - - param->u.crypt.err = 0; - param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - - if (param_len != - (int) ((char *) param->u.crypt.key - (char *) param) + - param->u.crypt.key_len) { - printk("Len mismatch %d, %d\n", param_len, - param->u.crypt.key_len); - return -EINVAL; - } - if (is_broadcast_ether_addr(param->sta_addr)) { - if (param->u.crypt.idx >= WEP_KEYS) - return -EINVAL; - crypt = &ieee->crypt[param->u.crypt.idx]; - } else { - return -EINVAL; - } - - if (strcmp(param->u.crypt.alg, "none") == 0) { - if (crypt) { - sec.enabled = 0; - /* FIXME FIXME */ - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - goto done; - } - sec.enabled = 1; - /* FIXME FIXME */ - sec.flags |= SEC_ENABLED; - - /* IPW HW cannot build TKIP MIC, host decryption still needed. */ - if (!(ieee->host_encrypt || ieee->host_decrypt) && - strcmp(param->u.crypt.alg, "TKIP")) - goto skip_host_crypt; - - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL) { - printk("unknown crypto alg '%s'\n", param->u.crypt.alg); - param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; - ret = -EINVAL; - goto done; - } - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - - new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); - new_crypt->ops = ops; - if (new_crypt->ops) - new_crypt->priv = - new_crypt->ops->init(param->u.crypt.idx); - - if (new_crypt->priv == NULL) { - kfree(new_crypt); - param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; - ret = -EINVAL; - goto done; - } - - *crypt = new_crypt; - } - - if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(param->u.crypt.key, - param->u.crypt.key_len, param->u.crypt.seq, - (*crypt)->priv) < 0) { - printk("key setting failed\n"); - param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; - ret = -EINVAL; - goto done; - } - - skip_host_crypt: - if (param->u.crypt.set_tx) { - ieee->tx_keyidx = param->u.crypt.idx; - sec.active_key = param->u.crypt.idx; - sec.flags |= SEC_ACTIVE_KEY; - } else - sec.flags &= ~SEC_ACTIVE_KEY; - - if (param->u.crypt.alg != NULL) { - memcpy(sec.keys[param->u.crypt.idx], - param->u.crypt.key, - param->u.crypt.key_len); - sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; - sec.flags |= (1 << param->u.crypt.idx); - - if (strcmp(param->u.crypt.alg, "WEP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - } - done: - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && - ieee->reset_port(ieee->dev)) { - printk("reset_port failed\n"); - param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; - return -EINVAL; - } - - return ret; -} - -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, - struct iw_point *p) -{ - struct ieee_param *param; - int ret = 0; - - down(&ieee->wx_sem); - - if (p->length < sizeof(struct ieee_param) || !p->pointer) { - ret = -EINVAL; - goto out; - } - - param = memdup_user(p->pointer, p->length); - if (IS_ERR(param)) { - ret = PTR_ERR(param); - goto out; - } - - switch (param->cmd) { - case IEEE_CMD_SET_WPA_PARAM: - ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name, - param->u.wpa_param.value); - break; - case IEEE_CMD_SET_WPA_IE: - ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length); - break; - case IEEE_CMD_SET_ENCRYPTION: - ret = ieee80211_wpa_set_encryption(ieee, param, p->length); - break; - case IEEE_CMD_MLME: - ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command, - param->u.mlme.reason_code); - break; - default: - printk("Unknown WPA supplicant request: %d\n", param->cmd); - ret = -EOPNOTSUPP; - break; - } - - if (ret == 0 && copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - - kfree(param); -out: - up(&ieee->wx_sem); - - return ret; -} - -void notify_wx_assoc_event(struct ieee80211_device *ieee) -{ - union iwreq_data wrqu; - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - if (ieee->state == IEEE80211_LINKED) - memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); - else - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c deleted file mode 100644 index 46f35644126c..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c +++ /dev/null @@ -1,567 +0,0 @@ -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Some pieces of code might be stolen from ipw2100 driver - * copyright of who own it's copyright ;-) - * - * PS wx handler mostly stolen from hostap, copyright who - * own it's copyright ;-) - * - * released under the GPL - */ - - -#include - -#include "ieee80211.h" - -/* FIXME: add A freqs */ - -const long ieee80211_wlan_frequencies[] = { - 2412, 2417, 2422, 2427, - 2432, 2437, 2442, 2447, - 2452, 2457, 2462, 2467, - 2472, 2484 -}; - - -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *b) -{ - int ret; - struct iw_freq *fwrq = &wrqu->freq; -// printk("in %s\n",__func__); - down(&ieee->wx_sem); - - if (ieee->iw_mode == IW_MODE_INFRA) { - ret = -EOPNOTSUPP; - goto out; - } - - /* if setting by freq convert to channel */ - if (fwrq->e == 1) { - if ((fwrq->m >= (int) 2.412e8 && - fwrq->m <= (int) 2.487e8)) { - int f = fwrq->m / 100000; - int c = 0; - - while ((c < 14) && (f != ieee80211_wlan_frequencies[c])) - c++; - - /* hack to fall through */ - fwrq->e = 0; - fwrq->m = c + 1; - } - } - - if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) { - ret = -EOPNOTSUPP; - goto out; - - } else { /* Set the channel */ - - - ieee->current_network.channel = fwrq->m; - ieee->set_chan(ieee->dev, ieee->current_network.channel); - - if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) - if (ieee->state == IEEE80211_LINKED) { - ieee80211_stop_send_beacons(ieee); - ieee80211_start_send_beacons(ieee); - } - } - - ret = 0; -out: - up(&ieee->wx_sem); - return ret; -} - - -int ieee80211_wx_get_freq(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *b) -{ - struct iw_freq *fwrq = &wrqu->freq; - - if (ieee->current_network.channel == 0) - return -1; - - fwrq->m = ieee->current_network.channel; - fwrq->e = 0; - - return 0; -} - -int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - unsigned long flags; - - wrqu->ap_addr.sa_family = ARPHRD_ETHER; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - /* We want avoid to give to the user inconsistent infos*/ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state != IEEE80211_LINKED && - ieee->state != IEEE80211_LINKED_SCANNING && - ieee->wap_set == 0) - - memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); - else - memcpy(wrqu->ap_addr.sa_data, - ieee->current_network.bssid, ETH_ALEN); - - spin_unlock_irqrestore(&ieee->lock, flags); - - return 0; -} - - -int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *awrq, - char *extra) -{ - - int ret = 0; - unsigned long flags; - - short ifup = ieee->proto_started;//dev->flags & IFF_UP; - struct sockaddr *temp = (struct sockaddr *)awrq; - - //printk("=======Set WAP:"); - ieee->sync_scan_hurryup = 1; - - down(&ieee->wx_sem); - /* use ifconfig hw ether */ - if (ieee->iw_mode == IW_MODE_MASTER) { - ret = -1; - goto out; - } - - if (temp->sa_family != ARPHRD_ETHER) { - ret = -EINVAL; - goto out; - } - - if (ifup) - ieee80211_stop_protocol(ieee); - - /* just to avoid to give inconsistent infos in the - * get wx method. not really needed otherwise - */ - spin_lock_irqsave(&ieee->lock, flags); - - memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); - ieee->wap_set = !is_zero_ether_addr(temp->sa_data); - //printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]); - - spin_unlock_irqrestore(&ieee->lock, flags); - - if (ifup) - ieee80211_start_protocol(ieee); - -out: - up(&ieee->wx_sem); - return ret; -} - -int ieee80211_wx_get_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *b) -{ - int len, ret = 0; - unsigned long flags; - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - /* We want avoid to give to the user inconsistent infos*/ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->current_network.ssid[0] == '\0' || - ieee->current_network.ssid_len == 0){ - ret = -1; - goto out; - } - - if (ieee->state != IEEE80211_LINKED && - ieee->state != IEEE80211_LINKED_SCANNING && - ieee->ssid_set == 0){ - ret = -1; - goto out; - } - len = ieee->current_network.ssid_len; - wrqu->essid.length = len; - strncpy(b, ieee->current_network.ssid, len); - wrqu->essid.flags = 1; - -out: - spin_unlock_irqrestore(&ieee->lock, flags); - - return ret; - -} - -int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - - u32 target_rate = wrqu->bitrate.value; - - //added by lizhaoming for auto mode - if (target_rate == -1) - ieee->rate = 110; - else - ieee->rate = target_rate/100000; - - //FIXME: we might want to limit rate also in management protocols. - return 0; -} - - - -int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - - wrqu->bitrate.value = ieee->rate * 100000; - - return 0; -} - -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *b) -{ - - ieee->sync_scan_hurryup = 1; - - down(&ieee->wx_sem); - - if (wrqu->mode == ieee->iw_mode) - goto out; - - if (wrqu->mode == IW_MODE_MONITOR) - ieee->dev->type = ARPHRD_IEEE80211; - else - ieee->dev->type = ARPHRD_ETHER; - - if (!ieee->proto_started) { - ieee->iw_mode = wrqu->mode; - } else { - ieee80211_stop_protocol(ieee); - ieee->iw_mode = wrqu->mode; - ieee80211_start_protocol(ieee); - } - -out: - up(&ieee->wx_sem); - return 0; -} - - -void ieee80211_wx_sync_scan_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); - short chan; - - chan = ieee->current_network.channel; - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee->dev); - - ieee80211_stop_send_beacons(ieee); - - ieee->state = IEEE80211_LINKED_SCANNING; - ieee->link_change(ieee->dev); - - ieee80211_start_scan_syncro(ieee); - - ieee->set_chan(ieee->dev, chan); - - ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee->dev); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) - ieee80211_start_send_beacons(ieee); - - //YJ,add,080828, In prevent of lossing ping packet during scanning - //ieee80211_sta_ps_send_null_frame(ieee, false); - //YJ,add,080828,end - - up(&ieee->wx_sem); - -} - -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *b) -{ - int ret = 0; - - down(&ieee->wx_sem); - - if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) { - ret = -1; - goto out; - } - //YJ,add,080828 - //In prevent of lossing ping packet during scanning - //ieee80211_sta_ps_send_null_frame(ieee, true); - //YJ,add,080828,end - - if (ieee->state == IEEE80211_LINKED) { - queue_work(ieee->wq, &ieee->wx_sync_scan_wq); - /* intentionally forget to up sem */ - return 0; - } - -out: - up(&ieee->wx_sem); - return ret; -} - -int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *extra) -{ - - int ret = 0, len; - short proto_started; - unsigned long flags; - - ieee->sync_scan_hurryup = 1; - - down(&ieee->wx_sem); - - proto_started = ieee->proto_started; - - if (wrqu->essid.length > IW_ESSID_MAX_SIZE) { - ret = -E2BIG; - goto out; - } - - if (ieee->iw_mode == IW_MODE_MONITOR) { - ret = -1; - goto out; - } - - if (proto_started) - ieee80211_stop_protocol(ieee); - - /* this is just to be sure that the GET wx callback - * has consistent infos. not needed otherwise - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (wrqu->essid.flags && wrqu->essid.length) { -//YJ,modified,080819 - len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE; - memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819 - strncpy(ieee->current_network.ssid, extra, len); - ieee->current_network.ssid_len = len; - ieee->ssid_set = 1; -//YJ,modified,080819,end - - //YJ,add,080819,for hidden ap - if (len == 0) { - memset(ieee->current_network.bssid, 0, ETH_ALEN); - ieee->current_network.capability = 0; - } - //YJ,add,080819,for hidden ap,end - } else { - ieee->ssid_set = 0; - ieee->current_network.ssid[0] = '\0'; - ieee->current_network.ssid_len = 0; - } - //printk("==========set essid %s!\n",ieee->current_network.ssid); - spin_unlock_irqrestore(&ieee->lock, flags); - - if (proto_started) - ieee80211_start_protocol(ieee); -out: - up(&ieee->wx_sem); - return ret; -} - -int ieee80211_wx_get_mode(struct ieee80211_device *ieee, - struct iw_request_info *a, union iwreq_data *wrqu, - char *b) -{ - - wrqu->mode = ieee->iw_mode; - return 0; -} - -int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - - int *parms = (int *)extra; - int enable = (parms[0] > 0); - short prev = ieee->raw_tx; - - down(&ieee->wx_sem); - - if (enable) - ieee->raw_tx = 1; - else - ieee->raw_tx = 0; - - netdev_info(ieee->dev, "raw TX is %s\n", - ieee->raw_tx ? "enabled" : "disabled"); - - if (ieee->iw_mode == IW_MODE_MONITOR) { - if (prev == 0 && ieee->raw_tx) { - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee->dev); - - netif_carrier_on(ieee->dev); - } - - if (prev && ieee->raw_tx == 1) - netif_carrier_off(ieee->dev); - } - - up(&ieee->wx_sem); - - return 0; -} - -int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - strlcpy(wrqu->name, "802.11", IFNAMSIZ); - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - strlcat(wrqu->name, "b", IFNAMSIZ); - if (ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "/g", IFNAMSIZ); - } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) - strlcat(wrqu->name, "g", IFNAMSIZ); - - if ((ieee->state == IEEE80211_LINKED) || - (ieee->state == IEEE80211_LINKED_SCANNING)) - strlcat(wrqu->name, " link", IFNAMSIZ); - else if (ieee->state != IEEE80211_NOLINK) - strlcat(wrqu->name, " .....", IFNAMSIZ); - - - return 0; -} - - -/* this is mostly stolen from hostap */ -int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - int ret = 0; - - if ((!ieee->sta_wake_up) || - (!ieee->ps_request_tx_ack) || - (!ieee->enter_sleep_state) || - (!ieee->ps_is_queue_empty)) { - - printk("ERROR. PS mode tried to be use but driver missed a callback\n\n"); - - return -1; - } - - down(&ieee->wx_sem); - - if (wrqu->power.disabled) { - ieee->ps = IEEE80211_PS_DISABLED; - - goto exit; - } - switch (wrqu->power.flags & IW_POWER_MODE) { - case IW_POWER_UNICAST_R: - ieee->ps = IEEE80211_PS_UNICAST; - - break; - case IW_POWER_ALL_R: - ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; - break; - - case IW_POWER_ON: - ieee->ps = IEEE80211_PS_DISABLED; - break; - - default: - ret = -EINVAL; - goto exit; - } - - if (wrqu->power.flags & IW_POWER_TIMEOUT) { - - ieee->ps_timeout = wrqu->power.value / 1000; - printk("Timeout %d\n", ieee->ps_timeout); - } - - if (wrqu->power.flags & IW_POWER_PERIOD) { - - ret = -EOPNOTSUPP; - goto exit; - //wrq->value / 1024; - - } -exit: - up(&ieee->wx_sem); - return ret; - -} - -/* this is stolen from hostap */ -int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *extra) -{ - int ret = 0; - - down(&ieee->wx_sem); - - if (ieee->ps == IEEE80211_PS_DISABLED) { - wrqu->power.disabled = 1; - goto exit; - } - - wrqu->power.disabled = 0; - -// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { - wrqu->power.flags = IW_POWER_TIMEOUT; - wrqu->power.value = ieee->ps_timeout * 1000; -// } else { -// ret = -EOPNOTSUPP; -// goto exit; - //wrqu->power.flags = IW_POWER_PERIOD; - //wrqu->power.value = ieee->current_network.dtim_period * - // ieee->current_network.beacon_interval * 1024; -// } - - - if (ieee->ps & IEEE80211_PS_MBCAST) - wrqu->power.flags |= IW_POWER_ALL_R; - else - wrqu->power.flags |= IW_POWER_UNICAST_R; - -exit: - up(&ieee->wx_sem); - return ret; - -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c deleted file mode 100644 index 0dc5ae414270..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c +++ /dev/null @@ -1,591 +0,0 @@ -/****************************************************************************** - - Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. - - 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. - - 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., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -****************************************************************************** - - Few modifications for Realtek's Wi-Fi drivers by - Andrea Merello - - A special thanks goes to Realtek for their support ! - -******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ieee80211.h" - - -/* - - -802.11 Data Frame - - -802.11 frame_contorl for data frames - 2 bytes - ,-----------------------------------------------------------------------------------------. -bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | - |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| -val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | - |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| -desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | - | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | - '-----------------------------------------------------------------------------------------' - /\ - | -802.11 Data Frame | - ,--------- 'ctrl' expands to >-----------' - | - ,--'---,-------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `--------------------------------------------------| |------' -Total: 28 non-data bytes `----.----' - | - .- 'Frame data' expands to <---------------------------' - | - V - ,---------------------------------------------------. -Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | - |------|------|---------|----------|------|---------| -Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | - | DSAP | SSAP | | | | Packet | - | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - `-----------------------------------------| | -Total: 8 non-data bytes `----.----' - | - .- 'IP Packet' expands, if WEP enabled, to <--' - | - V - ,-----------------------. -Bytes | 4 | 0-2296 | 4 | - |-----|-----------|-----| -Desc. | IV | Encrypted | ICV | - | | IP Packet | | - `-----------------------' -Total: 8 non-data bytes - - -802.3 Ethernet Data Frame - - ,-----------------------------------------. -Bytes | 6 | 6 | 2 | Variable | 4 | - |-------|-------|------|-----------|------| -Desc. | Dest. | Source| Type | IP Packet | fcs | - | MAC | MAC | | | | - `-----------------------------------------' -Total: 18 non-data bytes - -In the event that fragmentation is required, the incoming payload is split into -N parts of size ieee->fts. The first fragment contains the SNAP header and the -remaining packets are just data. - -If encryption is enabled, each fragment payload size is reduced by enough space -to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) -So if you have 1500 bytes of payload with ieee->fts set to 500 without -encryption it will take 3 frames. With WEP it will take 4 frames as the -payload of each frame is reduced to 492 bytes. - -* SKB visualization -* -* ,- skb->data -* | -* | ETHERNET HEADER ,-<-- PAYLOAD -* | | 14 bytes from skb->data -* | 2 bytes for Type --> ,T. | (sizeof ethhdr) -* | | | | -* |,-Dest.--. ,--Src.---. | | | -* | 6 bytes| | 6 bytes | | | | -* v | | | | | | -* 0 | v 1 | v | v 2 -* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -* ^ | ^ | ^ | -* | | | | | | -* | | | | `T' <---- 2 bytes for Type -* | | | | -* | | '---SNAP--' <-------- 6 bytes for SNAP -* | | -* `-IV--' <-------------------- 4 bytes for IV (WEP) -* -* SNAP HEADER -* -*/ - -static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; -static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; - -static inline int ieee80211_put_snap(u8 *data, u16 h_proto) -{ - struct ieee80211_snap_hdr *snap; - u8 *oui; - - snap = (struct ieee80211_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - - *(u16 *)(data + SNAP_SIZE) = htons(h_proto); - - return SNAP_SIZE + sizeof(u16); -} - -int ieee80211_encrypt_fragment(struct ieee80211_device *ieee, - struct sk_buff *frag, int hdr_len) -{ - struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx]; - int res; - - /* - * added to care about null crypt condition, to solve that system hangs - * when shared keys error - */ - if (!crypt || !crypt->ops) - return -1; - -#ifdef CONFIG_IEEE80211_CRYPT_TKIP - struct ieee80211_hdr_4addr *header; - - if (ieee->tkip_countermeasures && - crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { - header = (struct ieee80211_hdr_4addr *)frag->data; - if (net_ratelimit()) { - netdev_dbg(ieee->dev, "TKIP countermeasures: dropped " - "TX packet to %pM\n", header->addr1); - } - return -1; - } -#endif - /* - * To encrypt, frame format is: - * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) - * - * PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU - * encryption. - * - * Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. - */ - atomic_inc(&crypt->refcnt); - res = 0; - if (crypt->ops->encrypt_msdu) - res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); - if (res == 0 && crypt->ops->encrypt_mpdu) - res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); - - atomic_dec(&crypt->refcnt); - if (res < 0) { - netdev_info(ieee->dev, "Encryption failed: len=%d.\n", frag->len); - ieee->ieee_stats.tx_discards++; - return -1; - } - - return 0; -} - - -void ieee80211_txb_free(struct ieee80211_txb *txb) -{ - int i; - if (unlikely(!txb)) - return; - for (i = 0; i < txb->nr_frags; i++) - if (txb->fragments[i]) - dev_kfree_skb_any(txb->fragments[i]); - kfree(txb); -} - -static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, - gfp_t gfp_mask) -{ - struct ieee80211_txb *txb; - int i; - txb = kmalloc( - sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags), - gfp_mask); - if (!txb) - return NULL; - - memset(txb, 0, sizeof(struct ieee80211_txb)); - txb->nr_frags = nr_frags; - txb->frag_size = txb_size; - - for (i = 0; i < nr_frags; i++) { - txb->fragments[i] = dev_alloc_skb(txb_size); - if (unlikely(!txb->fragments[i])) { - i--; - break; - } - } - if (unlikely(i != nr_frags)) { - while (i >= 0) - dev_kfree_skb_any(txb->fragments[i--]); - kfree(txb); - return NULL; - } - return txb; -} - -/* - * Classify the to-be send data packet - * Need to acquire the sent queue index. - */ -static int ieee80211_classify(struct sk_buff *skb, - struct ieee80211_network *network) -{ - struct ether_header *eh = (struct ether_header *)skb->data; - unsigned int wme_UP = 0; - - if (!network->QoS_Enable) { - skb->priority = 0; - return(wme_UP); - } - - if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) { - const struct iphdr *ih = (struct iphdr *)(skb->data + - sizeof(struct ether_header)); - wme_UP = (ih->tos >> 5)&0x07; - } else if (vlan_tx_tag_present(skb)) {/* vtag packet */ -#ifndef VLAN_PRI_SHIFT -#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */ -#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */ -#endif - u32 tag = vlan_tx_tag_get(skb); - wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; - } else if (ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) { - wme_UP = 7; - } - - skb->priority = wme_UP; - return(wme_UP); -} - -/* SKBs are added to the ieee->tx_queue. */ -int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - struct ieee80211_txb *txb = NULL; - struct ieee80211_hdr_3addrqos *frag_hdr; - int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; - unsigned long flags; - struct net_device_stats *stats = &ieee->stats; - int ether_type, encrypt; - int bytes, fc, qos_ctl, hdr_len; - struct sk_buff *skb_frag; - struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */ - .duration_id = 0, - .seq_ctl = 0, - .qos_ctl = 0 - }; - u8 dest[ETH_ALEN], src[ETH_ALEN]; - - struct ieee80211_crypt_data* crypt; - - spin_lock_irqsave(&ieee->lock, flags); - - /* - * If there is no driver handler to take the TXB, don't bother - * creating it... - */ - if ((!ieee->hard_start_xmit && - !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) || - ((!ieee->softmac_data_hard_start_xmit && - (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { - netdev_warn(ieee->dev, "No xmit handler.\n"); - goto success; - } - - ieee80211_classify(skb,&ieee->current_network); - if (likely(ieee->raw_tx == 0)){ - - if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len); - goto success; - } - - ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); - - crypt = ieee->crypt[ieee->tx_keyidx]; - - encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && - ieee->host_encrypt && crypt && crypt->ops; - - if (!encrypt && ieee->ieee802_1x && - ieee->drop_unencrypted && ether_type != ETH_P_PAE) { - stats->tx_dropped++; - goto success; - } - - #ifdef CONFIG_IEEE80211_DEBUG - if (crypt && !encrypt && ether_type == ETH_P_PAE) { - struct eapol *eap = (struct eapol *)(skb->data + - sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); - IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", - eap_get_type(eap->type)); - } - #endif - - /* Save source and destination addresses */ - memcpy(&dest, skb->data, ETH_ALEN); - memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); - - /* Advance the SKB to the start of the payload */ - skb_pull(skb, sizeof(struct ethhdr)); - - /* Determine total amount of storage required for TXB packets */ - bytes = skb->len + SNAP_SIZE + sizeof(u16); - - if (ieee->current_network.QoS_Enable) { - if (encrypt) - fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA | - IEEE80211_FCTL_WEP; - else - fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA; - - } else { - if (encrypt) - fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | - IEEE80211_FCTL_WEP; - else - fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; - } - - if (ieee->iw_mode == IW_MODE_INFRA) { - fc |= IEEE80211_FCTL_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */ - memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(&header.addr2, &src, ETH_ALEN); - memcpy(&header.addr3, &dest, ETH_ALEN); - } else if (ieee->iw_mode == IW_MODE_ADHOC) { - /* - * not From/To DS: Addr1 = DA, Addr2 = SA, - * Addr3 = BSSID - */ - memcpy(&header.addr1, dest, ETH_ALEN); - memcpy(&header.addr2, src, ETH_ALEN); - memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); - } - header.frame_ctl = cpu_to_le16(fc); - - /* - * Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) - */ - if (is_multicast_ether_addr(header.addr1)) { - frag_size = MAX_FRAG_THRESHOLD; - qos_ctl = QOS_CTL_NOTCONTAIN_ACK; - } else { - /* default:392 */ - frag_size = ieee->fts; - qos_ctl = 0; - } - - if (ieee->current_network.QoS_Enable) { - hdr_len = IEEE80211_3ADDR_LEN + 2; - /* skb->priority is set in the ieee80211_classify() */ - qos_ctl |= skb->priority; - header.qos_ctl = cpu_to_le16(qos_ctl); - } else { - hdr_len = IEEE80211_3ADDR_LEN; - } - - /* - * Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account - * for it when determining the amount of payload space. - */ - bytes_per_frag = frag_size - hdr_len; - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - bytes_per_frag -= IEEE80211_FCS_LEN; - - /* Each fragment may need to have room for encryption pre/postfix */ - if (encrypt) - bytes_per_frag -= crypt->ops->extra_prefix_len + - crypt->ops->extra_postfix_len; - - /* - * Number of fragments is the total bytes_per_frag / - * payload_per_fragment - */ - nr_frags = bytes / bytes_per_frag; - bytes_last_frag = bytes % bytes_per_frag; - if (bytes_last_frag) - nr_frags++; - else - bytes_last_frag = bytes_per_frag; - - /* - * When we allocate the TXB we allocate enough space for the - * reserve and full fragment bytes (bytes_per_frag doesn't - * include prefix, postfix, header, FCS, etc.) - */ - txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC); - if (unlikely(!txb)) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); - goto failed; - } - txb->encrypted = encrypt; - txb->payload_size = bytes; - - for (i = 0; i < nr_frags; i++) { - skb_frag = txb->fragments[i]; - skb_frag->priority = UP2AC(skb->priority); - if (encrypt) - skb_reserve(skb_frag, crypt->ops->extra_prefix_len); - - frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put( - skb_frag, hdr_len); - memcpy(frag_hdr, &header, hdr_len); - - /* - * If this is not the last fragment, then add the MOREFRAGS - * bit to the frame control - */ - if (i != nr_frags - 1) { - frag_hdr->frame_ctl = cpu_to_le16( - fc | IEEE80211_FCTL_MOREFRAGS); - bytes = bytes_per_frag; - - } else { - /* The last fragment takes the remaining length */ - bytes = bytes_last_frag; - } - if (ieee->current_network.QoS_Enable) { - /* - * add 1 only indicate to corresponding seq - * number control 2006/7/12 - */ - frag_hdr->seq_ctl = cpu_to_le16( - ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i); - } else { - frag_hdr->seq_ctl = cpu_to_le16( - ieee->seq_ctrl[0]<<4 | i); - } - - /* Put a SNAP header on the first fragment */ - if (i == 0) { - ieee80211_put_snap( - skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), - ether_type); - bytes -= SNAP_SIZE + sizeof(u16); - } - - memcpy(skb_put(skb_frag, bytes), skb->data, bytes); - - /* Advance the SKB... */ - skb_pull(skb, bytes); - - /* - * Encryption routine will move the header forward in - * order to insert the IV between the header and the - * payload - */ - if (encrypt) - ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - skb_put(skb_frag, 4); - } - /* Advance sequence number in data frame. */ - if (ieee->current_network.QoS_Enable) { - if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) - ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; - else - ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; - } else { - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - } else { - if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) { - netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len); - goto success; - } - - txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC); - if (!txb) { - netdev_warn(ieee->dev, "Could not allocate TXB\n"); - goto failed; - } - - txb->encrypted = 0; - txb->payload_size = skb->len; - memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len); - } - - success: - spin_unlock_irqrestore(&ieee->lock, flags); - dev_kfree_skb_any(skb); - if (txb) { - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { - ieee80211_softmac_xmit(txb, ieee); - } else { - if ((*ieee->hard_start_xmit)(txb, dev) == 0) { - stats->tx_packets++; - stats->tx_bytes += txb->payload_size; - return NETDEV_TX_OK; - } - ieee80211_txb_free(txb); - } - } - - return NETDEV_TX_OK; - - failed: - spin_unlock_irqrestore(&ieee->lock, flags); - netif_stop_queue(dev); - stats->tx_errors++; - return NETDEV_TX_BUSY; - -} diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c deleted file mode 100644 index 07c3f715a6f5..000000000000 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Copyright(c) 2004 Intel Corporation. All rights reserved. - * - * Portions of this file are based on the WEP enablement code provided by the - * Host AP project hostap-drivers v0.1.3 - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * - * Copyright (c) 2002-2003, Jouni Malinen - * - * 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. - * - * 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., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * James P. Ketrenos - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - */ - -#include -#include -#include -#include -#include - -#include "ieee80211.h" -static const char *ieee80211_modes[] = { - "?", "a", "b", "ab", "g", "ag", "bg", "abg" -}; - -#define MAX_CUSTOM_LEN 64 -static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee, - char *start, char *stop, - struct ieee80211_network *network, - struct iw_request_info *info) -{ - char custom[MAX_CUSTOM_LEN]; - char *p; - struct iw_event iwe; - int i, j; - u8 max_rate, rate; - - /* First entry *MUST* be the AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); - - /* Remaining entries will be displayed in the order we provide them */ - - /* Add the ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; - if (network->ssid_len == 0) { - iwe.u.data.length = sizeof(""); - start = iwe_stream_add_point(info, start, stop, &iwe, ""); - } else { - iwe.u.data.length = min_t(u8, network->ssid_len, 32); - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - } - /* Add the protocol name */ - iwe.cmd = SIOCGIWNAME; - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]); - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN); - - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - if (network->capability & - (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) { - if (network->capability & WLAN_CAPABILITY_BSS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); - } - - /* Add frequency/channel */ - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = network->channel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); - - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (network->capability & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - - /* Add basic and extended rates */ - max_rate = 0; - p = custom; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); - for (i = 0, j = 0; i < network->rates_len; ) { - if (j < network->rates_ex_len && - ((network->rates_ex[j] & 0x7F) < - (network->rates[i] & 0x7F))) - rate = network->rates_ex[j++] & 0x7F; - else - rate = network->rates[i++] & 0x7F; - if (rate > max_rate) - max_rate = rate; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - } - for (; j < network->rates_ex_len; j++) { - rate = network->rates_ex[j] & 0x7F; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - if (rate > max_rate) - max_rate = rate; - } - - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = max_rate * 500000; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN); - - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - /* Add quality statistics */ - /* TODO: Fix these values... */ - if (network->stats.signal == 0 || network->stats.rssi == 0) - netdev_info(ieee->dev, "========>signal:%d, rssi:%d\n", - network->stats.signal, network->stats.rssi); - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = network->stats.signalstrength; - iwe.u.qual.level = network->stats.signal; - iwe.u.qual.noise = network->stats.noise; - iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK; - if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) - iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; - if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) - iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; - if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) - iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; - iwe.u.qual.updated = 7; - start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); - - iwe.cmd = IWEVCUSTOM; - p = custom; - - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - memset(&iwe, 0, sizeof(iwe)); - if (network->wpa_ie_len) { - char buf[MAX_WPA_IE_LEN]; - memcpy(buf, network->wpa_ie, network->wpa_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->wpa_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - memset(&iwe, 0, sizeof(iwe)); - if (network->rsn_ie_len) { - char buf[MAX_WPA_IE_LEN]; - memcpy(buf, network->rsn_ie, network->rsn_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->rsn_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - /* Add EXTRA: Age to display seconds since last beacon/probe response - * for given network. - */ - iwe.cmd = IWEVCUSTOM; - p = custom; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100)); - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - return start; -} - -int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct ieee80211_network *network; - unsigned long flags; - int err = 0; - char *ev = extra; - char *stop = ev + wrqu->data.length; - int i = 0; - - IEEE80211_DEBUG_WX("Getting scan\n"); - down(&ieee->wx_sem); - spin_lock_irqsave(&ieee->lock, flags); - - if (!ieee->bHwRadioOff) { - list_for_each_entry(network, &ieee->network_list, list) { - i++; - - if ((stop-ev) < 200) { - err = -E2BIG; - break; - } - if (ieee->scan_age == 0 || - time_after(network->last_scanned + ieee->scan_age, jiffies)) { - ev = rtl818x_translate_scan(ieee, ev, stop, network, info); - } else - IEEE80211_DEBUG_SCAN( - "Not showing network '%s (" - "%pM)' due to age (%lums).\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid, - (jiffies - network->last_scanned) / (HZ / 100)); - } - } - spin_unlock_irqrestore(&ieee->lock, flags); - up(&ieee->wx_sem); - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; - IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i); - - return err; -} - -int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &(wrqu->encoding); - struct net_device *dev = ieee->dev; - struct ieee80211_security sec = { - .flags = 0 - }; - int i, key, key_provided, len; - struct ieee80211_crypt_data **crypt; - - IEEE80211_DEBUG_WX("SET_ENCODE\n"); - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - key_provided = 1; - } else { - key_provided = 0; - key = ieee->tx_keyidx; - } - - IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? - "provided" : "default"); - - crypt = &ieee->crypt[key]; - - if (erq->flags & IW_ENCODE_DISABLED) { - if (key_provided && *crypt) { - IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", - key); - ieee80211_crypt_delayed_deinit(ieee, crypt); - } else - IEEE80211_DEBUG_WX("Disabling encryption.\n"); - - /* Check all the keys to see if any are still configured, - * and if no key index was provided, de-init them all. - */ - for (i = 0; i < WEP_KEYS; i++) { - if (ieee->crypt[i] != NULL) { - if (key_provided) - break; - ieee80211_crypt_delayed_deinit( - ieee, &ieee->crypt[i]); - } - } - - if (i == WEP_KEYS) { - sec.enabled = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - } - - goto done; - } - - sec.enabled = 1; - sec.flags |= SEC_ENABLED; - - if (*crypt != NULL && (*crypt)->ops != NULL && - strcmp((*crypt)->ops->name, "WEP") != 0) { - /* changing to use WEP; deinit previously used algorithm - * on this key. - */ - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - - if (*crypt == NULL) { - struct ieee80211_crypt_data *new_crypt; - - /* take WEP into use */ - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), - GFP_KERNEL); - if (new_crypt == NULL) - return -ENOMEM; - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (!new_crypt->ops) - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - - if (new_crypt->ops) - new_crypt->priv = new_crypt->ops->init(key); - - if (!new_crypt->ops || !new_crypt->priv) { - kfree(new_crypt); - new_crypt = NULL; - - netdev_warn(ieee->dev, - "could not initialize WEP: load module ieee80211_crypt_wep\n"); - return -EOPNOTSUPP; - } - *crypt = new_crypt; - } - - /* If a new key was provided, set it up */ - if (erq->length > 0) { - len = erq->length <= 5 ? 5 : 13; - memcpy(sec.keys[key], keybuf, erq->length); - if (len > erq->length) - memset(sec.keys[key] + erq->length, 0, - len - erq->length); - IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", - key, escape_essid(sec.keys[key], len), - erq->length, len); - sec.key_sizes[key] = len; - (*crypt)->ops->set_key(sec.keys[key], len, NULL, - (*crypt)->priv); - sec.flags |= (1 << key); - /* This ensures a key will be activated if no key is - * explicitly set. - */ - if (key == sec.active_key) - sec.flags |= SEC_ACTIVE_KEY; - ieee->tx_keyidx = key; - } else { - len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, - NULL, (*crypt)->priv); - if (len == 0) { - /* Set a default key of all 0 */ - IEEE80211_DEBUG_WX("Setting key %d to all zero.\n", - key); - memset(sec.keys[key], 0, 13); - (*crypt)->ops->set_key(sec.keys[key], 13, NULL, - (*crypt)->priv); - sec.key_sizes[key] = 13; - sec.flags |= (1 << key); - } - - /* No key data - just set the default TX key index */ - if (key_provided) { - IEEE80211_DEBUG_WX( - "Setting key %d to default Tx key.\n", key); - ieee->tx_keyidx = key; - sec.active_key = key; - sec.flags |= SEC_ACTIVE_KEY; - } - } - - done: - ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); - sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.flags |= SEC_AUTH_MODE; - IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? - "OPEN" : "SHARED KEY"); - - /* For now we just support WEP, so only set that security level... - * TODO: When WPA is added this is one place that needs to change - */ - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ - - if (ieee->set_security) - ieee->set_security(dev, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. - */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - netdev_dbg(ieee->dev, "reset_port failed\n"); - return -EINVAL; - } - return 0; -} - -int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &(wrqu->encoding); - int len, key; - struct ieee80211_crypt_data *crypt; - - IEEE80211_DEBUG_WX("GET_ENCODE\n"); - - if (ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - } else - key = ieee->tx_keyidx; - - crypt = ieee->crypt[key]; - erq->flags = key + 1; - - if (crypt == NULL || crypt->ops == NULL) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } - - if (strcmp(crypt->ops->name, "WEP") != 0) { - /* only WEP is supported with wireless extensions, so just - * report that encryption is used. - */ - erq->length = 0; - erq->flags |= IW_ENCODE_ENABLED; - return 0; - } - - len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv); - erq->length = (len >= 0 ? len : 0); - - erq->flags |= IW_ENCODE_ENABLED; - - if (ieee->open_wep) - erq->flags |= IW_ENCODE_OPEN; - else - erq->flags |= IW_ENCODE_RESTRICTED; - - return 0; -} - -int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct net_device *dev = ieee->dev; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int i, idx, ret = 0; - int group_key = 0; - const char *alg; - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > WEP_KEYS) - return -EINVAL; - idx--; - } else - idx = ieee->tx_keyidx; - - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - crypt = &ieee->crypt[idx]; - group_key = 1; - } else { - /* some Cisco APs use idx>0 for unicast in dynamic WEP */ - if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) - return -EINVAL; - if (ieee->iw_mode == IW_MODE_INFRA) - crypt = &ieee->crypt[idx]; - else - return -EINVAL; - } - - sec.flags |= SEC_ENABLED; - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - if (*crypt) - ieee80211_crypt_delayed_deinit(ieee, crypt); - - for (i = 0; i < WEP_KEYS; i++) - if (ieee->crypt[i] != NULL) - break; - - if (i == WEP_KEYS) { - sec.enabled = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_LEVEL; - } - goto done; - } - - sec.enabled = 1; - - switch (ext->alg) { - case IW_ENCODE_ALG_WEP: - alg = "WEP"; - break; - case IW_ENCODE_ALG_TKIP: - alg = "TKIP"; - break; - case IW_ENCODE_ALG_CCMP: - alg = "CCMP"; - break; - default: - IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); - ret = -EINVAL; - goto done; - } - - ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) - ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) { - IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); - netdev_err(ieee->dev, "========>unknown crypto alg %d\n", - ext->alg); - ret = -EINVAL; - goto done; - } - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - new_crypt->ops = ops; - if (new_crypt->ops) - new_crypt->priv = new_crypt->ops->init(idx); - if (new_crypt->priv == NULL) { - kfree(new_crypt); - ret = -EINVAL; - goto done; - } - *crypt = new_crypt; - - } - - if (ext->key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, - (*crypt)->priv) < 0) { - IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name); - netdev_err(ieee->dev, "key setting failed\n"); - ret = -EINVAL; - goto done; - } -#if 1 - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - ieee->tx_keyidx = idx; - sec.active_key = idx; - sec.flags |= SEC_ACTIVE_KEY; - } - - if (ext->alg != IW_ENCODE_ALG_NONE) { - memcpy(sec.keys[idx], ext->key, ext->key_len); - sec.key_sizes[idx] = ext->key_len; - sec.flags |= (1 << idx); - if (ext->alg == IW_ENCODE_ALG_WEP) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (ext->alg == IW_ENCODE_ALG_TKIP) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (ext->alg == IW_ENCODE_ALG_CCMP) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - /* Don't set sec level for group keys. */ - if (group_key) - sec.flags &= ~SEC_LEVEL; - } -#endif -done: - if (ieee->set_security) - ieee->set_security(ieee->dev, &sec); - - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(dev)) { - IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name); - return -EINVAL; - } - - return ret; -} - -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_mlme *mlme = (struct iw_mlme *) extra; -#if 1 - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - case IW_MLME_DISASSOC: - ieee80211_disassociate(ieee); - break; - default: - return -EOPNOTSUPP; - } -#endif - return 0; -} - -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - /* need to support wpa2 here */ - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - /* Host AP driver does not use these parameters and allows - * wpa_supplicant to control them internally. - */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures = data->value; - break; - case IW_AUTH_DROP_UNENCRYPTED: - ieee->drop_unencrypted = data->value; - break; - - case IW_AUTH_80211_AUTH_ALG: - ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM) ? 1 : 0; - break; - -#if 1 - case IW_AUTH_WPA_ENABLED: - ieee->wpa_enabled = (data->value) ? 1 : 0; - break; - -#endif - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - ieee->ieee802_1x = data->value; - break; - case IW_AUTH_PRIVACY_INVOKED: - ieee->privacy_invoked = data->value; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -#if 1 -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) -{ - u8 *buf = NULL; - - if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) { - netdev_err(ieee->dev, "return error out, len:%zu\n", len); - return -EINVAL; - } - - if (len) { - if (len != ie[1]+2) { - netdev_err(ieee->dev, "len:%zu, ie:%d\n", len, ie[1]); - return -EINVAL; - } - buf = kmemdup(ie, len, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = len; - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - - return 0; - -} -#endif diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h deleted file mode 100644 index 9f931dba1d82..000000000000 --- a/drivers/staging/rtl8187se/r8180.h +++ /dev/null @@ -1,640 +0,0 @@ -/* - * This is part of rtl8180 OpenSource driver. - * Copyright (C) Andrea Merello 2004-2005 - * Released under the terms of GPL (General Public Licence) - * - * Parts of this driver are based on the GPL part of the official realtek driver - * - * Parts of this driver are based on the rtl8180 driver skeleton from Patric - * Schenke & Andres Salomon - * - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - * - * We want to thanks the Authors of those projects and the Ndiswrapper project - * Authors. - */ - -#ifndef R8180H -#define R8180H - -#include - -#define RTL8180_MODULE_NAME "r8180" -#define DMESG(x, a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a) -#define DMESGW(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a) -#define DMESGE(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* for rtnl_lock() */ -#include -#include -#include /* Necessary because we use the proc fs. */ -#include -#include "ieee80211/ieee80211.h" -#include - -#define EPROM_93c46 0 -#define EPROM_93c56 1 - -#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) - -#define DEFAULT_FRAG_THRESHOLD 2342U -#define MIN_FRAG_THRESHOLD 256U -#define DEFAULT_RTS_THRESHOLD 2342U -#define MIN_RTS_THRESHOLD 0U -#define MAX_RTS_THRESHOLD 2342U -#define DEFAULT_BEACONINTERVAL 0x64U - -#define DEFAULT_RETRY_RTS 7 -#define DEFAULT_RETRY_DATA 7 - -#define BEACON_QUEUE 6 - -#define aSifsTime 10 - -#define sCrcLng 4 -#define sAckCtsLng 112 /* bits in ACK and CTS frames. */ -/* +by amy 080312. */ -#define RATE_ADAPTIVE_TIMER_PERIOD 300 - -enum wireless_mode { - WIRELESS_MODE_UNKNOWN = 0x00, - WIRELESS_MODE_A = 0x01, - WIRELESS_MODE_B = 0x02, - WIRELESS_MODE_G = 0x04, - WIRELESS_MODE_AUTO = 0x08, -}; - -struct chnl_access_setting { - u16 sifs_timer; - u16 difs_timer; - u16 slot_time_timer; - u16 eifs_timer; - u16 cwmin_index; - u16 cwmax_index; -}; - -enum nic_t { - NIC_8185 = 1, - NIC_8185B -}; - -typedef u32 AC_CODING; -#define AC0_BE 0 /* ACI: 0x00 */ /* Best Effort. */ -#define AC1_BK 1 /* ACI: 0x01 */ /* Background. */ -#define AC2_VI 2 /* ACI: 0x10 */ /* Video. */ -#define AC3_VO 3 /* ACI: 0x11 */ /* Voice. */ -#define AC_MAX 4 /* Max: define total number; Should not to be used as a real - * enum. - */ - -/* - * ECWmin/ECWmax field. - * Ref: WMM spec 2.2.2: WME Parameter Element, p.13. - */ -typedef union _ECW { - u8 charData; - struct { - u8 ECWmin:4; - u8 ECWmax:4; - } f; /* Field */ -} ECW, *PECW; - -/* - * ACI/AIFSN Field. Ref: WMM spec 2.2.2: WME Parameter Element, p.12. - */ -typedef union _ACI_AIFSN { - u8 charData; - - struct { - u8 AIFSN:4; - u8 ACM:1; - u8 ACI:2; - u8 Reserved:1; - } f; /* Field */ -} ACI_AIFSN, *PACI_AIFSN; - -/* - * AC Parameters Record Format. - * Ref: WMM spec 2.2.2: WME Parameter Element, p.12. - */ -typedef union _AC_PARAM { - u32 longData; - u8 charData[4]; - - struct { - ACI_AIFSN AciAifsn; - ECW Ecw; - u16 TXOPLimit; - } f; /* Field */ -} AC_PARAM, *PAC_PARAM; - -struct buffer { - struct buffer *next; - u32 *buf; - dma_addr_t dma; -}; - -/* YJ,modified,080828. */ -struct stats { - unsigned long txrdu; - unsigned long rxrdu; - unsigned long rxnolast; - unsigned long rxnodata; - unsigned long rxnopointer; - unsigned long txnperr; - unsigned long txresumed; - unsigned long rxerr; - unsigned long rxoverflow; - unsigned long rxint; - unsigned long txbkpokint; - unsigned long txbepoking; - unsigned long txbkperr; - unsigned long txbeperr; - unsigned long txnpokint; - unsigned long txhpokint; - unsigned long txhperr; - unsigned long ints; - unsigned long shints; - unsigned long txoverflow; - unsigned long rxdmafail; - unsigned long txbeacon; - unsigned long txbeaconerr; - unsigned long txlpokint; - unsigned long txlperr; - unsigned long txretry; /* retry number tony 20060601 */ - unsigned long rxcrcerrmin; /* crc error (0-500) */ - unsigned long rxcrcerrmid; /* crc error (500-1000) */ - unsigned long rxcrcerrmax; /* crc error (>1000) */ - unsigned long rxicverr; /* ICV error */ -}; - -#define MAX_LD_SLOT_NUM 10 -#define KEEP_ALIVE_INTERVAL 20 /* in seconds. */ -#define CHECK_FOR_HANG_PERIOD 2 /* be equal to watchdog check time. */ -#define DEFAULT_KEEP_ALIVE_LEVEL 1 -#define DEFAULT_SLOT_NUM 2 -#define POWER_PROFILE_AC 0 -#define POWER_PROFILE_BATTERY 1 - -struct link_detect_t { - u32 rx_frame_num[MAX_LD_SLOT_NUM]; /* number of Rx Frame. - * CheckForHang_period to determine - * link status. - */ - u16 slot_num; /* number of CheckForHang period to determine link status, - * default is 2. - */ - u16 slot_index; - u32 num_tx_ok_in_period; /* number of packet transmitted during - * CheckForHang. - */ - u32 num_rx_ok_in_period; /* number of packet received during - * CheckForHang. - */ - u8 idle_count; /* (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD) */ - u32 last_num_tx_unicast; - u32 last_num_rx_unicast; - - bool b_busy_traffic; /* when it is set to 1, UI cann't scan at will. */ -}; - -/* YJ,modified,080828,end */ - -/* by amy for led - * ========================================================================== - * LED customization. - * ========================================================================== - */ -enum led_strategy_8185 { - SW_LED_MODE0, - SW_LED_MODE1, - HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different - * control modes). */ -}; - -enum rt_rf_power_state { - RF_ON, - RF_SLEEP, - RF_OFF -}; - -enum _ReasonCode { - unspec_reason = 0x1, - auth_not_valid = 0x2, - deauth_lv_ss = 0x3, - inactivity = 0x4, - ap_overload = 0x5, - class2_err = 0x6, - class3_err = 0x7, - disas_lv_ss = 0x8, - asoc_not_auth = 0x9, - - /* ----MIC_CHECK */ - mic_failure = 0xe, - /* ----END MIC_CHECK */ - - /* Reason code defined in 802.11i D10.0 p.28. */ - invalid_IE = 0x0d, - four_way_tmout = 0x0f, - two_way_tmout = 0x10, - IE_dismatch = 0x11, - invalid_Gcipher = 0x12, - invalid_Pcipher = 0x13, - invalid_AKMP = 0x14, - unsup_RSNIEver = 0x15, - invalid_RSNIE = 0x16, - auth_802_1x_fail = 0x17, - ciper_reject = 0x18, - - /* Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, - * 2005-11-15. - */ - QoS_unspec = 0x20, /* 32 */ - QAP_bandwidth = 0x21, /* 33 */ - poor_condition = 0x22, /* 34 */ - no_facility = 0x23, /* 35 */ - /* Where is 36??? */ - req_declined = 0x25, /* 37 */ - invalid_param = 0x26, /* 38 */ - req_not_honored = 0x27, /* 39 */ - TS_not_created = 0x2F, /* 47 */ - DL_not_allowed = 0x30, /* 48 */ - dest_not_exist = 0x31, /* 49 */ - dest_not_QSTA = 0x32, /* 50 */ -}; - -enum rt_ps_mode { - ACTIVE, /* Active/Continuous access. */ - MAX_PS, /* Max power save mode. */ - FAST_PS /* Fast power save mode. */ -}; - -/* by amy for power save. */ -struct r8180_priv { - struct pci_dev *pdev; - - short epromtype; - int irq; - struct ieee80211_device *ieee80211; - - short plcp_preamble_mode; /* 0:auto 1:short 2:long */ - - spinlock_t irq_th_lock; - spinlock_t tx_lock; - spinlock_t ps_lock; - spinlock_t rf_ps_lock; - - u16 irq_mask; - short irq_enabled; - struct net_device *dev; - short chan; - short sens; - short max_sens; - u8 chtxpwr[15]; /* channels from 1 to 14, 0 not used. */ - u8 chtxpwr_ofdm[15]; /* channels from 1 to 14, 0 not used. */ - u8 channel_plan; /* it's the channel plan index. */ - short up; - short crcmon; /* if 1 allow bad crc frame reception in monitor mode. */ - - struct timer_list scan_timer; - spinlock_t scan_lock; - u8 active_probe; - struct semaphore wx_sem; - short hw_wep; - - short digphy; - short antb; - short diversity; - u32 key0[4]; - short (*rf_set_sens)(struct net_device *dev, short sens); - void (*rf_set_chan)(struct net_device *dev, short ch); - void (*rf_close)(struct net_device *dev); - void (*rf_init)(struct net_device *dev); - void (*rf_sleep)(struct net_device *dev); - void (*rf_wakeup)(struct net_device *dev); - /* short rate; */ - short promisc; - /* stats */ - struct stats stats; - struct link_detect_t link_detect; /* YJ,add,080828 */ - struct iw_statistics wstats; - - /* RX stuff. */ - u32 *rxring; - u32 *rxringtail; - dma_addr_t rxringdma; - struct buffer *rxbuffer; - struct buffer *rxbufferhead; - int rxringcount; - u16 rxbuffersize; - - struct sk_buff *rx_skb; - - short rx_skb_complete; - - u32 rx_prevlen; - - u32 *txmapring; - u32 *txbkpring; - u32 *txbepring; - u32 *txvipring; - u32 *txvopring; - u32 *txhpring; - dma_addr_t txmapringdma; - dma_addr_t txbkpringdma; - dma_addr_t txbepringdma; - dma_addr_t txvipringdma; - dma_addr_t txvopringdma; - dma_addr_t txhpringdma; - u32 *txmapringtail; - u32 *txbkpringtail; - u32 *txbepringtail; - u32 *txvipringtail; - u32 *txvopringtail; - u32 *txhpringtail; - u32 *txmapringhead; - u32 *txbkpringhead; - u32 *txbepringhead; - u32 *txvipringhead; - u32 *txvopringhead; - u32 *txhpringhead; - struct buffer *txmapbufs; - struct buffer *txbkpbufs; - struct buffer *txbepbufs; - struct buffer *txvipbufs; - struct buffer *txvopbufs; - struct buffer *txhpbufs; - struct buffer *txmapbufstail; - struct buffer *txbkpbufstail; - struct buffer *txbepbufstail; - struct buffer *txvipbufstail; - struct buffer *txvopbufstail; - struct buffer *txhpbufstail; - - int txringcount; - int txbuffsize; - struct tasklet_struct irq_rx_tasklet; - u8 dma_poll_mask; - - /* adhoc/master mode stuff. */ - u32 *txbeaconringtail; - dma_addr_t txbeaconringdma; - u32 *txbeaconring; - int txbeaconcount; - struct buffer *txbeaconbufs; - struct buffer *txbeaconbufstail; - - u8 retry_data; - u8 retry_rts; - u16 rts; - - /* by amy for led. */ - enum led_strategy_8185 led_strategy; - /* by amy for led. */ - - /* by amy for power save. */ - struct timer_list watch_dog_timer; - bool bInactivePs; - bool bSwRfProcessing; - enum rt_rf_power_state eInactivePowerState; - enum rt_rf_power_state eRFPowerState; - u32 RfOffReason; - bool RFChangeInProgress; - bool SetRFPowerStateInProgress; - u8 RFProgType; - bool bLeisurePs; - enum rt_ps_mode dot11PowerSaveMode; - u8 TxPollingTimes; - - bool bApBufOurFrame; /* TRUE if AP buffer our unicast data , we will - * keep eAwake until receive data or timeout. - */ - u8 WaitBufDataBcnCount; - u8 WaitBufDataTimeOut; - - /* by amy for power save. */ - /* by amy for antenna. */ - u8 EEPROMSwAntennaDiversity; - bool EEPROMDefaultAntenna1; - u8 RegSwAntennaDiversityMechanism; - bool bSwAntennaDiverity; - u8 RegDefaultAntenna; - bool bDefaultAntenna1; - u8 SignalStrength; - long Stats_SignalStrength; - long LastSignalStrengthInPercent; /* In percentage, used for smoothing, - * e.g. Moving Average. - */ - u8 SignalQuality; /* in 0-100 index. */ - long Stats_SignalQuality; - long RecvSignalPower; /* in dBm. */ - long Stats_RecvSignalPower; - u8 LastRxPktAntenna; /* +by amy 080312 Antenna which received the lasted - * packet. 0: Aux, 1:Main. Added by Roger, - * 2008.01.25. - */ - u32 AdRxOkCnt; - long AdRxSignalStrength; - u8 CurrAntennaIndex; /* Index to current Antenna (both Tx and Rx). */ - u8 AdTickCount; /* Times of SwAntennaDiversityTimer happened. */ - u8 AdCheckPeriod; /* # of period SwAntennaDiversityTimer to check Rx - * signal strength for SW Antenna Diversity. - */ - u8 AdMinCheckPeriod; /* Min value of AdCheckPeriod. */ - u8 AdMaxCheckPeriod; /* Max value of AdCheckPeriod. */ - long AdRxSsThreshold; /* Signal strength threshold to switch antenna. */ - long AdMaxRxSsThreshold; /* Max value of AdRxSsThreshold. */ - bool bAdSwitchedChecking; /* TRUE if we shall shall check Rx signal - * strength for last time switching antenna. - */ - long AdRxSsBeforeSwitched; /* Rx signal strength before we switched - * antenna. - */ - struct timer_list SwAntennaDiversityTimer; - /* by amy for antenna {by amy 080312 */ - - /* Crystal calibration. Added by Roger, 2007.12.11. */ - - bool bXtalCalibration; /* Crystal calibration.*/ - u8 XtalCal_Xin; /* Crystal calibration for Xin. 0~7.5pF */ - u8 XtalCal_Xout; /* Crystal calibration for Xout. 0~7.5pF */ - - /* Tx power tracking with thermal meter indication. - * Added by Roger, 2007.12.11. - */ - - bool bTxPowerTrack; /* Tx Power tracking. */ - u8 ThermalMeter; /* Thermal meter reference indication. */ - - /* Dynamic Initial Gain Adjustment Mechanism. Added by Bruce, - * 2007-02-14. - */ - bool bDigMechanism; /* TRUE if DIG is enabled, FALSE ow. */ - bool bRegHighPowerMechanism; /* For High Power Mechanism. 061010, - * by rcnjko. - */ - u32 FalseAlarmRegValue; - u8 RegDigOfdmFaUpTh; /* Upper threshold of OFDM false alarm, which is - * used in DIG. - */ - u8 DIG_NumberFallbackVote; - u8 DIG_NumberUpgradeVote; - /* For HW antenna diversity, added by Roger, 2008.01.30. */ - u32 AdMainAntennaRxOkCnt; /* Main antenna Rx OK count. */ - u32 AdAuxAntennaRxOkCnt; /* Aux antenna Rx OK count. */ - bool bHWAdSwitched; /* TRUE if we has switched default antenna by HW - * evaluation. - */ - /* RF High Power upper/lower threshold. */ - u8 RegHiPwrUpperTh; - u8 RegHiPwrLowerTh; - /* RF RSSI High Power upper/lower Threshold. */ - u8 RegRSSIHiPwrUpperTh; - u8 RegRSSIHiPwrLowerTh; - /* Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, - * by Bruce, 2007-04-12. - */ - u8 CurCCKRSSI; - bool bCurCCKPkt; - /* High Power Mechanism. Added by amy, 080312. */ - bool bToUpdateTxPwr; - long UndecoratedSmoothedSS; - long UndecoratedSmoothedRxPower; - u8 RSSI; - char RxPower; - u8 InitialGain; - /* For adjust Dig Threshold during Legacy/Leisure Power Save Mode. */ - u32 DozePeriodInPast2Sec; - /* Don't access BB/RF under disable PLL situation. */ - u8 InitialGainBackUp; - u8 RegBModeGainStage; - /* by amy for rate adaptive */ - struct timer_list rateadapter_timer; - u32 RateAdaptivePeriod; - bool bEnhanceTxPwr; - bool bUpdateARFR; - int ForcedDataRate; /* Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M.) - */ - u32 NumTxUnicast; /* YJ,add,080828,for keep alive. */ - u8 keepAliveLevel; /*YJ,add,080828,for KeepAlive. */ - unsigned long NumTxOkTotal; - u16 LastRetryCnt; - u16 LastRetryRate; - unsigned long LastTxokCnt; - unsigned long LastRxokCnt; - u16 CurrRetryCnt; - unsigned long LastTxOKBytes; - unsigned long NumTxOkBytesTotal; - u8 LastFailTxRate; - long LastFailTxRateSS; - u8 FailTxRateCount; - u32 LastTxThroughput; - /* for up rate. */ - unsigned short bTryuping; - u8 CurrTxRate; /* the rate before up. */ - u16 CurrRetryRate; - u16 TryupingCount; - u8 TryDownCountLowData; - u8 TryupingCountNoData; - - u8 CurrentOperaRate; - struct work_struct reset_wq; - struct work_struct watch_dog_wq; - short ack_tx_to_ieee; - - u8 dma_poll_stop_mask; - - u16 ShortRetryLimit; - u16 LongRetryLimit; - u16 EarlyRxThreshold; - u32 TransmitConfig; - u32 ReceiveConfig; - u32 IntrMask; - - struct chnl_access_setting ChannelAccessSetting; -}; - -#define MANAGE_PRIORITY 0 -#define BK_PRIORITY 1 -#define BE_PRIORITY 2 -#define VI_PRIORITY 3 -#define VO_PRIORITY 4 -#define HI_PRIORITY 5 -#define BEACON_PRIORITY 6 - -#define LOW_PRIORITY VI_PRIORITY -#define NORM_PRIORITY VO_PRIORITY -/* AC2Queue mapping. */ -#define AC2Q(_ac) (((_ac) == WME_AC_VO) ? VO_PRIORITY : \ - ((_ac) == WME_AC_VI) ? VI_PRIORITY : \ - ((_ac) == WME_AC_BK) ? BK_PRIORITY : \ - BE_PRIORITY) - -short rtl8180_tx(struct net_device *dev, u8 *skbuf, int len, int priority, - bool morefrag, short fragdesc, int rate); - -u8 read_nic_byte(struct net_device *dev, int x); -u32 read_nic_dword(struct net_device *dev, int x); -u16 read_nic_word(struct net_device *dev, int x); -void write_nic_byte(struct net_device *dev, int x, u8 y); -void write_nic_word(struct net_device *dev, int x, u16 y); -void write_nic_dword(struct net_device *dev, int x, u32 y); -void force_pci_posting(struct net_device *dev); - -void rtl8180_rtx_disable(struct net_device *); -void rtl8180_set_anaparam(struct net_device *dev, u32 a); -void rtl8185_set_anaparam2(struct net_device *dev, u32 a); -void rtl8180_set_hw_wep(struct net_device *dev); -void rtl8180_no_hw_wep(struct net_device *dev); -void rtl8180_update_msr(struct net_device *dev); -void rtl8180_beacon_tx_disable(struct net_device *dev); -void rtl8180_beacon_rx_disable(struct net_device *dev); -int rtl8180_down(struct net_device *dev); -int rtl8180_up(struct net_device *dev); -void rtl8180_commit(struct net_device *dev); -void rtl8180_set_chan(struct net_device *dev, short ch); -void write_phy(struct net_device *dev, u8 adr, u8 data); -void write_phy_cck(struct net_device *dev, u8 adr, u32 data); -void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data); -void rtl8185_tx_antenna(struct net_device *dev, u8 ant); -void rtl8185_rf_pins_enable(struct net_device *dev); -void IPSEnter(struct net_device *dev); -void IPSLeave(struct net_device *dev); -int get_curr_tx_free_desc(struct net_device *dev, int priority); -void UpdateInitialGain(struct net_device *dev); -bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt, - bool bAntDiversity); - -void rtl8185b_adapter_start(struct net_device *dev); -void rtl8185b_rx_enable(struct net_device *dev); -void rtl8185b_tx_enable(struct net_device *dev); -void rtl8180_reset(struct net_device *dev); -void rtl8185b_irq_enable(struct net_device *dev); -void fix_rx_fifo(struct net_device *dev); -void fix_tx_fifo(struct net_device *dev); -void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch); -void rtl8180_rate_adapter(struct work_struct *work); -bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet, - u32 ChangeSource); - -#endif - -/* fun with the built-in ieee80211 stack... */ -extern int ieee80211_crypto_init(void); -extern void ieee80211_crypto_deinit(void); -extern int ieee80211_crypto_tkip_init(void); -extern void ieee80211_crypto_tkip_exit(void); -extern int ieee80211_crypto_ccmp_init(void); -extern void ieee80211_crypto_ccmp_exit(void); -extern int ieee80211_crypto_wep_init(void); -extern void ieee80211_crypto_wep_exit(void); diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h deleted file mode 100644 index b52b5b0610ab..000000000000 --- a/drivers/staging/rtl8187se/r8180_93cx6.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - This is part of rtl8180 OpenSource driver - Copyright (C) Andrea Merello 2004-2005 - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the official realtek driver - Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. -*/ - -/*This files contains card eeprom (93c46 or 93c56) programming routines*/ -/*memory is addressed by WORDS*/ - -#include "r8180.h" -#include "r8180_hw.h" - -#define EPROM_DELAY 10 - -#define EPROM_ANAPARAM_ADDRLWORD 0xd -#define EPROM_ANAPARAM_ADDRHWORD 0xe - -#define RFCHIPID 0x6 -#define RFCHIPID_INTERSIL 1 -#define RFCHIPID_RFMD 2 -#define RFCHIPID_PHILIPS 3 -#define RFCHIPID_MAXIM 4 -#define RFCHIPID_GCT 5 -#define RFCHIPID_RTL8225 9 -#define RF_ZEBRA2 11 -#define EPROM_TXPW_BASE 0x05 -#define RF_ZEBRA4 12 -#define RFCHIPID_RTL8255 0xa -#define RF_PARAM 0x19 -#define RF_PARAM_DIGPHY_SHIFT 0 -#define RF_PARAM_ANTBDEFAULT_SHIFT 1 -#define RF_PARAM_CARRIERSENSE_SHIFT 2 -#define RF_PARAM_CARRIERSENSE_MASK (3<<2) -#define ENERGY_TRESHOLD 0x17 -#define EPROM_VERSION 0x1E -#define MAC_ADR 0x7 - -#define CIS 0x18 - -#define EPROM_TXPW_OFDM_CH1_2 0x20 - -#define EPROM_TXPW_CH1_2 0x30 - -#define RTL818X_EEPROM_CMD_READ (1 << 0) -#define RTL818X_EEPROM_CMD_WRITE (1 << 1) -#define RTL818X_EEPROM_CMD_CK (1 << 2) -#define RTL818X_EEPROM_CMD_CS (1 << 3) - diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c deleted file mode 100644 index a6022d4e7573..000000000000 --- a/drivers/staging/rtl8187se/r8180_core.c +++ /dev/null @@ -1,3775 +0,0 @@ -/* - * This is part of rtl818x pci OpenSource driver - v 0.1 - * Copyright (C) Andrea Merello 2004-2005 - * Released under the terms of GPL (General Public License) - * - * Parts of this driver are based on the GPL part of the official - * Realtek driver. - * - * Parts of this driver are based on the rtl8180 driver skeleton - * from Patric Schenke & Andres Salomon. - * - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - * - * Parts of BB/RF code are derived from David Young rtl8180 netbsd driver. - * - * RSSI calc function from 'The Deuce' - * - * Some ideas borrowed from the 8139too.c driver included in linux kernel. - * - * We (I?) want to thanks the Authors of those projecs and also the - * Ndiswrapper's project Authors. - * - * A big big thanks goes also to Realtek corp. for their help in my attempt to - * add RTL8185 and RTL8225 support, and to David Young also. - * - * Power management interface routines. - * Written by Mariusz Matuszek. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#undef RX_DONT_PASS_UL -#undef DUMMY_RX - -#include -#include -#include -#include -#include -#include - -#include "r8180_hw.h" -#include "r8180.h" -#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */ -#include "r8180_93cx6.h" /* Card EEPROM */ -#include "r8180_wx.h" -#include "r8180_dm.h" - -#include "ieee80211/dot11d.h" - -static struct pci_device_id rtl8180_pci_id_tbl[] = { - { - .vendor = PCI_VENDOR_ID_REALTEK, - .device = 0x8199, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .driver_data = 0, - }, - { - .vendor = 0, - .device = 0, - .subvendor = 0, - .subdevice = 0, - .driver_data = 0, - } -}; - -static char ifname[IFNAMSIZ] = "wlan%d"; -static int hwwep; - -MODULE_LICENSE("GPL"); -MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl); -MODULE_AUTHOR("Andrea Merello "); -MODULE_DESCRIPTION("Linux driver for Realtek RTL8187SE WiFi cards"); - -module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); -module_param(hwwep, int, S_IRUGO|S_IWUSR); - -MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards"); - -static int rtl8180_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); - -static void rtl8180_pci_remove(struct pci_dev *pdev); - -static void rtl8180_shutdown(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - if (dev->netdev_ops->ndo_stop) - dev->netdev_ops->ndo_stop(dev); - pci_disable_device(pdev); -} - -static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (!netif_running(dev)) - goto out_pci_suspend; - - if (dev->netdev_ops->ndo_stop) - dev->netdev_ops->ndo_stop(dev); - - netif_device_detach(dev); - -out_pci_suspend: - pci_save_state(pdev); - pci_disable_device(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - return 0; -} - -static int rtl8180_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - int err; - u32 val; - - pci_set_power_state(pdev, PCI_D0); - - err = pci_enable_device(pdev); - if (err) { - dev_err(&pdev->dev, "pci_enable_device failed on resume\n"); - - return err; - } - - pci_restore_state(pdev); - - /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries - * from interfering with C3 CPU state. pci_restore_state won't help - * here since it only restores the first 64 bytes pci config header. - */ - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - - if (!netif_running(dev)) - goto out; - - if (dev->netdev_ops->ndo_open) - dev->netdev_ops->ndo_open(dev); - - netif_device_attach(dev); -out: - return 0; -} - -static struct pci_driver rtl8180_pci_driver = { - .name = RTL8180_MODULE_NAME, - .id_table = rtl8180_pci_id_tbl, - .probe = rtl8180_pci_probe, - .remove = rtl8180_pci_remove, - .suspend = rtl8180_suspend, - .resume = rtl8180_resume, - .shutdown = rtl8180_shutdown, -}; - -u8 read_nic_byte(struct net_device *dev, int x) -{ - return 0xff&readb((u8 __iomem *)dev->mem_start + x); -} - -u32 read_nic_dword(struct net_device *dev, int x) -{ - return readl((u8 __iomem *)dev->mem_start + x); -} - -u16 read_nic_word(struct net_device *dev, int x) -{ - return readw((u8 __iomem *)dev->mem_start + x); -} - -void write_nic_byte(struct net_device *dev, int x, u8 y) -{ - writeb(y, (u8 __iomem *)dev->mem_start + x); - udelay(20); -} - -void write_nic_dword(struct net_device *dev, int x, u32 y) -{ - writel(y, (u8 __iomem *)dev->mem_start + x); - udelay(20); -} - -void write_nic_word(struct net_device *dev, int x, u16 y) -{ - writew(y, (u8 __iomem *)dev->mem_start + x); - udelay(20); -} - -inline void force_pci_posting(struct net_device *dev) -{ - read_nic_byte(dev, EPROM_CMD); - mb(); -} - -static irqreturn_t rtl8180_interrupt(int irq, void *netdev); -void set_nic_rxring(struct net_device *dev); -void set_nic_txring(struct net_device *dev); -static struct net_device_stats *rtl8180_stats(struct net_device *dev); -void rtl8180_commit(struct net_device *dev); -void rtl8180_start_tx_beacon(struct net_device *dev); - -static struct proc_dir_entry *rtl8180_proc; - -static int proc_get_registers(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - int i, n, max = 0xff; - - /* This dump the current register page */ - for (n = 0; n <= max;) { - seq_printf(m, "\nD: %2x > ", n); - - for (i = 0; i < 16 && n <= max; i++, n++) - seq_printf(m, "%2x ", read_nic_byte(dev, n)); - } - seq_putc(m, '\n'); - return 0; -} - -int get_curr_tx_free_desc(struct net_device *dev, int priority); - -static int proc_get_stats_hw(struct seq_file *m, void *v) -{ - return 0; -} - -static int proc_get_stats_rx(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - seq_printf(m, - "RX OK: %lu\n" - "RX Retry: %lu\n" - "RX CRC Error(0-500): %lu\n" - "RX CRC Error(500-1000): %lu\n" - "RX CRC Error(>1000): %lu\n" - "RX ICV Error: %lu\n", - priv->stats.rxint, - priv->stats.rxerr, - priv->stats.rxcrcerrmin, - priv->stats.rxcrcerrmid, - priv->stats.rxcrcerrmax, - priv->stats.rxicverr - ); - - return 0; -} - -static int proc_get_stats_tx(struct seq_file *m, void *v) -{ - struct net_device *dev = m->private; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - unsigned long totalOK; - - totalOK = priv->stats.txnpokint + priv->stats.txhpokint + - priv->stats.txlpokint; - - seq_printf(m, - "TX OK: %lu\n" - "TX Error: %lu\n" - "TX Retry: %lu\n" - "TX beacon OK: %lu\n" - "TX beacon error: %lu\n", - totalOK, - priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr, - priv->stats.txretry, - priv->stats.txbeacon, - priv->stats.txbeaconerr - ); - - return 0; -} - -static void rtl8180_proc_module_init(void) -{ - DMESG("Initializing proc filesystem"); - rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net); -} - -static void rtl8180_proc_module_remove(void) -{ - remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net); -} - -static void rtl8180_proc_remove_one(struct net_device *dev) -{ - remove_proc_subtree(dev->name, rtl8180_proc); -} - -/* - * seq_file wrappers for procfile show routines. - */ -static int rtl8180_proc_open(struct inode *inode, struct file *file) -{ - struct net_device *dev = proc_get_parent_data(inode); - int (*show)(struct seq_file *, void *) = PDE_DATA(inode); - - return single_open(file, show, dev); -} - -static const struct file_operations rtl8180_proc_fops = { - .open = rtl8180_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* - * Table of proc files we need to create. - */ -struct rtl8180_proc_file { - char name[12]; - int (*show)(struct seq_file *, void *); -}; - -static const struct rtl8180_proc_file rtl8180_proc_files[] = { - { "stats-hw", &proc_get_stats_hw }, - { "stats-rx", &proc_get_stats_rx }, - { "stats-tx", &proc_get_stats_tx }, - { "registers", &proc_get_registers }, - { "" } -}; - -static void rtl8180_proc_init_one(struct net_device *dev) -{ - const struct rtl8180_proc_file *f; - struct proc_dir_entry *dir; - - dir = proc_mkdir_data(dev->name, 0, rtl8180_proc, dev); - if (!dir) { - DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name); - return; - } - - for (f = rtl8180_proc_files; f->name[0]; f++) { - if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir, - &rtl8180_proc_fops, f->show)) { - DMESGE("Unable to initialize /proc/net/r8180/%s/%s\n", - dev->name, f->name); - return; - } - } -} - -/* - * FIXME: check if we can use some standard already-existent - * data type+functions in kernel. - */ - -static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma, - struct buffer **bufferhead) -{ - struct buffer *tmp; - - if (!*buffer) { - - *buffer = kmalloc(sizeof(struct buffer), GFP_KERNEL); - - if (*buffer == NULL) { - DMESGE("Failed to kmalloc head of TX/RX struct"); - return -1; - } - (*buffer)->next = *buffer; - (*buffer)->buf = buf; - (*buffer)->dma = dma; - if (bufferhead != NULL) - (*bufferhead) = (*buffer); - return 0; - } - tmp = *buffer; - - while (tmp->next != (*buffer)) - tmp = tmp->next; - tmp->next = kmalloc(sizeof(struct buffer), GFP_KERNEL); - if (tmp->next == NULL) { - DMESGE("Failed to kmalloc TX/RX struct"); - return -1; - } - tmp->next->buf = buf; - tmp->next->dma = dma; - tmp->next->next = *buffer; - - return 0; -} - -static void buffer_free(struct net_device *dev, struct buffer **buffer, int len, - short consistent) -{ - - struct buffer *tmp, *next; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev = priv->pdev; - - if (!*buffer) - return; - - tmp = *buffer; - - do { - next = tmp->next; - if (consistent) { - pci_free_consistent(pdev, len, - tmp->buf, tmp->dma); - } else { - pci_unmap_single(pdev, tmp->dma, - len, PCI_DMA_FROMDEVICE); - kfree(tmp->buf); - } - kfree(tmp); - tmp = next; - } while (next != *buffer); - - *buffer = NULL; -} - -int get_curr_tx_free_desc(struct net_device *dev, int priority) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u32 *tail; - u32 *head; - int ret; - - switch (priority) { - case MANAGE_PRIORITY: - head = priv->txmapringhead; - tail = priv->txmapringtail; - break; - case BK_PRIORITY: - head = priv->txbkpringhead; - tail = priv->txbkpringtail; - break; - case BE_PRIORITY: - head = priv->txbepringhead; - tail = priv->txbepringtail; - break; - case VI_PRIORITY: - head = priv->txvipringhead; - tail = priv->txvipringtail; - break; - case VO_PRIORITY: - head = priv->txvopringhead; - tail = priv->txvopringtail; - break; - case HI_PRIORITY: - head = priv->txhpringhead; - tail = priv->txhpringtail; - break; - default: - return -1; - } - - if (head <= tail) - ret = priv->txringcount - (tail - head)/8; - else - ret = (head - tail)/8; - - if (ret > priv->txringcount) - DMESG("BUG"); - - return ret; -} - -static short check_nic_enought_desc(struct net_device *dev, int priority) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = netdev_priv(dev); - int requiredbyte; - int required; - - requiredbyte = priv->ieee80211->fts + - sizeof(struct ieee80211_header_data); - - if (ieee->current_network.QoS_Enable) - requiredbyte += 2; - - required = requiredbyte / (priv->txbuffsize-4); - - if (requiredbyte % priv->txbuffsize) - required++; - - /* for now we keep two free descriptor as a safety boundary - * between the tail and the head - */ - - return required + 2 < get_curr_tx_free_desc(dev, priority); -} - -void fix_tx_fifo(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u32 *tmp; - int i; - - for (tmp = priv->txmapring, i = 0; - i < priv->txringcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - - for (tmp = priv->txbkpring, i = 0; - i < priv->txringcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - - for (tmp = priv->txbepring, i = 0; - i < priv->txringcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - for (tmp = priv->txvipring, i = 0; - i < priv->txringcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - - for (tmp = priv->txvopring, i = 0; - i < priv->txringcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - - for (tmp = priv->txhpring, i = 0; - i < priv->txringcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - - for (tmp = priv->txbeaconring, i = 0; - i < priv->txbeaconcount; - tmp += 8, i++) { - *tmp = *tmp & ~(1<<31); - } - - priv->txmapringtail = priv->txmapring; - priv->txmapringhead = priv->txmapring; - priv->txmapbufstail = priv->txmapbufs; - - priv->txbkpringtail = priv->txbkpring; - priv->txbkpringhead = priv->txbkpring; - priv->txbkpbufstail = priv->txbkpbufs; - - priv->txbepringtail = priv->txbepring; - priv->txbepringhead = priv->txbepring; - priv->txbepbufstail = priv->txbepbufs; - - priv->txvipringtail = priv->txvipring; - priv->txvipringhead = priv->txvipring; - priv->txvipbufstail = priv->txvipbufs; - - priv->txvopringtail = priv->txvopring; - priv->txvopringhead = priv->txvopring; - priv->txvopbufstail = priv->txvopbufs; - - priv->txhpringtail = priv->txhpring; - priv->txhpringhead = priv->txhpring; - priv->txhpbufstail = priv->txhpbufs; - - priv->txbeaconringtail = priv->txbeaconring; - priv->txbeaconbufstail = priv->txbeaconbufs; - set_nic_txring(dev); - - ieee80211_reset_queue(priv->ieee80211); - priv->ack_tx_to_ieee = 0; -} - -void fix_rx_fifo(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u32 *tmp; - struct buffer *rxbuf; - u8 rx_desc_size; - - rx_desc_size = 8; /* 4*8 = 32 bytes */ - - for (tmp = priv->rxring, rxbuf = priv->rxbufferhead; - (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size); - tmp += rx_desc_size, rxbuf = rxbuf->next) { - *(tmp+2) = rxbuf->dma; - *tmp = *tmp & ~0xfff; - *tmp = *tmp | priv->rxbuffersize; - *tmp |= (1<<31); - } - - priv->rxringtail = priv->rxring; - priv->rxbuffer = priv->rxbufferhead; - priv->rx_skb_complete = 1; - set_nic_rxring(dev); -} - -static void rtl8180_irq_disable(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - write_nic_dword(dev, IMR, 0); - force_pci_posting(dev); - priv->irq_enabled = 0; -} - -void rtl8180_set_mode(struct net_device *dev, int mode) -{ - u8 ecmd; - - ecmd = read_nic_byte(dev, EPROM_CMD); - ecmd = ecmd & ~EPROM_CMD_OPERATING_MODE_MASK; - ecmd = ecmd | (mode<ieee80211->state == IEEE80211_LINKED) { - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - msr |= (MSR_LINK_ADHOC<ieee80211->iw_mode == IW_MODE_MASTER) - msr |= (MSR_LINK_MASTER<ieee80211->iw_mode == IW_MODE_INFRA) - msr |= (MSR_LINK_MANAGED< 14) || (ch < 1)) { - netdev_err(dev, "In %s: Invalid channel %d\n", __func__, ch); - return; - } - - priv->chan = ch; - priv->rf_set_chan(dev, priv->chan); -} - -void set_nic_txring(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma); - write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma); - write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma); - write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma); - write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma); - write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma); - write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma); -} - -void rtl8180_beacon_tx_enable(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ); - write_nic_byte(dev, TPPollStop, priv->dma_poll_mask); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); -} - -void rtl8180_beacon_tx_disable(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ; - write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - -} - -void rtl8180_rtx_disable(struct net_device *dev) -{ - u8 cmd; - struct r8180_priv *priv = ieee80211_priv(dev); - - cmd = read_nic_byte(dev, CMD); - write_nic_byte(dev, CMD, cmd & - ~((1<rx_skb_complete) - dev_kfree_skb_any(priv->rx_skb); -} - -static short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count, - int addr) -{ - int i; - u32 *desc; - u32 *tmp; - dma_addr_t dma_desc, dma_tmp; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev = priv->pdev; - void *buf; - - if ((bufsize & 0xfff) != bufsize) { - DMESGE("TX buffer allocation too large"); - return 0; - } - desc = (u32 *)pci_alloc_consistent(pdev, - sizeof(u32)*8*count+256, &dma_desc); - if (desc == NULL) - return -1; - - if (dma_desc & 0xff) - /* - * descriptor's buffer must be 256 byte aligned - * we shouldn't be here, since we set DMA mask ! - */ - WARN(1, "DMA buffer is not aligned\n"); - - tmp = desc; - - for (i = 0; i < count; i++) { - buf = (void *)pci_alloc_consistent(pdev, bufsize, &dma_tmp); - if (buf == NULL) - return -ENOMEM; - - switch (addr) { - case TX_MANAGEPRIORITY_RING_ADDR: - if (-1 == buffer_add(&priv->txmapbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer NP"); - return -ENOMEM; - } - break; - case TX_BKPRIORITY_RING_ADDR: - if (-1 == buffer_add(&priv->txbkpbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer LP"); - return -ENOMEM; - } - break; - case TX_BEPRIORITY_RING_ADDR: - if (-1 == buffer_add(&priv->txbepbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer NP"); - return -ENOMEM; - } - break; - case TX_VIPRIORITY_RING_ADDR: - if (-1 == buffer_add(&priv->txvipbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer LP"); - return -ENOMEM; - } - break; - case TX_VOPRIORITY_RING_ADDR: - if (-1 == buffer_add(&priv->txvopbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer NP"); - return -ENOMEM; - } - break; - case TX_HIGHPRIORITY_RING_ADDR: - if (-1 == buffer_add(&priv->txhpbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer HP"); - return -ENOMEM; - } - break; - case TX_BEACON_RING_ADDR: - if (-1 == buffer_add(&priv->txbeaconbufs, - buf, dma_tmp, NULL)) { - DMESGE("Unable to allocate mem for buffer BP"); - return -ENOMEM; - } - break; - } - *tmp = *tmp & ~(1<<31); /* descriptor empty, owned by the drv */ - *(tmp+2) = (u32)dma_tmp; - *(tmp+3) = bufsize; - - if (i+1 < count) - *(tmp+4) = (u32)dma_desc+((i+1)*8*4); - else - *(tmp+4) = (u32)dma_desc; - - tmp = tmp+8; - } - - switch (addr) { - case TX_MANAGEPRIORITY_RING_ADDR: - priv->txmapringdma = dma_desc; - priv->txmapring = desc; - break; - case TX_BKPRIORITY_RING_ADDR: - priv->txbkpringdma = dma_desc; - priv->txbkpring = desc; - break; - case TX_BEPRIORITY_RING_ADDR: - priv->txbepringdma = dma_desc; - priv->txbepring = desc; - break; - case TX_VIPRIORITY_RING_ADDR: - priv->txvipringdma = dma_desc; - priv->txvipring = desc; - break; - case TX_VOPRIORITY_RING_ADDR: - priv->txvopringdma = dma_desc; - priv->txvopring = desc; - break; - case TX_HIGHPRIORITY_RING_ADDR: - priv->txhpringdma = dma_desc; - priv->txhpring = desc; - break; - case TX_BEACON_RING_ADDR: - priv->txbeaconringdma = dma_desc; - priv->txbeaconring = desc; - break; - - } - - return 0; -} - -static void free_tx_desc_rings(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev = priv->pdev; - int count = priv->txringcount; - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txmapring, priv->txmapringdma); - buffer_free(dev, &(priv->txmapbufs), priv->txbuffsize, 1); - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txbkpring, priv->txbkpringdma); - buffer_free(dev, &(priv->txbkpbufs), priv->txbuffsize, 1); - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txbepring, priv->txbepringdma); - buffer_free(dev, &(priv->txbepbufs), priv->txbuffsize, 1); - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txvipring, priv->txvipringdma); - buffer_free(dev, &(priv->txvipbufs), priv->txbuffsize, 1); - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txvopring, priv->txvopringdma); - buffer_free(dev, &(priv->txvopbufs), priv->txbuffsize, 1); - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txhpring, priv->txhpringdma); - buffer_free(dev, &(priv->txhpbufs), priv->txbuffsize, 1); - - count = priv->txbeaconcount; - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->txbeaconring, priv->txbeaconringdma); - buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1); -} - -static void free_rx_desc_ring(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev = priv->pdev; - int count = priv->rxringcount; - - pci_free_consistent(pdev, sizeof(u32)*8*count+256, - priv->rxring, priv->rxringdma); - - buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0); -} - -static short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count) -{ - int i; - u32 *desc; - u32 *tmp; - dma_addr_t dma_desc, dma_tmp; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct pci_dev *pdev = priv->pdev; - void *buf; - u8 rx_desc_size; - - rx_desc_size = 8; /* 4*8 = 32 bytes */ - - if ((bufsize & 0xfff) != bufsize) { - DMESGE("RX buffer allocation too large"); - return -1; - } - - desc = (u32 *)pci_alloc_consistent(pdev, - sizeof(u32) * rx_desc_size * count + 256, &dma_desc); - - if (dma_desc & 0xff) - /* - * descriptor's buffer must be 256 byte aligned - * should never happen since we specify the DMA mask - */ - WARN(1, "DMA buffer is not aligned\n"); - - priv->rxring = desc; - priv->rxringdma = dma_desc; - tmp = desc; - - for (i = 0; i < count; i++) { - buf = kmalloc(bufsize * sizeof(u8), GFP_ATOMIC); - if (buf == NULL) { - DMESGE("Failed to kmalloc RX buffer"); - return -1; - } - - dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8), - PCI_DMA_FROMDEVICE); - if (pci_dma_mapping_error(pdev, dma_tmp)) - return -1; - if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp, - &(priv->rxbufferhead))) { - DMESGE("Unable to allocate mem RX buf"); - return -1; - } - *tmp = 0; /* zero pads the header of the descriptor */ - *tmp = *tmp | (bufsize&0xfff); - *(tmp+2) = (u32)dma_tmp; - *tmp = *tmp | (1<<31); /* descriptor void, owned by the NIC */ - - tmp = tmp+rx_desc_size; - } - - /* this is the last descriptor */ - *(tmp - rx_desc_size) = *(tmp - rx_desc_size) | (1 << 30); - - return 0; -} - - -void set_nic_rxring(struct net_device *dev) -{ - u8 pgreg; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - pgreg = read_nic_byte(dev, PGSELECT); - write_nic_byte(dev, PGSELECT, pgreg & ~(1<rxringdma); -} - -void rtl8180_reset(struct net_device *dev) -{ - u8 cr; - - rtl8180_irq_disable(dev); - - cr = read_nic_byte(dev, CMD); - cr = cr & 2; - cr = cr | (1< 12) - return 10; - return rtl_rate[rate]; -} - -inline u8 rtl8180_IsWirelessBMode(u16 rate) -{ - if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220)) - return 1; - else - return 0; -} - -u16 N_DBPSOfRate(u16 DataRate); - -static u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame, - u8 bShortPreamble) -{ - u16 FrameTime; - u16 N_DBPS; - u16 Ceiling; - - if (rtl8180_IsWirelessBMode(DataRate)) { - if (bManagementFrame || !bShortPreamble || DataRate == 10) - /* long preamble */ - FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10))); - else - /* short preamble */ - FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10))); - - if ((FrameLength*8 % (DataRate/10)) != 0) /* get the ceilling */ - FrameTime++; - } else { /* 802.11g DSSS-OFDM PLCP length field calculation. */ - N_DBPS = N_DBPSOfRate(DataRate); - Ceiling = (16 + 8*FrameLength + 6) / N_DBPS - + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0); - FrameTime = (u16)(16 + 4 + 4*Ceiling + 6); - } - return FrameTime; -} - -u16 N_DBPSOfRate(u16 DataRate) -{ - u16 N_DBPS = 24; - - switch (DataRate) { - case 60: - N_DBPS = 24; - break; - case 90: - N_DBPS = 36; - break; - case 120: - N_DBPS = 48; - break; - case 180: - N_DBPS = 72; - break; - case 240: - N_DBPS = 96; - break; - case 360: - N_DBPS = 144; - break; - case 480: - N_DBPS = 192; - break; - case 540: - N_DBPS = 216; - break; - default: - break; - } - - return N_DBPS; -} - -/* - * For Netgear case, they want good-looking signal strength. - */ -static long NetgearSignalStrengthTranslate(long LastSS, long CurrSS) -{ - long RetSS; - - /* Step 1. Scale mapping. */ - if (CurrSS >= 71 && CurrSS <= 100) - RetSS = 90 + ((CurrSS - 70) / 3); - else if (CurrSS >= 41 && CurrSS <= 70) - RetSS = 78 + ((CurrSS - 40) / 3); - else if (CurrSS >= 31 && CurrSS <= 40) - RetSS = 66 + (CurrSS - 30); - else if (CurrSS >= 21 && CurrSS <= 30) - RetSS = 54 + (CurrSS - 20); - else if (CurrSS >= 5 && CurrSS <= 20) - RetSS = 42 + (((CurrSS - 5) * 2) / 3); - else if (CurrSS == 4) - RetSS = 36; - else if (CurrSS == 3) - RetSS = 27; - else if (CurrSS == 2) - RetSS = 18; - else if (CurrSS == 1) - RetSS = 9; - else - RetSS = CurrSS; - - /* Step 2. Smoothing. */ - if (LastSS > 0) - RetSS = ((LastSS * 5) + (RetSS) + 5) / 6; - - return RetSS; -} - -/* - * Translate 0-100 signal strength index into dBm. - */ -static long TranslateToDbm8185(u8 SignalStrengthIndex) -{ - long SignalPower; - - /* Translate to dBm (x=0.5y-95). */ - SignalPower = (long)((SignalStrengthIndex + 1) >> 1); - SignalPower -= 95; - - return SignalPower; -} - -/* - * Perform signal smoothing for dynamic mechanism. - * This is different with PerformSignalSmoothing8185 in smoothing formula. - * No dramatic adjustment is applied because dynamic mechanism need some - * degree of correctness. Ported from 8187B. - */ -static void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv, - bool bCckRate) -{ - long smoothedSS; - long smoothedRx; - - /* Determine the current packet is CCK rate. */ - priv->bCurCCKPkt = bCckRate; - - smoothedSS = priv->SignalStrength * 10; - - if (priv->UndecoratedSmoothedSS >= 0) - smoothedSS = ((priv->UndecoratedSmoothedSS * 5) + - smoothedSS) / 6; - - priv->UndecoratedSmoothedSS = smoothedSS; - - smoothedRx = ((priv->UndecoratedSmoothedRxPower * 50) + - (priv->RxPower * 11)) / 60; - - priv->UndecoratedSmoothedRxPower = smoothedRx; - - if (bCckRate) - priv->CurCCKRSSI = priv->RSSI; - else - priv->CurCCKRSSI = 0; -} - - -/* - * This is rough RX isr handling routine - */ -static void rtl8180_rx(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct sk_buff *tmp_skb; - short first, last; - u32 len; - int lastlen; - unsigned char quality, signal; - u8 rate; - u32 *tmp, *tmp2; - u8 rx_desc_size; - u8 padding; - char rxpower = 0; - u32 RXAGC = 0; - long RxAGC_dBm = 0; - u8 LNA = 0, BB = 0; - u8 LNA_gain[4] = {02, 17, 29, 39}; - u8 Antenna = 0; - struct ieee80211_hdr_4addr *hdr; - u16 fc, type; - u8 bHwError = 0, bCRC = 0, bICV = 0; - bool bCckRate = false; - u8 RSSI = 0; - long SignalStrengthIndex = 0; - struct ieee80211_rx_stats stats = { - .signal = 0, - .noise = -98, - .rate = 0, - .freq = IEEE80211_24GHZ_BAND, - }; - - stats.nic_type = NIC_8185B; - rx_desc_size = 8; - - if ((*(priv->rxringtail)) & (1<<31)) { - /* we have got an RX int, but the descriptor. we are pointing - * is empty. - */ - - priv->stats.rxnodata++; - priv->ieee80211->stats.rx_errors++; - - tmp2 = NULL; - tmp = priv->rxringtail; - do { - if (tmp == priv->rxring) - tmp = priv->rxring + (priv->rxringcount - 1) * - rx_desc_size; - else - tmp -= rx_desc_size; - - if (!(*tmp & (1<<31))) - tmp2 = tmp; - } while (tmp != priv->rxring); - - if (tmp2) - priv->rxringtail = tmp2; - } - - /* while there are filled descriptors */ - while (!(*(priv->rxringtail) & (1<<31))) { - if (*(priv->rxringtail) & (1<<26)) - DMESGW("RX buffer overflow"); - if (*(priv->rxringtail) & (1<<12)) - priv->stats.rxicverr++; - - if (*(priv->rxringtail) & (1<<27)) { - priv->stats.rxdmafail++; - goto drop; - } - - pci_dma_sync_single_for_cpu(priv->pdev, - priv->rxbuffer->dma, - priv->rxbuffersize * sizeof(u8), - PCI_DMA_FROMDEVICE); - - first = *(priv->rxringtail) & (1<<29) ? 1 : 0; - if (first) - priv->rx_prevlen = 0; - - last = *(priv->rxringtail) & (1<<28) ? 1 : 0; - if (last) { - lastlen = ((*priv->rxringtail) & 0xfff); - - /* if the last descriptor (that should tell us the total - * packet len) tell us something less than the - * descriptors len we had until now, then there is some - * problem.. - * workaround to prevent kernel panic - */ - if (lastlen < priv->rx_prevlen) - len = 0; - else - len = lastlen-priv->rx_prevlen; - - if (*(priv->rxringtail) & (1<<13)) { - if ((*(priv->rxringtail) & 0xfff) < 500) - priv->stats.rxcrcerrmin++; - else if ((*(priv->rxringtail) & 0x0fff) > 1000) - priv->stats.rxcrcerrmax++; - else - priv->stats.rxcrcerrmid++; - - } - - } else { - len = priv->rxbuffersize; - } - - if (first && last) { - padding = ((*(priv->rxringtail+3))&(0x04000000))>>26; - } else if (first) { - padding = ((*(priv->rxringtail+3))&(0x04000000))>>26; - if (padding) - len -= 2; - } else { - padding = 0; - } - padding = 0; - priv->rx_prevlen += len; - - if (priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100) { - /* HW is probably passing several buggy frames without - * FD or LD flag set. - * Throw this garbage away to prevent skb memory - * exhausting - */ - if (!priv->rx_skb_complete) - dev_kfree_skb_any(priv->rx_skb); - priv->rx_skb_complete = 1; - } - - signal = (unsigned char)((*(priv->rxringtail + 3) & - 0x00ff0000) >> 16); - signal = (signal & 0xfe) >> 1; - - quality = (unsigned char)((*(priv->rxringtail+3)) & (0xff)); - - stats.mac_time[0] = *(priv->rxringtail+1); - stats.mac_time[1] = *(priv->rxringtail+2); - - rxpower = ((char)((*(priv->rxringtail + 4) & - 0x00ff0000) >> 16)) / 2 - 42; - - RSSI = ((u8)((*(priv->rxringtail + 3) & - 0x0000ff00) >> 8)) & 0x7f; - - rate = ((*(priv->rxringtail)) & - ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20; - - stats.rate = rtl8180_rate2rate(rate); - Antenna = (*(priv->rxringtail + 3) & 0x00008000) == 0 ? 0 : 1; - if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */ - RxAGC_dBm = rxpower+1; /* bias */ - } else { /* CCK rate. */ - RxAGC_dBm = signal; /* bit 0 discard */ - - LNA = (u8) (RxAGC_dBm & 0x60) >> 5; /* bit 6~ bit 5 */ - BB = (u8) (RxAGC_dBm & 0x1F); /* bit 4 ~ bit 0 */ - - /* Pin_11b=-(LNA_gain+BB_gain) (dBm) */ - RxAGC_dBm = -(LNA_gain[LNA] + (BB * 2)); - - RxAGC_dBm += 4; /* bias */ - } - - if (RxAGC_dBm & 0x80) /* absolute value */ - RXAGC = ~(RxAGC_dBm)+1; - bCckRate = rtl8180_IsWirelessBMode(stats.rate); - /* Translate RXAGC into 1-100. */ - if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */ - if (RXAGC > 90) - RXAGC = 90; - else if (RXAGC < 25) - RXAGC = 25; - RXAGC = (90-RXAGC)*100/65; - } else { /* CCK rate. */ - if (RXAGC > 95) - RXAGC = 95; - else if (RXAGC < 30) - RXAGC = 30; - RXAGC = (95-RXAGC)*100/65; - } - priv->SignalStrength = (u8)RXAGC; - priv->RecvSignalPower = RxAGC_dBm; - priv->RxPower = rxpower; - priv->RSSI = RSSI; - /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */ - if (quality >= 127) - /* 0 causes epc to show signal zero, walk around now */ - quality = 1; - else if (quality < 27) - quality = 100; - else - quality = 127 - quality; - priv->SignalQuality = quality; - - stats.signal = (u8) quality; - - stats.signalstrength = RXAGC; - if (stats.signalstrength > 100) - stats.signalstrength = 100; - stats.signalstrength = (stats.signalstrength * 70) / 100 + 30; - stats.rssi = priv->wstats.qual.qual = priv->SignalQuality; - stats.noise = priv->wstats.qual.noise = - 100 - priv->wstats.qual.qual; - bHwError = (((*(priv->rxringtail)) & (0x00000fff)) == 4080) | - (((*(priv->rxringtail)) & (0x04000000)) != 0) | - (((*(priv->rxringtail)) & (0x08000000)) != 0) | - (((~(*(priv->rxringtail))) & (0x10000000)) != 0) | - (((~(*(priv->rxringtail))) & (0x20000000)) != 0); - bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13; - bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12; - hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf; - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - - if (IEEE80211_FTYPE_CTL != type && - !bHwError && !bCRC && !bICV && - eqMacAddr(priv->ieee80211->current_network.bssid, - fc & IEEE80211_FCTL_TODS ? hdr->addr1 : - fc & IEEE80211_FCTL_FROMDS ? hdr->addr2 : - hdr->addr3)) { - - /* Perform signal smoothing for dynamic - * mechanism on demand. This is different - * with PerformSignalSmoothing8185 in smoothing - * fomula. No dramatic adjustion is apply - * because dynamic mechanism need some degree - * of correctness. */ - PerformUndecoratedSignalSmoothing8185(priv, bCckRate); - - /* For good-looking singal strength. */ - SignalStrengthIndex = NetgearSignalStrengthTranslate( - priv->LastSignalStrengthInPercent, - priv->SignalStrength); - - priv->LastSignalStrengthInPercent = SignalStrengthIndex; - priv->Stats_SignalStrength = - TranslateToDbm8185((u8)SignalStrengthIndex); - - /* - * We need more correct power of received packets and - * the "SignalStrength" of RxStats is beautified, so we - * record the correct power here. - */ - - priv->Stats_SignalQuality = (long)( - priv->Stats_SignalQuality * 5 + - (long)priv->SignalQuality + 5) / 6; - - priv->Stats_RecvSignalPower = (long)( - priv->Stats_RecvSignalPower * 5 + - priv->RecvSignalPower - 1) / 6; - - /* - * Figure out which antenna received the last packet. - * 0: aux, 1: main - */ - priv->LastRxPktAntenna = Antenna ? 1 : 0; - SwAntennaDiversityRxOk8185(dev, priv->SignalStrength); - } - - if (first) { - if (!priv->rx_skb_complete) { - /* seems that HW sometimes fails to receive and - * doesn't provide the last descriptor. - */ - dev_kfree_skb_any(priv->rx_skb); - priv->stats.rxnolast++; - } - priv->rx_skb = dev_alloc_skb(len+2); - if (!priv->rx_skb) - goto drop; - - priv->rx_skb_complete = 0; - priv->rx_skb->dev = dev; - } else { - /* if we are here we should have already RXed the first - * frame. - * If we get here and the skb is not allocated then - * we have just throw out garbage (skb not allocated) - * and we are still rxing garbage.... - */ - if (!priv->rx_skb_complete) { - - tmp_skb = dev_alloc_skb( - priv->rx_skb->len + len + 2); - - if (!tmp_skb) - goto drop; - - tmp_skb->dev = dev; - - memcpy(skb_put(tmp_skb, priv->rx_skb->len), - priv->rx_skb->data, - priv->rx_skb->len); - - dev_kfree_skb_any(priv->rx_skb); - - priv->rx_skb = tmp_skb; - } - } - - if (!priv->rx_skb_complete) { - memcpy(skb_put(priv->rx_skb, len), ((unsigned char *) - priv->rxbuffer->buf) + (padding ? 2 : 0), len); - } - - if (last && !priv->rx_skb_complete) { - if (priv->rx_skb->len > 4) - skb_trim(priv->rx_skb, priv->rx_skb->len-4); - if (!ieee80211_rtl_rx(priv->ieee80211, - priv->rx_skb, &stats)) - dev_kfree_skb_any(priv->rx_skb); - priv->rx_skb_complete = 1; - } - - pci_dma_sync_single_for_device(priv->pdev, - priv->rxbuffer->dma, - priv->rxbuffersize * sizeof(u8), - PCI_DMA_FROMDEVICE); - -drop: /* this is used when we have not enough mem */ - /* restore the descriptor */ - *(priv->rxringtail+2) = priv->rxbuffer->dma; - *(priv->rxringtail) = *(priv->rxringtail) & ~0xfff; - *(priv->rxringtail) = - *(priv->rxringtail) | priv->rxbuffersize; - - *(priv->rxringtail) = - *(priv->rxringtail) | (1<<31); - - priv->rxringtail += rx_desc_size; - if (priv->rxringtail >= - (priv->rxring)+(priv->rxringcount)*rx_desc_size) - priv->rxringtail = priv->rxring; - - priv->rxbuffer = (priv->rxbuffer->next); - } -} - - -static void rtl8180_dma_kick(struct net_device *dev, int priority) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - write_nic_byte(dev, TX_DMA_POLLING, - (1 << (priority + 1)) | priv->dma_poll_mask); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - - force_pci_posting(dev); -} - -static void rtl8180_data_hard_stop(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ; - write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); -} - -static void rtl8180_data_hard_resume(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ); - write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); -} - -/* - * This function TX data frames when the ieee80211 stack requires this. - * It checks also if we need to stop the ieee tx queue, eventually do it - */ -static void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, - int rate) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - int mode; - struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *)skb->data; - bool morefrag = le16_to_cpu(h->frame_control) & IEEE80211_FCTL_MOREFRAGS; - unsigned long flags; - int priority; - - mode = priv->ieee80211->iw_mode; - - rate = ieeerate2rtlrate(rate); - /* - * This function doesn't require lock because we make sure it's called - * with the tx_lock already acquired. - * This come from the kernel's hard_xmit callback (through the ieee - * stack, or from the try_wake_queue (again through the ieee stack. - */ - priority = AC2Q(skb->priority); - spin_lock_irqsave(&priv->tx_lock, flags); - - if (priv->ieee80211->bHwRadioOff) { - spin_unlock_irqrestore(&priv->tx_lock, flags); - - return; - } - - if (!check_nic_enought_desc(dev, priority)) { - DMESGW("Error: no descriptor left by previous TX (avail %d) ", - get_curr_tx_free_desc(dev, priority)); - ieee80211_rtl_stop_queue(priv->ieee80211); - } - rtl8180_tx(dev, skb->data, skb->len, priority, morefrag, 0, rate); - if (!check_nic_enought_desc(dev, priority)) - ieee80211_rtl_stop_queue(priv->ieee80211); - - spin_unlock_irqrestore(&priv->tx_lock, flags); -} - -/* - * This is a rough attempt to TX a frame - * This is called by the ieee 80211 stack to TX management frames. - * If the ring is full packets are dropped (for data frame the queue - * is stopped before this can happen). For this reason it is better - * if the descriptors are larger than the largest management frame - * we intend to TX: i'm unsure what the HW does if it will not find - * the last fragment of a frame because it has been dropped... - * Since queues for Management and Data frames are different we - * might use a different lock than tx_lock (for example mgmt_tx_lock) - */ -/* these function may loop if invoked with 0 descriptors or 0 len buffer */ -static int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - unsigned long flags; - int priority; - - priority = MANAGE_PRIORITY; - - spin_lock_irqsave(&priv->tx_lock, flags); - - if (priv->ieee80211->bHwRadioOff) { - spin_unlock_irqrestore(&priv->tx_lock, flags); - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; - } - - rtl8180_tx(dev, skb->data, skb->len, priority, - 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate)); - - priv->ieee80211->stats.tx_bytes += skb->len; - priv->ieee80211->stats.tx_packets++; - spin_unlock_irqrestore(&priv->tx_lock, flags); - - dev_kfree_skb_any(skb); - return NETDEV_TX_OK; -} - -static void rtl8180_prepare_beacon(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct sk_buff *skb; - - u16 word = read_nic_word(dev, BcnItv); - word &= ~BcnItv_BcnItv; /* clear Bcn_Itv */ - - /* word |= 0x64; */ - word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval); - - write_nic_word(dev, BcnItv, word); - - skb = ieee80211_get_beacon(priv->ieee80211); - if (skb) { - rtl8180_tx(dev, skb->data, skb->len, BEACON_PRIORITY, - 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate)); - dev_kfree_skb_any(skb); - } -} - -/* - * This function do the real dirty work: it enqueues a TX command descriptor in - * the ring buffer, copyes the frame in a TX buffer and kicks the NIC to ensure - * it does the DMA transfer. - */ -short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority, - bool morefrag, short descfrag, int rate) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u32 *tail, *temp_tail; - u32 *begin; - u32 *buf; - int i; - int remain; - int buflen; - int count; - struct buffer *buflist; - struct ieee80211_hdr_3addr *frag_hdr = - (struct ieee80211_hdr_3addr *)txbuf; - u8 dest[ETH_ALEN]; - u8 bUseShortPreamble = 0; - u8 bCTSEnable = 0; - u8 bRTSEnable = 0; - u16 Duration = 0; - u16 RtsDur = 0; - u16 ThisFrameTime = 0; - u16 TxDescDuration = 0; - bool ownbit_flag = false; - - switch (priority) { - case MANAGE_PRIORITY: - tail = priv->txmapringtail; - begin = priv->txmapring; - buflist = priv->txmapbufstail; - count = priv->txringcount; - break; - case BK_PRIORITY: - tail = priv->txbkpringtail; - begin = priv->txbkpring; - buflist = priv->txbkpbufstail; - count = priv->txringcount; - break; - case BE_PRIORITY: - tail = priv->txbepringtail; - begin = priv->txbepring; - buflist = priv->txbepbufstail; - count = priv->txringcount; - break; - case VI_PRIORITY: - tail = priv->txvipringtail; - begin = priv->txvipring; - buflist = priv->txvipbufstail; - count = priv->txringcount; - break; - case VO_PRIORITY: - tail = priv->txvopringtail; - begin = priv->txvopring; - buflist = priv->txvopbufstail; - count = priv->txringcount; - break; - case HI_PRIORITY: - tail = priv->txhpringtail; - begin = priv->txhpring; - buflist = priv->txhpbufstail; - count = priv->txringcount; - break; - case BEACON_PRIORITY: - tail = priv->txbeaconringtail; - begin = priv->txbeaconring; - buflist = priv->txbeaconbufstail; - count = priv->txbeaconcount; - break; - default: - return -1; - break; - } - - memcpy(&dest, frag_hdr->addr1, ETH_ALEN); - if (is_multicast_ether_addr(dest)) { - Duration = 0; - RtsDur = 0; - bRTSEnable = 0; - bCTSEnable = 0; - - ThisFrameTime = ComputeTxTime(len + sCrcLng, - rtl8180_rate2rate(rate), 0, bUseShortPreamble); - TxDescDuration = ThisFrameTime; - } else { /* Unicast packet */ - u16 AckTime; - - /* for Keep alive */ - priv->NumTxUnicast++; - - /* Figure out ACK rate according to BSS basic rate - * and Tx rate. - * AckCTSLng = 14 use 1M bps send - */ - AckTime = ComputeTxTime(14, 10, 0, 0); - - if (((len + sCrcLng) > priv->rts) && priv->rts) { /* RTS/CTS. */ - u16 RtsTime, CtsTime; - bRTSEnable = 1; - bCTSEnable = 0; - - /* Rate and time required for RTS. */ - RtsTime = ComputeTxTime(sAckCtsLng / 8, - priv->ieee80211->basic_rate, 0, 0); - - /* Rate and time required for CTS. - * AckCTSLng = 14 use 1M bps send - */ - CtsTime = ComputeTxTime(14, 10, 0, 0); - - /* Figure out time required to transmit this frame. */ - ThisFrameTime = ComputeTxTime(len + sCrcLng, - rtl8180_rate2rate(rate), 0, - bUseShortPreamble); - - /* RTS-CTS-ThisFrame-ACK. */ - RtsDur = CtsTime + ThisFrameTime + - AckTime + 3 * aSifsTime; - - TxDescDuration = RtsTime + RtsDur; - } else { /* Normal case. */ - bCTSEnable = 0; - bRTSEnable = 0; - RtsDur = 0; - - ThisFrameTime = ComputeTxTime(len + sCrcLng, - rtl8180_rate2rate(rate), 0, bUseShortPreamble); - TxDescDuration = ThisFrameTime + aSifsTime + AckTime; - } - - if (!(le16_to_cpu(frag_hdr->frame_control) & IEEE80211_FCTL_MOREFRAGS)) { - /* ThisFrame-ACK. */ - Duration = aSifsTime + AckTime; - } else { /* One or more fragments remained. */ - u16 NextFragTime; - - /* pretend following packet length = current packet */ - NextFragTime = ComputeTxTime(len + sCrcLng, - rtl8180_rate2rate(rate), 0, bUseShortPreamble); - - /* ThisFrag-ACk-NextFrag-ACK. */ - Duration = NextFragTime + 3 * aSifsTime + 2 * AckTime; - } - - } /* End of Unicast packet */ - - frag_hdr->duration_id = Duration; - - buflen = priv->txbuffsize; - remain = len; - temp_tail = tail; - - while (remain != 0) { - mb(); - if (!buflist) { - DMESGE("TX buffer error, cannot TX frames. pri %d.", - priority); - return -1; - } - buf = buflist->buf; - - if ((*tail & (1 << 31)) && (priority != BEACON_PRIORITY)) { - DMESGW("No more TX desc, returning %x of %x", - remain, len); - priv->stats.txrdu++; - return remain; - } - - *tail = 0; /* zeroes header */ - *(tail+1) = 0; - *(tail+3) = 0; - *(tail+5) = 0; - *(tail+6) = 0; - *(tail+7) = 0; - - /* FIXME: should be triggered by HW encryption parameters.*/ - *tail |= (1<<15); /* no encrypt */ - - if (remain == len && !descfrag) { - ownbit_flag = false; - *tail = *tail | (1 << 29); /* first segment of packet */ - *tail = *tail | (len); - } else { - ownbit_flag = true; - } - - for (i = 0; i < buflen && remain > 0; i++, remain--) { - /* copy data into descriptor pointed DMAble buffer */ - ((u8 *)buf)[i] = txbuf[i]; - - if (remain == 4 && i+4 >= buflen) - break; - /* ensure the last desc has at least 4 bytes payload */ - } - txbuf = txbuf + i; - *(tail+3) = *(tail+3) & ~0xfff; - *(tail+3) = *(tail+3) | i; /* buffer length */ - - if (bCTSEnable) - *tail |= (1<<18); - - if (bRTSEnable) { /* rts enable */ - /* RTS RATE */ - *tail |= (ieeerate2rtlrate( - priv->ieee80211->basic_rate) << 19); - - *tail |= (1<<23); /* rts enable */ - *(tail+1) |= (RtsDur&0xffff); /* RTS Duration */ - } - *(tail+3) |= ((TxDescDuration&0xffff)<<16); /* DURATION */ - - *(tail + 5) |= (11 << 8); /* retry lim; */ - - *tail = *tail | ((rate&0xf) << 24); - - if (morefrag) - *tail = (*tail) | (1<<17); /* more fragment */ - if (!remain) - *tail = (*tail) | (1<<28); /* last segment of frame */ - - *(tail+5) = *(tail+5)|(2<<27); - *(tail+7) = *(tail+7)|(1<<4); - - wmb(); - if (ownbit_flag) - /* descriptor ready to be txed */ - *tail |= (1 << 31); - - if ((tail - begin)/8 == count-1) - tail = begin; - else - tail = tail+8; - - buflist = buflist->next; - - mb(); - - switch (priority) { - case MANAGE_PRIORITY: - priv->txmapringtail = tail; - priv->txmapbufstail = buflist; - break; - case BK_PRIORITY: - priv->txbkpringtail = tail; - priv->txbkpbufstail = buflist; - break; - case BE_PRIORITY: - priv->txbepringtail = tail; - priv->txbepbufstail = buflist; - break; - case VI_PRIORITY: - priv->txvipringtail = tail; - priv->txvipbufstail = buflist; - break; - case VO_PRIORITY: - priv->txvopringtail = tail; - priv->txvopbufstail = buflist; - break; - case HI_PRIORITY: - priv->txhpringtail = tail; - priv->txhpbufstail = buflist; - break; - case BEACON_PRIORITY: - /* - * The HW seems to be happy with the 1st - * descriptor filled and the 2nd empty... - * So always update descriptor 1 and never - * touch 2nd - */ - break; - } - } - *temp_tail = *temp_tail | (1<<31); /* descriptor ready to be txed */ - rtl8180_dma_kick(dev, priority); - - return 0; -} - -void rtl8180_irq_rx_tasklet(struct r8180_priv *priv); - -static void rtl8180_link_change(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u16 beacon_interval; - struct ieee80211_network *net = &priv->ieee80211->current_network; - - rtl8180_update_msr(dev); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - - write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]); - write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]); - - beacon_interval = read_nic_word(dev, BEACON_INTERVAL); - beacon_interval &= ~BEACON_INTERVAL_MASK; - beacon_interval |= net->beacon_interval; - write_nic_word(dev, BEACON_INTERVAL, beacon_interval); - - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - - rtl8180_set_chan(dev, priv->chan); -} - -static void rtl8180_rq_tx_ack(struct net_device *dev) -{ - - struct r8180_priv *priv = ieee80211_priv(dev); - - write_nic_byte(dev, CONFIG4, - read_nic_byte(dev, CONFIG4) | CONFIG4_PWRMGT); - priv->ack_tx_to_ieee = 1; -} - -static short rtl8180_is_tx_queue_empty(struct net_device *dev) -{ - - struct r8180_priv *priv = ieee80211_priv(dev); - u32 *d; - - for (d = priv->txmapring; - d < priv->txmapring + priv->txringcount; d += 8) - if (*d & (1<<31)) - return 0; - - for (d = priv->txbkpring; - d < priv->txbkpring + priv->txringcount; d += 8) - if (*d & (1<<31)) - return 0; - - for (d = priv->txbepring; - d < priv->txbepring + priv->txringcount; d += 8) - if (*d & (1<<31)) - return 0; - - for (d = priv->txvipring; - d < priv->txvipring + priv->txringcount; d += 8) - if (*d & (1<<31)) - return 0; - - for (d = priv->txvopring; - d < priv->txvopring + priv->txringcount; d += 8) - if (*d & (1<<31)) - return 0; - - for (d = priv->txhpring; - d < priv->txhpring + priv->txringcount; d += 8) - if (*d & (1<<31)) - return 0; - return 1; -} - -static void rtl8180_hw_wakeup(struct net_device *dev) -{ - unsigned long flags; - struct r8180_priv *priv = ieee80211_priv(dev); - - spin_lock_irqsave(&priv->ps_lock, flags); - write_nic_byte(dev, CONFIG4, - read_nic_byte(dev, CONFIG4) & ~CONFIG4_PWRMGT); - if (priv->rf_wakeup) - priv->rf_wakeup(dev); - spin_unlock_irqrestore(&priv->ps_lock, flags); -} - -static void rtl8180_hw_sleep_down(struct net_device *dev) -{ - unsigned long flags; - struct r8180_priv *priv = ieee80211_priv(dev); - - spin_lock_irqsave(&priv->ps_lock, flags); - if (priv->rf_sleep) - priv->rf_sleep(dev); - spin_unlock_irqrestore(&priv->ps_lock, flags); -} - -static void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u32 rb = jiffies; - unsigned long flags; - - spin_lock_irqsave(&priv->ps_lock, flags); - - /* - * Writing HW register with 0 equals to disable - * the timer, that is not really what we want - */ - tl -= MSECS(4+16+7); - - /* - * If the interval in which we are requested to sleep is too - * short then give up and remain awake - */ - if (((tl >= rb) && (tl-rb) <= MSECS(MIN_SLEEP_TIME)) - || ((rb > tl) && (rb-tl) < MSECS(MIN_SLEEP_TIME))) { - spin_unlock_irqrestore(&priv->ps_lock, flags); - netdev_warn(dev, "too short to sleep\n"); - return; - } - - { - u32 tmp = (tl > rb) ? (tl-rb) : (rb-tl); - - priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp); - /* as tl may be less than rb */ - queue_delayed_work(priv->ieee80211->wq, - &priv->ieee80211->hw_wakeup_wq, tmp); - } - /* - * If we suspect the TimerInt is gone beyond tl - * while setting it, then give up - */ - - if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME))) || - ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) { - spin_unlock_irqrestore(&priv->ps_lock, flags); - return; - } - - queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq); - spin_unlock_irqrestore(&priv->ps_lock, flags); -} - -static void rtl8180_wmm_single_param_update(struct net_device *dev, - u8 mode, AC_CODING eACI, PAC_PARAM param) -{ - u8 u1bAIFS; - u32 u4bAcParam; - - /* Retrieve parameters to update. */ - /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */ - u1bAIFS = param->f.AciAifsn.f.AIFSN * ((mode & IEEE_G) == IEEE_G ? - 9 : 20) + aSifsTime; - u4bAcParam = (((u32)param->f.TXOPLimit << AC_PARAM_TXOP_LIMIT_OFFSET) | - ((u32)param->f.Ecw.f.ECWmax << AC_PARAM_ECW_MAX_OFFSET) | - ((u32)param->f.Ecw.f.ECWmin << AC_PARAM_ECW_MIN_OFFSET) | - ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - - switch (eACI) { - case AC1_BK: - write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); - return; - case AC0_BE: - write_nic_dword(dev, AC_BE_PARAM, u4bAcParam); - return; - case AC2_VI: - write_nic_dword(dev, AC_VI_PARAM, u4bAcParam); - return; - case AC3_VO: - write_nic_dword(dev, AC_VO_PARAM, u4bAcParam); - return; - default: - pr_warn("SetHwReg8185(): invalid ACI: %d!\n", eACI); - return; - } -} - -static void rtl8180_wmm_param_update(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, - struct ieee80211_device, wmm_param_update_wq); - struct net_device *dev = ieee->dev; - u8 *ac_param = (u8 *)(ieee->current_network.wmm_param); - u8 mode = ieee->current_network.mode; - AC_CODING eACI; - AC_PARAM AcParam; - - if (!ieee->current_network.QoS_Enable) { - /* legacy ac_xx_param update */ - AcParam.longData = 0; - AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */ - AcParam.f.AciAifsn.f.ACM = 0; - AcParam.f.Ecw.f.ECWmin = 3; /* Follow 802.11 CWmin. */ - AcParam.f.Ecw.f.ECWmax = 7; /* Follow 802.11 CWmax. */ - AcParam.f.TXOPLimit = 0; - - for (eACI = 0; eACI < AC_MAX; eACI++) { - AcParam.f.AciAifsn.f.ACI = (u8)eACI; - - rtl8180_wmm_single_param_update(dev, mode, eACI, - (PAC_PARAM)&AcParam); - } - return; - } - - for (eACI = 0; eACI < AC_MAX; eACI++) { - rtl8180_wmm_single_param_update(dev, mode, - ((PAC_PARAM)ac_param)->f.AciAifsn.f.ACI, - (PAC_PARAM)ac_param); - - ac_param += sizeof(AC_PARAM); - } -} - -void rtl8180_restart_wq(struct work_struct *work); -void rtl8180_watch_dog_wq(struct work_struct *work); -void rtl8180_hw_wakeup_wq(struct work_struct *work); -void rtl8180_hw_sleep_wq(struct work_struct *work); -void rtl8180_sw_antenna_wq(struct work_struct *work); -void rtl8180_watch_dog(struct net_device *dev); - -static void watch_dog_adaptive(unsigned long data) -{ - struct r8180_priv *priv = ieee80211_priv((struct net_device *)data); - - if (!priv->up) { - DMESG("<----watch_dog_adaptive():driver is not up!\n"); - return; - } - - /* Tx High Power Mechanism. */ - if (CheckHighPower((struct net_device *)data)) - queue_work(priv->ieee80211->wq, - (void *)&priv->ieee80211->tx_pw_wq); - - /* Tx Power Tracking on 87SE. */ - if (CheckTxPwrTracking((struct net_device *)data)) - TxPwrTracking87SE((struct net_device *)data); - - /* Perform DIG immediately. */ - if (CheckDig((struct net_device *)data)) - queue_work(priv->ieee80211->wq, - (void *)&priv->ieee80211->hw_dig_wq); - - rtl8180_watch_dog((struct net_device *)data); - - queue_work(priv->ieee80211->wq, - (void *)&priv->ieee80211->GPIOChangeRFWorkItem); - - priv->watch_dog_timer.expires = jiffies + - MSECS(IEEE80211_WATCH_DOG_TIME); - - add_timer(&priv->watch_dog_timer); -} - -static struct rtl8187se_channel_list channel_plan_list[] = { - /* FCC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, - 44, 48, 52, 56, 60, 64}, 19}, - - /* IC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, - - /* ETSI */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, - 44, 48, 52, 56, 60, 64}, 21}, - - /* Spain. Change to ETSI. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, - 44, 48, 52, 56, 60, 64}, 21}, - - /* France. Change to ETSI. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, - 44, 48, 52, 56, 60, 64}, 21}, - - /* MKK */ - {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, - - /* MKK1 */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, - 40, 44, 48, 52, 56, 60, 64}, 22}, - - /* Israel. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, - 44, 48, 52, 56, 60, 64}, 21}, - - /* For 11a , TELEC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, - - /* For Global Domain. 1-11 active, 12-14 passive. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, - - /* world wide 13: ch1~ch11 active, ch12~13 passive */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13} -}; - -static void rtl8180_set_channel_map(u8 channel_plan, - struct ieee80211_device *ieee) -{ - int i; - - ieee->MinPassiveChnlNum = MAX_CHANNEL_NUMBER+1; - ieee->IbssStartChnl = 0; - - switch (channel_plan) { - case COUNTRY_CODE_FCC: - case COUNTRY_CODE_IC: - case COUNTRY_CODE_ETSI: - case COUNTRY_CODE_SPAIN: - case COUNTRY_CODE_FRANCE: - case COUNTRY_CODE_MKK: - case COUNTRY_CODE_MKK1: - case COUNTRY_CODE_ISRAEL: - case COUNTRY_CODE_TELEC: - { - Dot11d_Init(ieee); - ieee->bGlobalDomain = false; - if (channel_plan_list[channel_plan].len != 0) { - /* Clear old channel map */ - memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - /* Set new channel map */ - for (i = 0; i < channel_plan_list[channel_plan].len; i++) { - if (channel_plan_list[channel_plan].channel[i] <= 14) - GET_DOT11D_INFO(ieee)->channel_map[channel_plan_list[channel_plan].channel[i]] = 1; - } - } - break; - } - case COUNTRY_CODE_GLOBAL_DOMAIN: - { - GET_DOT11D_INFO(ieee)->bEnabled = false; - Dot11d_Reset(ieee); - ieee->bGlobalDomain = true; - break; - } - case COUNTRY_CODE_WORLD_WIDE_13_INDEX: - { - ieee->MinPassiveChnlNum = 12; - ieee->IbssStartChnl = 10; - break; - } - default: - { - Dot11d_Init(ieee); - ieee->bGlobalDomain = false; - memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - for (i = 1; i <= 14; i++) - GET_DOT11D_INFO(ieee)->channel_map[i] = 1; - break; - } - } -} - -void GPIOChangeRFWorkItemCallBack(struct work_struct *work); - -static void rtl8180_statistics_init(struct stats *pstats) -{ - memset(pstats, 0, sizeof(struct stats)); -} - -static void rtl8180_link_detect_init(struct link_detect_t *plink_detect) -{ - memset(plink_detect, 0, sizeof(struct link_detect_t)); - plink_detect->slot_num = DEFAULT_SLOT_NUM; -} - -static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom) -{ - struct net_device *dev = eeprom->data; - u8 reg = read_nic_byte(dev, EPROM_CMD); - - eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; - eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; - eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; - eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; -} - -static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom) -{ - struct net_device *dev = eeprom->data; - u8 reg = 2 << 6; - - if (eeprom->reg_data_in) - reg |= RTL818X_EEPROM_CMD_WRITE; - if (eeprom->reg_data_out) - reg |= RTL818X_EEPROM_CMD_READ; - if (eeprom->reg_data_clock) - reg |= RTL818X_EEPROM_CMD_CK; - if (eeprom->reg_chip_select) - reg |= RTL818X_EEPROM_CMD_CS; - - write_nic_byte(dev, EPROM_CMD, reg); - read_nic_byte(dev, EPROM_CMD); - udelay(10); -} - -static short rtl8180_init(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u16 word; - u16 usValue; - u16 tmpu16; - int i, j; - struct eeprom_93cx6 eeprom; - u16 eeprom_val; - - eeprom.data = dev; - eeprom.register_read = rtl8187se_eeprom_register_read; - eeprom.register_write = rtl8187se_eeprom_register_write; - eeprom.width = PCI_EEPROM_WIDTH_93C46; - - eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val); - priv->channel_plan = eeprom_val & 0xFF; - if (priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN) { - netdev_err(dev, "rtl8180_init: Invalid channel plan! Set to default.\n"); - priv->channel_plan = 0; - } - - DMESG("Channel plan is %d\n", priv->channel_plan); - rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211); - - /* FIXME: these constants are placed in a bad pleace. */ - priv->txbuffsize = 2048; /* 1024; */ - priv->txringcount = 32; /* 32; */ - priv->rxbuffersize = 2048; /* 1024; */ - priv->rxringcount = 64; /* 32; */ - priv->txbeaconcount = 2; - priv->rx_skb_complete = 1; - - priv->RFChangeInProgress = false; - priv->SetRFPowerStateInProgress = false; - priv->RFProgType = 0; - - priv->irq_enabled = 0; - - rtl8180_statistics_init(&priv->stats); - rtl8180_link_detect_init(&priv->link_detect); - - priv->ack_tx_to_ieee = 0; - priv->ieee80211->current_network.beacon_interval = - DEFAULT_BEACONINTERVAL; - priv->ieee80211->iw_mode = IW_MODE_INFRA; - priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN | - IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | - IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE; - priv->ieee80211->active_scan = 1; - priv->ieee80211->rate = 110; /* 11 mbps */ - priv->ieee80211->modulation = IEEE80211_CCK_MODULATION; - priv->ieee80211->host_encrypt = 1; - priv->ieee80211->host_decrypt = 1; - priv->ieee80211->sta_wake_up = rtl8180_hw_wakeup; - priv->ieee80211->ps_request_tx_ack = rtl8180_rq_tx_ack; - priv->ieee80211->enter_sleep_state = rtl8180_hw_sleep; - priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty; - - priv->hw_wep = hwwep; - priv->dev = dev; - priv->retry_rts = DEFAULT_RETRY_RTS; - priv->retry_data = DEFAULT_RETRY_DATA; - priv->RFChangeInProgress = false; - priv->SetRFPowerStateInProgress = false; - priv->RFProgType = 0; - priv->bInactivePs = true; /* false; */ - priv->ieee80211->bInactivePs = priv->bInactivePs; - priv->bSwRfProcessing = false; - priv->eRFPowerState = RF_OFF; - priv->RfOffReason = 0; - priv->led_strategy = SW_LED_MODE0; - priv->TxPollingTimes = 0; - priv->bLeisurePs = true; - priv->dot11PowerSaveMode = ACTIVE; - priv->AdMinCheckPeriod = 5; - priv->AdMaxCheckPeriod = 10; - priv->AdMaxRxSsThreshold = 30; /* 60->30 */ - priv->AdRxSsThreshold = 20; /* 50->20 */ - priv->AdCheckPeriod = priv->AdMinCheckPeriod; - priv->AdTickCount = 0; - priv->AdRxSignalStrength = -1; - priv->RegSwAntennaDiversityMechanism = 0; - priv->RegDefaultAntenna = 0; - priv->SignalStrength = 0; - priv->AdRxOkCnt = 0; - priv->CurrAntennaIndex = 0; - priv->AdRxSsBeforeSwitched = 0; - init_timer(&priv->SwAntennaDiversityTimer); - priv->SwAntennaDiversityTimer.data = (unsigned long)dev; - priv->SwAntennaDiversityTimer.function = - (void *)SwAntennaDiversityTimerCallback; - priv->bDigMechanism = true; - priv->InitialGain = 6; - priv->bXtalCalibration = false; - priv->XtalCal_Xin = 0; - priv->XtalCal_Xout = 0; - priv->bTxPowerTrack = false; - priv->ThermalMeter = 0; - priv->FalseAlarmRegValue = 0; - priv->RegDigOfdmFaUpTh = 0xc; /* Upper threshold of OFDM false alarm, - which is used in DIG. */ - priv->DIG_NumberFallbackVote = 0; - priv->DIG_NumberUpgradeVote = 0; - priv->LastSignalStrengthInPercent = 0; - priv->Stats_SignalStrength = 0; - priv->LastRxPktAntenna = 0; - priv->SignalQuality = 0; /* in 0-100 index. */ - priv->Stats_SignalQuality = 0; - priv->RecvSignalPower = 0; /* in dBm. */ - priv->Stats_RecvSignalPower = 0; - priv->AdMainAntennaRxOkCnt = 0; - priv->AdAuxAntennaRxOkCnt = 0; - priv->bHWAdSwitched = false; - priv->bRegHighPowerMechanism = true; - priv->RegHiPwrUpperTh = 77; - priv->RegHiPwrLowerTh = 75; - priv->RegRSSIHiPwrUpperTh = 70; - priv->RegRSSIHiPwrLowerTh = 20; - priv->bCurCCKPkt = false; - priv->UndecoratedSmoothedSS = -1; - priv->bToUpdateTxPwr = false; - priv->CurCCKRSSI = 0; - priv->RxPower = 0; - priv->RSSI = 0; - priv->NumTxOkTotal = 0; - priv->NumTxUnicast = 0; - priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL; - priv->CurrRetryCnt = 0; - priv->LastRetryCnt = 0; - priv->LastTxokCnt = 0; - priv->LastRxokCnt = 0; - priv->LastRetryRate = 0; - priv->bTryuping = 0; - priv->CurrTxRate = 0; - priv->CurrRetryRate = 0; - priv->TryupingCount = 0; - priv->TryupingCountNoData = 0; - priv->TryDownCountLowData = 0; - priv->LastTxOKBytes = 0; - priv->LastFailTxRate = 0; - priv->LastFailTxRateSS = 0; - priv->FailTxRateCount = 0; - priv->LastTxThroughput = 0; - priv->NumTxOkBytesTotal = 0; - priv->ForcedDataRate = 0; - priv->RegBModeGainStage = 1; - - priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - spin_lock_init(&priv->irq_th_lock); - spin_lock_init(&priv->tx_lock); - spin_lock_init(&priv->ps_lock); - spin_lock_init(&priv->rf_ps_lock); - sema_init(&priv->wx_sem, 1); - INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq); - INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, - (void *)rtl8180_hw_wakeup_wq); - INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq, - (void *)rtl8180_hw_sleep_wq); - INIT_WORK(&priv->ieee80211->wmm_param_update_wq, - (void *)rtl8180_wmm_param_update); - INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq, - (void *)rtl8180_rate_adapter); - INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq, - (void *)rtl8180_hw_dig_wq); - INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq, - (void *)rtl8180_tx_pw_wq); - INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem, - (void *) GPIOChangeRFWorkItemCallBack); - tasklet_init(&priv->irq_rx_tasklet, - (void(*)(unsigned long)) rtl8180_irq_rx_tasklet, - (unsigned long)priv); - - init_timer(&priv->watch_dog_timer); - priv->watch_dog_timer.data = (unsigned long)dev; - priv->watch_dog_timer.function = watch_dog_adaptive; - - init_timer(&priv->rateadapter_timer); - priv->rateadapter_timer.data = (unsigned long)dev; - priv->rateadapter_timer.function = timer_rate_adaptive; - priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD; - priv->bEnhanceTxPwr = false; - - priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit; - priv->ieee80211->set_chan = rtl8180_set_chan; - priv->ieee80211->link_change = rtl8180_link_change; - priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit; - priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop; - priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume; - - priv->ieee80211->init_wmmparam_flag = 0; - - priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon; - priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable; - priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - - priv->ShortRetryLimit = 7; - priv->LongRetryLimit = 7; - priv->EarlyRxThreshold = 7; - - priv->TransmitConfig = (1<ShortRetryLimit<LongRetryLimit<ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF | - RCR_AB | RCR_AM | RCR_APM | - (7<EarlyRxThreshold<EarlyRxThreshold == 7 ? - RCR_ONLYERLPKT : 0); - - priv->IntrMask = IMR_TMGDOK | IMR_TBDER | - IMR_THPDER | IMR_THPDOK | - IMR_TVODER | IMR_TVODOK | - IMR_TVIDER | IMR_TVIDOK | - IMR_TBEDER | IMR_TBEDOK | - IMR_TBKDER | IMR_TBKDOK | - IMR_RDU | - IMR_RER | IMR_ROK | - IMR_RQoSOK; - - priv->InitialGain = 6; - - DMESG("MAC controller is a RTL8187SE b/g"); - - priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION; - priv->ieee80211->short_slot = 1; - - eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue); - DMESG("usValue is %#hx\n", usValue); - /* 3Read AntennaDiversity */ - - /* SW Antenna Diversity. */ - priv->EEPROMSwAntennaDiversity = (usValue & EEPROM_SW_AD_MASK) == - EEPROM_SW_AD_ENABLE; - - /* Default Antenna to use. */ - priv->EEPROMDefaultAntenna1 = (usValue & EEPROM_DEF_ANT_MASK) == - EEPROM_DEF_ANT_1; - - if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */ - /* 0: default from EEPROM. */ - priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity; - else - /* 1:disable antenna diversity, 2: enable antenna diversity. */ - priv->bSwAntennaDiverity = - priv->RegSwAntennaDiversityMechanism == 2; - - if (priv->RegDefaultAntenna == 0) - /* 0: default from EEPROM. */ - priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1; - else - /* 1: main, 2: aux. */ - priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2; - - priv->plcp_preamble_mode = 2; - /* the eeprom type is stored in RCR register bit #6 */ - if (RCR_9356SEL & read_nic_dword(dev, RCR)) - priv->epromtype = EPROM_93c56; - else - priv->epromtype = EPROM_93c46; - - eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *) - dev->dev_addr, 3); - - for (i = 1, j = 0; i < 14; i += 2, j++) { - eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word); - priv->chtxpwr[i] = word & 0xff; - priv->chtxpwr[i+1] = (word & 0xff00)>>8; - } - for (i = 1, j = 0; i < 14; i += 2, j++) { - eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word); - priv->chtxpwr_ofdm[i] = word & 0xff; - priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8; - } - - /* 3Read crystal calibration and thermal meter indication on 87SE. */ - eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16); - - /* Crystal calibration for Xin and Xout resp. */ - priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; - priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4; - if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12) - priv->bXtalCalibration = true; - - /* Thermal meter reference indication. */ - priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8); - if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13) - priv->bTxPowerTrack = true; - - priv->rf_sleep = rtl8225z4_rf_sleep; - priv->rf_wakeup = rtl8225z4_rf_wakeup; - DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!"); - - priv->rf_close = rtl8225z2_rf_close; - priv->rf_init = rtl8225z2_rf_init; - priv->rf_set_chan = rtl8225z2_rf_set_chan; - priv->rf_set_sens = NULL; - - if (0 != alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, - TX_MANAGEPRIORITY_RING_ADDR)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, - TX_BKPRIORITY_RING_ADDR)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, - TX_BEPRIORITY_RING_ADDR)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, - TX_VIPRIORITY_RING_ADDR)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, - TX_VOPRIORITY_RING_ADDR)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount, - TX_HIGHPRIORITY_RING_ADDR)) - return -ENOMEM; - - if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount, - TX_BEACON_RING_ADDR)) - return -ENOMEM; - - if (request_irq(dev->irq, rtl8180_interrupt, - IRQF_SHARED, dev->name, dev)) { - DMESGE("Error allocating IRQ %d", dev->irq); - return -1; - } else { - priv->irq = dev->irq; - DMESG("IRQ %d", dev->irq); - } - - return 0; -} - -void rtl8180_no_hw_wep(struct net_device *dev) -{ -} - -void rtl8180_set_hw_wep(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u8 pgreg; - u8 security; - u32 key0_word4; - - pgreg = read_nic_byte(dev, PGSELECT); - write_nic_byte(dev, PGSELECT, pgreg & ~(1<key0[3] & 0xff; - write_nic_dword(dev, KEY0, (priv->key0[0])); - write_nic_dword(dev, KEY0+4, (priv->key0[1])); - write_nic_dword(dev, KEY0+4+4, (priv->key0[2])); - write_nic_dword(dev, KEY0+4+4+4, (key0_word4)); - - security = read_nic_byte(dev, SECURITY); - security |= (1<> 24)); - write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16)); - write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8)); - write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff))); -} - -inline void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data) -{ - data = data & 0xff; - rtl8185_write_phy(dev, adr, data); -} - -void write_phy_cck(struct net_device *dev, u8 adr, u32 data) -{ - data = data & 0xff; - rtl8185_write_phy(dev, adr, data | 0x10000); -} - -/* - * This configures registers for beacon tx and enables it via - * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might - * be used to stop beacon transmission - */ -void rtl8180_start_tx_beacon(struct net_device *dev) -{ - u16 word; - - DMESG("Enabling beacon TX"); - rtl8180_prepare_beacon(dev); - rtl8180_irq_disable(dev); - rtl8180_beacon_tx_enable(dev); - - word = read_nic_word(dev, AtimWnd) & ~AtimWnd_AtimWnd; - write_nic_word(dev, AtimWnd, word); /* word |= */ - - word = read_nic_word(dev, BintrItv); - word &= ~BintrItv_BintrItv; - word |= 1000; /* priv->ieee80211->current_network.beacon_interval * - * ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1); - * FIXME: check if correct ^^ worked with 0x3e8; - */ - write_nic_word(dev, BintrItv, word); - - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - - rtl8185b_irq_enable(dev); -} - -static struct net_device_stats *rtl8180_stats(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - return &priv->ieee80211->stats; -} - -/* - * Change current and default preamble mode. - */ -static bool MgntActSet_802_11_PowerSaveMode(struct r8180_priv *priv, - enum rt_ps_mode rtPsMode) -{ - /* Currently, we do not change power save mode on IBSS mode. */ - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - return false; - - priv->ieee80211->ps = rtPsMode; - - return true; -} - -static void LeisurePSEnter(struct r8180_priv *priv) -{ - if (priv->bLeisurePs) - if (priv->ieee80211->ps == IEEE80211_PS_DISABLED) - /* IEEE80211_PS_ENABLE */ - MgntActSet_802_11_PowerSaveMode(priv, - IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST); -} - -static void LeisurePSLeave(struct r8180_priv *priv) -{ - if (priv->bLeisurePs) - if (priv->ieee80211->ps != IEEE80211_PS_DISABLED) - MgntActSet_802_11_PowerSaveMode( - priv, IEEE80211_PS_DISABLED); -} - -void rtl8180_hw_wakeup_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of( - dwork, struct ieee80211_device, hw_wakeup_wq); - struct net_device *dev = ieee->dev; - - rtl8180_hw_wakeup(dev); -} - -void rtl8180_hw_sleep_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of( - dwork, struct ieee80211_device, hw_sleep_wq); - struct net_device *dev = ieee->dev; - - rtl8180_hw_sleep_down(dev); -} - -static void MgntLinkKeepAlive(struct r8180_priv *priv) -{ - if (priv->keepAliveLevel == 0) - return; - - if (priv->ieee80211->state == IEEE80211_LINKED) { - /* - * Keep-Alive. - */ - - if ((priv->keepAliveLevel == 2) || - (priv->link_detect.last_num_tx_unicast == - priv->NumTxUnicast && - priv->link_detect.last_num_rx_unicast == - priv->ieee80211->NumRxUnicast) - ) { - priv->link_detect.idle_count++; - - /* - * Send a Keep-Alive packet packet to AP if we had - * been idle for a while. - */ - if (priv->link_detect.idle_count >= - KEEP_ALIVE_INTERVAL / - CHECK_FOR_HANG_PERIOD - 1) { - priv->link_detect.idle_count = 0; - ieee80211_sta_ps_send_null_frame( - priv->ieee80211, false); - } - } else { - priv->link_detect.idle_count = 0; - } - priv->link_detect.last_num_tx_unicast = priv->NumTxUnicast; - priv->link_detect.last_num_rx_unicast = - priv->ieee80211->NumRxUnicast; - } -} - -void rtl8180_watch_dog(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - bool bEnterPS = false; - bool bBusyTraffic = false; - u32 TotalRxNum = 0; - u16 SlotIndex = 0; - u16 i = 0; - if (priv->ieee80211->actscanning == false) { - if ((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && - (priv->ieee80211->state == IEEE80211_NOLINK) && - (priv->ieee80211->beinretry == false) && - (priv->eRFPowerState == RF_ON)) - IPSEnter(dev); - } - if ((priv->ieee80211->state == IEEE80211_LINKED) && - (priv->ieee80211->iw_mode == IW_MODE_INFRA)) { - SlotIndex = (priv->link_detect.slot_index++) % - priv->link_detect.slot_num; - - priv->link_detect.rx_frame_num[SlotIndex] = - priv->ieee80211->NumRxDataInPeriod + - priv->ieee80211->NumRxBcnInPeriod; - - for (i = 0; i < priv->link_detect.slot_num; i++) - TotalRxNum += priv->link_detect.rx_frame_num[i]; - - if (TotalRxNum == 0) { - priv->ieee80211->state = IEEE80211_ASSOCIATING; - queue_work(priv->ieee80211->wq, - &priv->ieee80211->associate_procedure_wq); - } - } - - MgntLinkKeepAlive(priv); - - LeisurePSLeave(priv); - - if (priv->ieee80211->state == IEEE80211_LINKED) { - priv->link_detect.num_rx_ok_in_period = - priv->ieee80211->NumRxDataInPeriod; - if (priv->link_detect.num_rx_ok_in_period > 666 || - priv->link_detect.num_tx_ok_in_period > 666) { - bBusyTraffic = true; - } - if ((priv->link_detect.num_rx_ok_in_period + - priv->link_detect.num_tx_ok_in_period > 8) - || (priv->link_detect.num_rx_ok_in_period > 2)) { - bEnterPS = false; - } else - bEnterPS = true; - - if (bEnterPS) - LeisurePSEnter(priv); - else - LeisurePSLeave(priv); - } else - LeisurePSLeave(priv); - priv->link_detect.b_busy_traffic = bBusyTraffic; - priv->link_detect.num_rx_ok_in_period = 0; - priv->link_detect.num_tx_ok_in_period = 0; - priv->ieee80211->NumRxDataInPeriod = 0; - priv->ieee80211->NumRxBcnInPeriod = 0; -} - -static int _rtl8180_up(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - priv->up = 1; - - DMESG("Bringing up iface"); - rtl8185b_adapter_start(dev); - rtl8185b_rx_enable(dev); - rtl8185b_tx_enable(dev); - if (priv->bInactivePs) { - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - IPSLeave(dev); - } - timer_rate_adaptive((unsigned long)dev); - watch_dog_adaptive((unsigned long)dev); - if (priv->bSwAntennaDiverity) - SwAntennaDiversityTimerCallback(dev); - ieee80211_softmac_start_protocol(priv->ieee80211); - return 0; -} - -static int rtl8180_open(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret; - - down(&priv->wx_sem); - ret = rtl8180_up(dev); - up(&priv->wx_sem); - return ret; -} - -int rtl8180_up(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->up == 1) - return -1; - - return _rtl8180_up(dev); -} - -static int rtl8180_close(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret; - - down(&priv->wx_sem); - ret = rtl8180_down(dev); - up(&priv->wx_sem); - - return ret; -} - -int rtl8180_down(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->up == 0) - return -1; - - priv->up = 0; - - ieee80211_softmac_stop_protocol(priv->ieee80211); - /* FIXME */ - if (!netif_queue_stopped(dev)) - netif_stop_queue(dev); - rtl8180_rtx_disable(dev); - rtl8180_irq_disable(dev); - del_timer_sync(&priv->watch_dog_timer); - del_timer_sync(&priv->rateadapter_timer); - cancel_delayed_work(&priv->ieee80211->rate_adapter_wq); - cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq); - cancel_delayed_work(&priv->ieee80211->hw_sleep_wq); - cancel_delayed_work(&priv->ieee80211->hw_dig_wq); - cancel_delayed_work(&priv->ieee80211->tx_pw_wq); - del_timer_sync(&priv->SwAntennaDiversityTimer); - SetZebraRFPowerState8185(dev, RF_OFF); - memset(&priv->ieee80211->current_network, - 0, sizeof(struct ieee80211_network)); - priv->ieee80211->state = IEEE80211_NOLINK; - return 0; -} - -void rtl8180_restart_wq(struct work_struct *work) -{ - struct r8180_priv *priv = container_of( - work, struct r8180_priv, reset_wq); - struct net_device *dev = priv->dev; - - down(&priv->wx_sem); - - rtl8180_commit(dev); - - up(&priv->wx_sem); -} - -static void rtl8180_restart(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - schedule_work(&priv->reset_wq); -} - -void rtl8180_commit(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->up == 0) - return; - - del_timer_sync(&priv->watch_dog_timer); - del_timer_sync(&priv->rateadapter_timer); - cancel_delayed_work(&priv->ieee80211->rate_adapter_wq); - cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq); - cancel_delayed_work(&priv->ieee80211->hw_sleep_wq); - cancel_delayed_work(&priv->ieee80211->hw_dig_wq); - cancel_delayed_work(&priv->ieee80211->tx_pw_wq); - del_timer_sync(&priv->SwAntennaDiversityTimer); - ieee80211_softmac_stop_protocol(priv->ieee80211); - rtl8180_irq_disable(dev); - rtl8180_rtx_disable(dev); - _rtl8180_up(dev); -} - -static void r8180_set_multicast(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - short promisc; - - promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; - - if (promisc != priv->promisc) - rtl8180_restart(dev); - - priv->promisc = promisc; -} - -static int r8180_set_mac_adr(struct net_device *dev, void *mac) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct sockaddr *addr = mac; - - down(&priv->wx_sem); - - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - - if (priv->ieee80211->iw_mode == IW_MODE_MASTER) - memcpy(priv->ieee80211->current_network.bssid, - dev->dev_addr, ETH_ALEN); - - if (priv->up) { - rtl8180_down(dev); - rtl8180_up(dev); - } - - up(&priv->wx_sem); - - return 0; -} - -/* based on ipw2200 driver */ -static int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct iwreq *wrq = (struct iwreq *) rq; - int ret = -1; - - switch (cmd) { - case RTL_IOCTL_WPA_SUPPLICANT: - ret = ieee80211_wpa_supplicant_ioctl( - priv->ieee80211, &wrq->u.data); - return ret; - default: - return -EOPNOTSUPP; - } - - return -EOPNOTSUPP; -} - -static const struct net_device_ops rtl8180_netdev_ops = { - .ndo_open = rtl8180_open, - .ndo_stop = rtl8180_close, - .ndo_get_stats = rtl8180_stats, - .ndo_tx_timeout = rtl8180_restart, - .ndo_do_ioctl = rtl8180_ioctl, - .ndo_set_rx_mode = r8180_set_multicast, - .ndo_set_mac_address = r8180_set_mac_adr, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, - .ndo_start_xmit = ieee80211_rtl_xmit, -}; - -static int rtl8180_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - unsigned long ioaddr = 0; - struct net_device *dev = NULL; - struct r8180_priv *priv = NULL; - u8 unit = 0; - int ret = -ENODEV; - - unsigned long pmem_start, pmem_len, pmem_flags; - - DMESG("Configuring chip resources"); - - if (pci_enable_device(pdev)) { - DMESG("Failed to enable PCI device"); - return -EIO; - } - - pci_set_master(pdev); - pci_set_dma_mask(pdev, 0xffffff00ULL); - pci_set_consistent_dma_mask(pdev, 0xffffff00ULL); - dev = alloc_ieee80211(sizeof(struct r8180_priv)); - if (!dev) { - ret = -ENOMEM; - goto fail_free; - } - priv = ieee80211_priv(dev); - priv->ieee80211 = netdev_priv(dev); - - pci_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - - priv = ieee80211_priv(dev); - priv->pdev = pdev; - - pmem_start = pci_resource_start(pdev, 1); - pmem_len = pci_resource_len(pdev, 1); - pmem_flags = pci_resource_flags(pdev, 1); - - if (!(pmem_flags & IORESOURCE_MEM)) { - DMESG("region #1 not a MMIO resource, aborting"); - goto fail; - } - - if (!request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) { - DMESG("request_mem_region failed!"); - goto fail; - } - - ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len); - if (ioaddr == (unsigned long)NULL) { - DMESG("ioremap failed!"); - goto fail1; - } - - dev->mem_start = ioaddr; /* shared mem start */ - dev->mem_end = ioaddr + pci_resource_len(pdev, 0); /* shared mem end */ - - pci_read_config_byte(pdev, 0x05, &unit); - pci_write_config_byte(pdev, 0x05, unit & (~0x04)); - - dev->irq = pdev->irq; - priv->irq = 0; - - dev->netdev_ops = &rtl8180_netdev_ops; - dev->wireless_handlers = &r8180_wx_handlers_def; - - dev->type = ARPHRD_ETHER; - dev->watchdog_timeo = HZ*3; - - if (dev_alloc_name(dev, ifname) < 0) { - DMESG("Oops: devname already taken! Trying wlan%%d...\n"); - strcpy(ifname, "wlan%d"); - dev_alloc_name(dev, ifname); - } - - if (rtl8180_init(dev) != 0) { - DMESG("Initialization failed"); - goto fail1; - } - - netif_carrier_off(dev); - - if (register_netdev(dev)) - goto fail1; - - rtl8180_proc_init_one(dev); - - DMESG("Driver probe completed\n"); - return 0; -fail1: - if (dev->mem_start != (unsigned long)NULL) { - iounmap((void __iomem *)dev->mem_start); - release_mem_region(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1)); - } -fail: - if (dev) { - if (priv->irq) { - free_irq(dev->irq, dev); - dev->irq = 0; - } - free_ieee80211(dev); - } - -fail_free: - pci_disable_device(pdev); - - DMESG("wlan driver load failed\n"); - return ret; -} - -static void rtl8180_pci_remove(struct pci_dev *pdev) -{ - struct r8180_priv *priv; - struct net_device *dev = pci_get_drvdata(pdev); - - if (dev) { - unregister_netdev(dev); - - priv = ieee80211_priv(dev); - - rtl8180_proc_remove_one(dev); - rtl8180_down(dev); - priv->rf_close(dev); - rtl8180_reset(dev); - mdelay(10); - - if (priv->irq) { - DMESG("Freeing irq %d", dev->irq); - free_irq(dev->irq, dev); - priv->irq = 0; - } - - free_rx_desc_ring(dev); - free_tx_desc_rings(dev); - - if (dev->mem_start != (unsigned long)NULL) { - iounmap((void __iomem *)dev->mem_start); - release_mem_region(pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1)); - } - - free_ieee80211(dev); - } - pci_disable_device(pdev); - - DMESG("wlan driver removed\n"); -} - -static int __init rtl8180_pci_module_init(void) -{ - int ret; - - ret = ieee80211_crypto_init(); - if (ret) { - pr_err("ieee80211_crypto_init() failed %d\n", ret); - return ret; - } - ret = ieee80211_crypto_tkip_init(); - if (ret) { - pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret); - return ret; - } - ret = ieee80211_crypto_ccmp_init(); - if (ret) { - pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret); - return ret; - } - ret = ieee80211_crypto_wep_init(); - if (ret) { - pr_err("ieee80211_crypto_wep_init() failed %d\n", ret); - return ret; - } - - pr_info("\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n"); - pr_info("Copyright (c) 2004-2005, Andrea Merello\n"); - DMESG("Initializing module"); - DMESG("Wireless extensions version %d", WIRELESS_EXT); - rtl8180_proc_module_init(); - - if (pci_register_driver(&rtl8180_pci_driver)) { - DMESG("No device found"); - return -ENODEV; - } - return 0; -} - -static void __exit rtl8180_pci_module_exit(void) -{ - pci_unregister_driver(&rtl8180_pci_driver); - rtl8180_proc_module_remove(); - ieee80211_crypto_tkip_exit(); - ieee80211_crypto_ccmp_exit(); - ieee80211_crypto_wep_exit(); - ieee80211_crypto_deinit(); - DMESG("Exiting"); -} - -static void rtl8180_try_wake_queue(struct net_device *dev, int pri) -{ - unsigned long flags; - short enough_desc; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - spin_lock_irqsave(&priv->tx_lock, flags); - enough_desc = check_nic_enought_desc(dev, pri); - spin_unlock_irqrestore(&priv->tx_lock, flags); - - if (enough_desc) - ieee80211_rtl_wake_queue(priv->ieee80211); -} - -static void rtl8180_tx_isr(struct net_device *dev, int pri, short error) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u32 *tail; /* tail virtual addr */ - u32 *head; /* head virtual addr */ - u32 *begin; /* start of ring virtual addr */ - u32 *nicv; /* nic pointer virtual addr */ - u32 nic; /* nic pointer physical addr */ - u32 nicbegin; /* start of ring physical addr */ - unsigned long flag; - /* physical addr are ok on 32 bits since we set DMA mask */ - int offs; - int j, i; - int hd; - if (error) - priv->stats.txretry++; - spin_lock_irqsave(&priv->tx_lock, flag); - switch (pri) { - case MANAGE_PRIORITY: - tail = priv->txmapringtail; - begin = priv->txmapring; - head = priv->txmapringhead; - nic = read_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR); - nicbegin = priv->txmapringdma; - break; - case BK_PRIORITY: - tail = priv->txbkpringtail; - begin = priv->txbkpring; - head = priv->txbkpringhead; - nic = read_nic_dword(dev, TX_BKPRIORITY_RING_ADDR); - nicbegin = priv->txbkpringdma; - break; - case BE_PRIORITY: - tail = priv->txbepringtail; - begin = priv->txbepring; - head = priv->txbepringhead; - nic = read_nic_dword(dev, TX_BEPRIORITY_RING_ADDR); - nicbegin = priv->txbepringdma; - break; - case VI_PRIORITY: - tail = priv->txvipringtail; - begin = priv->txvipring; - head = priv->txvipringhead; - nic = read_nic_dword(dev, TX_VIPRIORITY_RING_ADDR); - nicbegin = priv->txvipringdma; - break; - case VO_PRIORITY: - tail = priv->txvopringtail; - begin = priv->txvopring; - head = priv->txvopringhead; - nic = read_nic_dword(dev, TX_VOPRIORITY_RING_ADDR); - nicbegin = priv->txvopringdma; - break; - case HI_PRIORITY: - tail = priv->txhpringtail; - begin = priv->txhpring; - head = priv->txhpringhead; - nic = read_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR); - nicbegin = priv->txhpringdma; - break; - - default: - spin_unlock_irqrestore(&priv->tx_lock, flag); - return; - } - - nicv = (u32 *)((nic - nicbegin) + (u8 *)begin); - if ((head <= tail && (nicv > tail || nicv < head)) || - (head > tail && (nicv > tail && nicv < head))) { - DMESGW("nic has lost pointer"); - spin_unlock_irqrestore(&priv->tx_lock, flag); - rtl8180_restart(dev); - return; - } - - /* - * We check all the descriptors between the head and the nic, - * but not the currently pointed by the nic (the next to be txed) - * and the previous of the pointed (might be in process ??) - */ - offs = (nic - nicbegin); - offs = offs / 8 / 4; - hd = (head - begin) / 8; - - if (offs >= hd) - j = offs - hd; - else - j = offs + (priv->txringcount-1-hd); - - j -= 2; - if (j < 0) - j = 0; - - for (i = 0; i < j; i++) { - if ((*head) & (1<<31)) - break; - if (((*head)&(0x10000000)) != 0) { - priv->CurrRetryCnt += (u16)((*head) & (0x000000ff)); - if (!error) - priv->NumTxOkTotal++; - } - - if (!error) - priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff); - - *head = *head & ~(1<<31); - - if ((head - begin)/8 == priv->txringcount-1) - head = begin; - else - head += 8; - } - - /* - * The head has been moved to the last certainly TXed - * (or at least processed by the nic) packet. - * The driver take forcefully owning of all these packets - * If the packet previous of the nic pointer has been - * processed this doesn't matter: it will be checked - * here at the next round. Anyway if no more packet are - * TXed no memory leak occur at all. - */ - - switch (pri) { - case MANAGE_PRIORITY: - priv->txmapringhead = head; - - if (priv->ack_tx_to_ieee) { - if (rtl8180_is_tx_queue_empty(dev)) { - priv->ack_tx_to_ieee = 0; - ieee80211_ps_tx_ack(priv->ieee80211, !error); - } - } - break; - case BK_PRIORITY: - priv->txbkpringhead = head; - break; - case BE_PRIORITY: - priv->txbepringhead = head; - break; - case VI_PRIORITY: - priv->txvipringhead = head; - break; - case VO_PRIORITY: - priv->txvopringhead = head; - break; - case HI_PRIORITY: - priv->txhpringhead = head; - break; - } - - spin_unlock_irqrestore(&priv->tx_lock, flag); -} - -static irqreturn_t rtl8180_interrupt(int irq, void *netdev) -{ - struct net_device *dev = (struct net_device *) netdev; - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - unsigned long flags; - u32 inta; - - /* We should return IRQ_NONE, but for now let me keep this */ - if (priv->irq_enabled == 0) - return IRQ_HANDLED; - - spin_lock_irqsave(&priv->irq_th_lock, flags); - - /* ISR: 4bytes */ - inta = read_nic_dword(dev, ISR); - write_nic_dword(dev, ISR, inta); /* reset int situation */ - - priv->stats.shints++; - - if (!inta) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; - /* - * most probably we can safely return IRQ_NONE, - * but for now is better to avoid problems - */ - } - - if (inta == 0xffff) { - /* HW disappeared */ - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; - } - - priv->stats.ints++; - - if (!netif_running(dev)) { - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return IRQ_HANDLED; - } - - if (inta & ISR_TimeOut) - write_nic_dword(dev, TimerInt, 0); - - if (inta & ISR_TBDOK) - priv->stats.txbeacon++; - - if (inta & ISR_TBDER) - priv->stats.txbeaconerr++; - - if (inta & IMR_TMGDOK) - rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0); - - if (inta & ISR_THPDER) { - priv->stats.txhperr++; - rtl8180_tx_isr(dev, HI_PRIORITY, 1); - priv->ieee80211->stats.tx_errors++; - } - - if (inta & ISR_THPDOK) { /* High priority tx ok */ - priv->link_detect.num_tx_ok_in_period++; - priv->stats.txhpokint++; - rtl8180_tx_isr(dev, HI_PRIORITY, 0); - } - - if (inta & ISR_RER) - priv->stats.rxerr++; - - if (inta & ISR_TBKDER) { /* corresponding to BK_PRIORITY */ - priv->stats.txbkperr++; - priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev, BK_PRIORITY, 1); - rtl8180_try_wake_queue(dev, BK_PRIORITY); - } - - if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */ - priv->stats.txbeperr++; - priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev, BE_PRIORITY, 1); - rtl8180_try_wake_queue(dev, BE_PRIORITY); - } - if (inta & ISR_TNPDER) { /* corresponding to VO_PRIORITY */ - priv->stats.txnperr++; - priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev, NORM_PRIORITY, 1); - rtl8180_try_wake_queue(dev, NORM_PRIORITY); - } - - if (inta & ISR_TLPDER) { /* corresponding to VI_PRIORITY */ - priv->stats.txlperr++; - priv->ieee80211->stats.tx_errors++; - rtl8180_tx_isr(dev, LOW_PRIORITY, 1); - rtl8180_try_wake_queue(dev, LOW_PRIORITY); - } - - if (inta & ISR_ROK) { - priv->stats.rxint++; - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & ISR_RQoSOK) { - priv->stats.rxint++; - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & ISR_BcnInt) - rtl8180_prepare_beacon(dev); - - if (inta & ISR_RDU) { - DMESGW("No RX descriptor available"); - priv->stats.rxrdu++; - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & ISR_RXFOVW) { - priv->stats.rxoverflow++; - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & ISR_TXFOVW) - priv->stats.txoverflow++; - - if (inta & ISR_TNPDOK) { /* Normal priority tx ok */ - priv->link_detect.num_tx_ok_in_period++; - priv->stats.txnpokint++; - rtl8180_tx_isr(dev, NORM_PRIORITY, 0); - rtl8180_try_wake_queue(dev, NORM_PRIORITY); - } - - if (inta & ISR_TLPDOK) { /* Low priority tx ok */ - priv->link_detect.num_tx_ok_in_period++; - priv->stats.txlpokint++; - rtl8180_tx_isr(dev, LOW_PRIORITY, 0); - rtl8180_try_wake_queue(dev, LOW_PRIORITY); - } - - if (inta & ISR_TBKDOK) { /* corresponding to BK_PRIORITY */ - priv->stats.txbkpokint++; - priv->link_detect.num_tx_ok_in_period++; - rtl8180_tx_isr(dev, BK_PRIORITY, 0); - rtl8180_try_wake_queue(dev, BE_PRIORITY); - } - - if (inta & ISR_TBEDOK) { /* corresponding to BE_PRIORITY */ - priv->stats.txbeperr++; - priv->link_detect.num_tx_ok_in_period++; - rtl8180_tx_isr(dev, BE_PRIORITY, 0); - rtl8180_try_wake_queue(dev, BE_PRIORITY); - } - force_pci_posting(dev); - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - - return IRQ_HANDLED; -} - -void rtl8180_irq_rx_tasklet(struct r8180_priv *priv) -{ - rtl8180_rx(priv->dev); -} - -void GPIOChangeRFWorkItemCallBack(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of( - work, struct ieee80211_device, GPIOChangeRFWorkItem.work); - struct net_device *dev = ieee->dev; - struct r8180_priv *priv = ieee80211_priv(dev); - u8 btPSR; - u8 btConfig0; - enum rt_rf_power_state eRfPowerStateToSet; - bool bActuallySet = false; - - char *argv[3]; - static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; - static char *envp[] = {"HOME=/", "TERM=linux", - "PATH=/usr/bin:/bin", NULL}; - static int readf_count; - - readf_count = (readf_count+1)%0xffff; - /* We should turn off LED before polling FF51[4]. */ - - /* Turn off LED. */ - btPSR = read_nic_byte(dev, PSR); - write_nic_byte(dev, PSR, (btPSR & ~BIT3)); - - /* It need to delay 4us suggested */ - udelay(4); - - /* HW radio On/Off according to the value of FF51[4](config0) */ - btConfig0 = btPSR = read_nic_byte(dev, CONFIG0); - - eRfPowerStateToSet = (btConfig0 & BIT4) ? RF_ON : RF_OFF; - - /* Turn LED back on when radio enabled */ - if (eRfPowerStateToSet == RF_ON) - write_nic_byte(dev, PSR, btPSR | BIT3); - - if ((priv->ieee80211->bHwRadioOff == true) && - (eRfPowerStateToSet == RF_ON)) { - priv->ieee80211->bHwRadioOff = false; - bActuallySet = true; - } else if ((priv->ieee80211->bHwRadioOff == false) && - (eRfPowerStateToSet == RF_OFF)) { - priv->ieee80211->bHwRadioOff = true; - bActuallySet = true; - } - - if (bActuallySet) { - MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW); - - /* To update the UI status for Power status changed */ - if (priv->ieee80211->bHwRadioOff == true) - argv[1] = "RFOFF"; - else - argv[1] = "RFON"; - argv[0] = RadioPowerPath; - argv[2] = NULL; - - call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC); - } -} - -module_init(rtl8180_pci_module_init); -module_exit(rtl8180_pci_module_exit); diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c deleted file mode 100644 index 8c020e064869..000000000000 --- a/drivers/staging/rtl8187se/r8180_dm.c +++ /dev/null @@ -1,1139 +0,0 @@ -#include "r8180_dm.h" -#include "r8180_hw.h" -#include "r8180_93cx6.h" - - /* Return TRUE if we shall perform High Power Mechanism, FALSE otherwise. */ -#define RATE_ADAPTIVE_TIMER_PERIOD 300 - -bool CheckHighPower(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - - if (!priv->bRegHighPowerMechanism) - return false; - - if (ieee->state == IEEE80211_LINKED_SCANNING) - return false; - - return true; -} - -/* - * Description: - * Update Tx power level if necessary. - * See also DoRxHighPower() and SetTxPowerLevel8185() for reference. - * - * Note: - * The reason why we udpate Tx power level here instead of DoRxHighPower() - * is the number of IO to change Tx power is much more than channel TR switch - * and they are related to OFDM and MAC registers. - * So, we don't want to update it so frequently in per-Rx packet base. - */ -static void DoTxHighPower(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u16 HiPwrUpperTh = 0; - u16 HiPwrLowerTh = 0; - u8 RSSIHiPwrUpperTh; - u8 RSSIHiPwrLowerTh; - u8 u1bTmp; - char OfdmTxPwrIdx, CckTxPwrIdx; - - HiPwrUpperTh = priv->RegHiPwrUpperTh; - HiPwrLowerTh = priv->RegHiPwrLowerTh; - - HiPwrUpperTh = HiPwrUpperTh * 10; - HiPwrLowerTh = HiPwrLowerTh * 10; - RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh; - RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh; - - /* lzm add 080826 */ - OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel]; - CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel]; - - if ((priv->UndecoratedSmoothedSS > HiPwrUpperTh) || - (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) { - /* Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah */ - - priv->bToUpdateTxPwr = true; - u1bTmp = read_nic_byte(dev, CCK_TXAGC); - - /* If it never enter High Power. */ - if (CckTxPwrIdx == u1bTmp) { - u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0; /* 8dbm */ - write_nic_byte(dev, CCK_TXAGC, u1bTmp); - - u1bTmp = read_nic_byte(dev, OFDM_TXAGC); - u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0; /* 8dbm */ - write_nic_byte(dev, OFDM_TXAGC, u1bTmp); - } - - } else if ((priv->UndecoratedSmoothedSS < HiPwrLowerTh) && - (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) { - if (priv->bToUpdateTxPwr) { - priv->bToUpdateTxPwr = false; - /* SD3 required. */ - u1bTmp = read_nic_byte(dev, CCK_TXAGC); - if (u1bTmp < CckTxPwrIdx) { - write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx); - } - - u1bTmp = read_nic_byte(dev, OFDM_TXAGC); - if (u1bTmp < OfdmTxPwrIdx) { - write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx); - } - } - } -} - - -/* - * Description: - * Callback function of UpdateTxPowerWorkItem. - * Because of some event happened, e.g. CCX TPC, High Power Mechanism, - * We update Tx power of current channel again. - */ -void rtl8180_tx_pw_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, tx_pw_wq); - struct net_device *dev = ieee->dev; - - DoTxHighPower(dev); -} - - -/* - * Return TRUE if we shall perform DIG Mechanism, FALSE otherwise. - */ -bool CheckDig(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - - if (!priv->bDigMechanism) - return false; - - if (ieee->state != IEEE80211_LINKED) - return false; - - if ((priv->ieee80211->rate / 5) < 36) /* Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. */ - return false; - return true; -} -/* - * Implementation of DIG for Zebra and Zebra2. - */ -static void DIG_Zebra(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u16 CCKFalseAlarm, OFDMFalseAlarm; - u16 OfdmFA1, OfdmFA2; - int InitialGainStep = 7; /* The number of initial gain stages. */ - int LowestGainStage = 4; /* The capable lowest stage of performing dig workitem. */ - u32 AwakePeriodIn2Sec = 0; - - CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff); - OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff); - OfdmFA1 = 0x15; - OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8; - - /* The number of initial gain steps is different, by Bruce, 2007-04-13. */ - if (priv->InitialGain == 0) { /* autoDIG */ - /* Advised from SD3 DZ */ - priv->InitialGain = 4; /* In 87B, m74dBm means State 4 (m82dBm) */ - } - /* Advised from SD3 DZ */ - OfdmFA1 = 0x20; - -#if 1 /* lzm reserved 080826 */ - AwakePeriodIn2Sec = (2000 - priv->DozePeriodInPast2Sec); - priv->DozePeriodInPast2Sec = 0; - - if (AwakePeriodIn2Sec) { - OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000); - OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000); - } else { - ; - } -#endif - - InitialGainStep = 8; - LowestGainStage = priv->RegBModeGainStage; /* Lowest gain stage. */ - - if (OFDMFalseAlarm > OfdmFA1) { - if (OFDMFalseAlarm > OfdmFA2) { - priv->DIG_NumberFallbackVote++; - if (priv->DIG_NumberFallbackVote > 1) { - /* serious OFDM False Alarm, need fallback */ - if (priv->InitialGain < InitialGainStep) { - priv->InitialGainBackUp = priv->InitialGain; - - priv->InitialGain = (priv->InitialGain + 1); - UpdateInitialGain(dev); - } - priv->DIG_NumberFallbackVote = 0; - priv->DIG_NumberUpgradeVote = 0; - } - } else { - if (priv->DIG_NumberFallbackVote) - priv->DIG_NumberFallbackVote--; - } - priv->DIG_NumberUpgradeVote = 0; - } else { - if (priv->DIG_NumberFallbackVote) - priv->DIG_NumberFallbackVote--; - priv->DIG_NumberUpgradeVote++; - - if (priv->DIG_NumberUpgradeVote > 9) { - if (priv->InitialGain > LowestGainStage) { /* In 87B, m78dBm means State 4 (m864dBm) */ - priv->InitialGainBackUp = priv->InitialGain; - - priv->InitialGain = (priv->InitialGain - 1); - UpdateInitialGain(dev); - } - priv->DIG_NumberFallbackVote = 0; - priv->DIG_NumberUpgradeVote = 0; - } - } -} - -/* - * Dispatch DIG implementation according to RF. - */ -static void DynamicInitGain(struct net_device *dev) -{ - DIG_Zebra(dev); -} - -void rtl8180_hw_dig_wq(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_dig_wq); - struct net_device *dev = ieee->dev; - struct r8180_priv *priv = ieee80211_priv(dev); - - /* Read CCK and OFDM False Alarm. */ - priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM); - - - /* Adjust Initial Gain dynamically. */ - DynamicInitGain(dev); - -} - -static int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate) -{ - u8 rate_len; - u8 rate_ex_len; - u8 RateMask = 0x7F; - u8 idx; - unsigned short Found = 0; - u8 NaiveTxRate = TxRate&RateMask; - - rate_len = priv->ieee80211->current_network.rates_len; - rate_ex_len = priv->ieee80211->current_network.rates_ex_len; - for (idx = 0; idx < rate_len; idx++) { - if ((priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate) { - Found = 1; - goto found_rate; - } - } - for (idx = 0; idx < rate_ex_len; idx++) { - if ((priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate) { - Found = 1; - goto found_rate; - } - } - return Found; -found_rate: - return Found; -} - -/* - * Get the Tx rate one degree up form the input rate in the supported rates. - * Return the upgrade rate if it is successed, otherwise return the input rate. - */ -static u8 GetUpgradeTxRate(struct net_device *dev, u8 rate) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u8 UpRate; - - /* Upgrade 1 degree. */ - switch (rate) { - case 108: /* Up to 54Mbps. */ - UpRate = 108; - break; - - case 96: /* Up to 54Mbps. */ - UpRate = 108; - break; - - case 72: /* Up to 48Mbps. */ - UpRate = 96; - break; - - case 48: /* Up to 36Mbps. */ - UpRate = 72; - break; - - case 36: /* Up to 24Mbps. */ - UpRate = 48; - break; - - case 22: /* Up to 18Mbps. */ - UpRate = 36; - break; - - case 11: /* Up to 11Mbps. */ - UpRate = 22; - break; - - case 4: /* Up to 5.5Mbps. */ - UpRate = 11; - break; - - case 2: /* Up to 2Mbps. */ - UpRate = 4; - break; - - default: - printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate); - return rate; - } - /* Check if the rate is valid. */ - if (IncludedInSupportedRates(priv, UpRate)) { - return UpRate; - } else { - return rate; - } - return rate; -} -/* - * Get the Tx rate one degree down form the input rate in the supported rates. - * Return the degrade rate if it is successed, otherwise return the input rate. - */ - -static u8 GetDegradeTxRate(struct net_device *dev, u8 rate) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u8 DownRate; - - /* Upgrade 1 degree. */ - switch (rate) { - case 108: /* Down to 48Mbps. */ - DownRate = 96; - break; - - case 96: /* Down to 36Mbps. */ - DownRate = 72; - break; - - case 72: /* Down to 24Mbps. */ - DownRate = 48; - break; - - case 48: /* Down to 18Mbps. */ - DownRate = 36; - break; - - case 36: /* Down to 11Mbps. */ - DownRate = 22; - break; - - case 22: /* Down to 5.5Mbps. */ - DownRate = 11; - break; - - case 11: /* Down to 2Mbps. */ - DownRate = 4; - break; - - case 4: /* Down to 1Mbps. */ - DownRate = 2; - break; - - case 2: /* Down to 1Mbps. */ - DownRate = 2; - break; - - default: - printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate); - return rate; - } - /* Check if the rate is valid. */ - if (IncludedInSupportedRates(priv, DownRate)) { - return DownRate; - } else { - return rate; - } - return rate; -} -/* - * Helper function to determine if specified data rate is - * CCK rate. - */ - -static bool MgntIsCckRate(u16 rate) -{ - bool bReturn = false; - - if ((rate <= 22) && (rate != 12) && (rate != 18)) { - bReturn = true; - } - - return bReturn; -} -/* - * Description: - * Tx Power tracking mechanism routine on 87SE. - */ -void TxPwrTracking87SE(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u8 tmpu1Byte, CurrentThermal, Idx; - char CckTxPwrIdx, OfdmTxPwrIdx; - - tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL); - CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */ - CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c : CurrentThermal;/* lzm add 080826 */ - - if (CurrentThermal != priv->ThermalMeter) { - /* Update Tx Power level on each channel. */ - for (Idx = 1; Idx < 15; Idx++) { - CckTxPwrIdx = priv->chtxpwr[Idx]; - OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx]; - - if (CurrentThermal > priv->ThermalMeter) { - /* higher thermal meter. */ - CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2; - OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2; - - if (CckTxPwrIdx > 35) - CckTxPwrIdx = 35; /* Force TxPower to maximal index. */ - if (OfdmTxPwrIdx > 35) - OfdmTxPwrIdx = 35; - } else { - /* lower thermal meter. */ - CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2; - OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2; - - if (CckTxPwrIdx < 0) - CckTxPwrIdx = 0; - if (OfdmTxPwrIdx < 0) - OfdmTxPwrIdx = 0; - } - - /* Update TxPower level on CCK and OFDM resp. */ - priv->chtxpwr[Idx] = CckTxPwrIdx; - priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx; - } - - /* Update TxPower level immediately. */ - rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel); - } - priv->ThermalMeter = CurrentThermal; -} -static void StaRateAdaptive87SE(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - unsigned long CurrTxokCnt; - u16 CurrRetryCnt; - u16 CurrRetryRate; - unsigned long CurrRxokCnt; - bool bTryUp = false; - bool bTryDown = false; - u8 TryUpTh = 1; - u8 TryDownTh = 2; - u32 TxThroughput; - long CurrSignalStrength; - bool bUpdateInitialGain = false; - u8 u1bOfdm = 0, u1bCck = 0; - char OfdmTxPwrIdx, CckTxPwrIdx; - - priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD; - - - CurrRetryCnt = priv->CurrRetryCnt; - CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt; - CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt; - CurrSignalStrength = priv->Stats_RecvSignalPower; - TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes); - priv->LastTxOKBytes = priv->NumTxOkBytesTotal; - priv->CurrentOperaRate = priv->ieee80211->rate / 5; - /* 2 Compute retry ratio. */ - if (CurrTxokCnt > 0) { - CurrRetryRate = (u16)(CurrRetryCnt * 100 / CurrTxokCnt); - } else { - /* It may be serious retry. To distinguish serious retry or no packets modified by Bruce */ - CurrRetryRate = (u16)(CurrRetryCnt * 100 / 1); - } - - priv->LastRetryCnt = priv->CurrRetryCnt; - priv->LastTxokCnt = priv->NumTxOkTotal; - priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal; - priv->CurrRetryCnt = 0; - - /* 2No Tx packets, return to init_rate or not? */ - if (CurrRetryRate == 0 && CurrTxokCnt == 0) { - /* - * After 9 (30*300ms) seconds in this condition, we try to raise rate. - */ - priv->TryupingCountNoData++; - - /* [TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00 */ - if (priv->TryupingCountNoData > 30) { - priv->TryupingCountNoData = 0; - priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate); - /* Reset Fail Record */ - priv->LastFailTxRate = 0; - priv->LastFailTxRateSS = -200; - priv->FailTxRateCount = 0; - } - goto SetInitialGain; - } else { - priv->TryupingCountNoData = 0; /*Reset trying up times. */ - } - - - /* - * For Netgear case, I comment out the following signal strength estimation, - * which can results in lower rate to transmit when sample is NOT enough (e.g. PING request). - * - * Restructure rate adaptive as the following main stages: - * (1) Add retry threshold in 54M upgrading condition with signal strength. - * (2) Add the mechanism to degrade to CCK rate according to signal strength - * and retry rate. - * (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated - * situation, Initial Gain Update is upon on DIG mechanism except CCK rate. - * (4) Add the mechanism of trying to upgrade tx rate. - * (5) Record the information of upping tx rate to avoid trying upping tx rate constantly. - * - */ - - /* - * 11Mbps or 36Mbps - * Check more times in these rate(key rates). - */ - if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72) - TryUpTh += 9; - /* - * Let these rates down more difficult. - */ - if (MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36) - TryDownTh += 1; - - /* 1 Adjust Rate. */ - if (priv->bTryuping == true) { - /* 2 For Test Upgrading mechanism - * Note: - * Sometimes the throughput is upon on the capability between the AP and NIC, - * thus the low data rate does not improve the performance. - * We randomly upgrade the data rate and check if the retry rate is improved. - */ - - /* Upgrading rate did not improve the retry rate, fallback to the original rate. */ - if ((CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput) { - /*Not necessary raising rate, fall back rate. */ - bTryDown = true; - } else { - priv->bTryuping = false; - } - } else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) { - /* - * 2For High Power - * - * Return to highest data rate, if signal strength is good enough. - * SignalStrength threshold(-50dbm) is for RTL8186. - * Revise SignalStrength threshold to -51dbm. - */ - /* Also need to check retry rate for safety, by Bruce, 2007-06-05. */ - if (priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate) { - bTryUp = true; - /* Upgrade Tx Rate directly. */ - priv->TryupingCount += TryUpTh; - } - - } else if (CurrTxokCnt > 9 && CurrTxokCnt < 100 && CurrRetryRate >= 600) { - /* - *2 For Serious Retry - * - * Traffic is not busy but our Tx retry is serious. - */ - bTryDown = true; - /* Let Rate Mechanism to degrade tx rate directly. */ - priv->TryDownCountLowData += TryDownTh; - } else if (priv->CurrentOperaRate == 108) { - /* 2For 54Mbps */ - /* Air Link */ - if ((CurrRetryRate > 26) && (priv->LastRetryRate > 25)) { - bTryDown = true; - } - /* Cable Link */ - else if ((CurrRetryRate > 17) && (priv->LastRetryRate > 16) && (CurrSignalStrength > -72)) { - bTryDown = true; - } - - if (bTryDown && (CurrSignalStrength < -75)) /* cable link */ - priv->TryDownCountLowData += TryDownTh; - } else if (priv->CurrentOperaRate == 96) { - /* 2For 48Mbps */ - /* Air Link */ - if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) { - bTryDown = true; - } else if (((CurrRetryRate > 21) && (priv->LastRetryRate > 20)) && (CurrSignalStrength > -74)) { /* Cable Link */ - /* Down to rate 36Mbps. */ - bTryDown = true; - } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) { - bTryDown = true; - priv->TryDownCountLowData += TryDownTh; - } else if ((CurrRetryRate < 8) && (priv->LastRetryRate < 8)) { /* TO DO: need to consider (RSSI) */ - bTryUp = true; - } - - if (bTryDown && (CurrSignalStrength < -75)) { - priv->TryDownCountLowData += TryDownTh; - } - } else if (priv->CurrentOperaRate == 72) { - /* 2For 36Mbps */ - if ((CurrRetryRate > 43) && (priv->LastRetryRate > 41)) { - /* Down to rate 24Mbps. */ - bTryDown = true; - } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) { - bTryDown = true; - priv->TryDownCountLowData += TryDownTh; - } else if ((CurrRetryRate < 15) && (priv->LastRetryRate < 16)) { /* TO DO: need to consider (RSSI) */ - bTryUp = true; - } - - if (bTryDown && (CurrSignalStrength < -80)) - priv->TryDownCountLowData += TryDownTh; - - } else if (priv->CurrentOperaRate == 48) { - /* 2For 24Mbps */ - /* Air Link */ - if (((CurrRetryRate > 63) && (priv->LastRetryRate > 62))) { - bTryDown = true; - } else if (((CurrRetryRate > 33) && (priv->LastRetryRate > 32)) && (CurrSignalStrength > -82)) { /* Cable Link */ - bTryDown = true; - } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) { - bTryDown = true; - priv->TryDownCountLowData += TryDownTh; - } else if ((CurrRetryRate < 20) && (priv->LastRetryRate < 21)) { /* TO DO: need to consider (RSSI) */ - bTryUp = true; - } - - if (bTryDown && (CurrSignalStrength < -82)) - priv->TryDownCountLowData += TryDownTh; - - } else if (priv->CurrentOperaRate == 36) { - if (((CurrRetryRate > 85) && (priv->LastRetryRate > 86))) { - bTryDown = true; - } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) { - bTryDown = true; - priv->TryDownCountLowData += TryDownTh; - } else if ((CurrRetryRate < 22) && (priv->LastRetryRate < 23)) { /* TO DO: need to consider (RSSI) */ - bTryUp = true; - } - } else if (priv->CurrentOperaRate == 22) { - /* 2For 11Mbps */ - if (CurrRetryRate > 95) { - bTryDown = true; - } else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */ - bTryUp = true; - } - } else if (priv->CurrentOperaRate == 11) { - /* 2For 5.5Mbps */ - if (CurrRetryRate > 149) { - bTryDown = true; - } else if ((CurrRetryRate < 60) && (priv->LastRetryRate < 65)) { - bTryUp = true; - } - } else if (priv->CurrentOperaRate == 4) { - /* 2For 2 Mbps */ - if ((CurrRetryRate > 99) && (priv->LastRetryRate > 99)) { - bTryDown = true; - } else if ((CurrRetryRate < 65) && (priv->LastRetryRate < 70)) { - bTryUp = true; - } - } else if (priv->CurrentOperaRate == 2) { - /* 2For 1 Mbps */ - if ((CurrRetryRate < 70) && (priv->LastRetryRate < 75)) { - bTryUp = true; - } - } - - if (bTryUp && bTryDown) - printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n"); - - /* 1 Test Upgrading Tx Rate - * Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC. - * To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate. - */ - if (!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0) - && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) { - if (jiffies % (CurrRetryRate + 101) == 0) { - bTryUp = true; - priv->bTryuping = true; - } - } - - /* 1 Rate Mechanism */ - if (bTryUp) { - priv->TryupingCount++; - priv->TryDownCountLowData = 0; - - /* - * Check more times if we need to upgrade indeed. - * Because the largest value of pHalData->TryupingCount is 0xFFFF and - * the largest value of pHalData->FailTxRateCount is 0x14, - * this condition will be satisfied at most every 2 min. - */ - - if ((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) || - (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping) { - priv->TryupingCount = 0; - /* - * When transferring from CCK to OFDM, DIG is an important issue. - */ - if (priv->CurrentOperaRate == 22) - bUpdateInitialGain = true; - - /* - * The difference in throughput between 48Mbps and 36Mbps is 8M. - * So, we must be careful in this rate scale. Isaiah 2008-02-15. - */ - if (((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) && - (priv->FailTxRateCount > 2)) - priv->RateAdaptivePeriod = (RATE_ADAPTIVE_TIMER_PERIOD / 2); - - /* (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold. */ - /* (2)If the signal strength is increased, it may be able to upgrade. */ - - priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate); - - if (priv->CurrentOperaRate == 36) { - priv->bUpdateARFR = true; - write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */ - } else if (priv->bUpdateARFR) { - priv->bUpdateARFR = false; - write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */ - } - - /* Update Fail Tx rate and count. */ - if (priv->LastFailTxRate != priv->CurrentOperaRate) { - priv->LastFailTxRate = priv->CurrentOperaRate; - priv->FailTxRateCount = 0; - priv->LastFailTxRateSS = -200; /* Set lowest power. */ - } - } - } else { - if (priv->TryupingCount > 0) - priv->TryupingCount--; - } - - if (bTryDown) { - priv->TryDownCountLowData++; - priv->TryupingCount = 0; - - /* Check if Tx rate can be degraded or Test trying upgrading should fallback. */ - if (priv->TryDownCountLowData > TryDownTh || priv->bTryuping) { - priv->TryDownCountLowData = 0; - priv->bTryuping = false; - /* Update fail information. */ - if (priv->LastFailTxRate == priv->CurrentOperaRate) { - priv->FailTxRateCount++; - /* Record the Tx fail rate signal strength. */ - if (CurrSignalStrength > priv->LastFailTxRateSS) - priv->LastFailTxRateSS = CurrSignalStrength; - } else { - priv->LastFailTxRate = priv->CurrentOperaRate; - priv->FailTxRateCount = 1; - priv->LastFailTxRateSS = CurrSignalStrength; - } - priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate); - - /* Reduce chariot training time at weak signal strength situation. SD3 ED demand. */ - if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72)) { - priv->CurrentOperaRate = 72; - } - - if (priv->CurrentOperaRate == 36) { - priv->bUpdateARFR = true; - write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */ - } else if (priv->bUpdateARFR) { - priv->bUpdateARFR = false; - write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */ - } - - /* - * When it is CCK rate, it may need to update initial gain to receive lower power packets. - */ - if (MgntIsCckRate(priv->CurrentOperaRate)) { - bUpdateInitialGain = true; - } - } - } else { - if (priv->TryDownCountLowData > 0) - priv->TryDownCountLowData--; - } - - /* - * Keep the Tx fail rate count to equal to 0x15 at most. - * Reduce the fail count at least to 10 sec if tx rate is tending stable. - */ - if (priv->FailTxRateCount >= 0x15 || - (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6)) { - priv->FailTxRateCount--; - } - - - OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel]; - CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel]; - - /* Mac0x9e increase 2 level in 36M~18M situation */ - if ((priv->CurrentOperaRate < 96) && (priv->CurrentOperaRate > 22)) { - u1bCck = read_nic_byte(dev, CCK_TXAGC); - u1bOfdm = read_nic_byte(dev, OFDM_TXAGC); - - /* case 1: Never enter High power */ - if (u1bCck == CckTxPwrIdx) { - if (u1bOfdm != (OfdmTxPwrIdx + 2)) { - priv->bEnhanceTxPwr = true; - u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2); - write_nic_byte(dev, OFDM_TXAGC, u1bOfdm); - } - } else if (u1bCck < CckTxPwrIdx) { - /* case 2: enter high power */ - if (!priv->bEnhanceTxPwr) { - priv->bEnhanceTxPwr = true; - u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2); - write_nic_byte(dev, OFDM_TXAGC, u1bOfdm); - } - } - } else if (priv->bEnhanceTxPwr) { /* 54/48/11/5.5/2/1 */ - u1bCck = read_nic_byte(dev, CCK_TXAGC); - u1bOfdm = read_nic_byte(dev, OFDM_TXAGC); - - /* case 1: Never enter High power */ - if (u1bCck == CckTxPwrIdx) { - priv->bEnhanceTxPwr = false; - write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx); - } - /* case 2: enter high power */ - else if (u1bCck < CckTxPwrIdx) { - priv->bEnhanceTxPwr = false; - u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2) : 0; - write_nic_byte(dev, OFDM_TXAGC, u1bOfdm); - } - } - - /* - * We need update initial gain when we set tx rate "from OFDM to CCK" or - * "from CCK to OFDM". - */ -SetInitialGain: - if (bUpdateInitialGain) { - if (MgntIsCckRate(priv->CurrentOperaRate)) { /* CCK */ - if (priv->InitialGain > priv->RegBModeGainStage) { - priv->InitialGainBackUp = priv->InitialGain; - - if (CurrSignalStrength < -85) /* Low power, OFDM [0x17] = 26. */ - /* SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26. */ - priv->InitialGain = priv->RegBModeGainStage; - - else if (priv->InitialGain > priv->RegBModeGainStage + 1) - priv->InitialGain -= 2; - - else - priv->InitialGain--; - - printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate); - UpdateInitialGain(dev); - } - } else { /* OFDM */ - if (priv->InitialGain < 4) { - priv->InitialGainBackUp = priv->InitialGain; - - priv->InitialGain++; - printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate); - UpdateInitialGain(dev); - } - } - } - - /* Record the related info */ - priv->LastRetryRate = CurrRetryRate; - priv->LastTxThroughput = TxThroughput; - priv->ieee80211->rate = priv->CurrentOperaRate * 5; -} - -void rtl8180_rate_adapter(struct work_struct *work) -{ - struct delayed_work *dwork = to_delayed_work(work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, rate_adapter_wq); - struct net_device *dev = ieee->dev; - StaRateAdaptive87SE(dev); -} -void timer_rate_adaptive(unsigned long data) -{ - struct r8180_priv *priv = ieee80211_priv((struct net_device *)data); - if (!priv->up) { - return; - } - if ((priv->ieee80211->iw_mode != IW_MODE_MASTER) - && (priv->ieee80211->state == IEEE80211_LINKED) && - (priv->ForcedDataRate == 0)) { - queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq); - } - priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod); - add_timer(&priv->rateadapter_timer); -} - -void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - priv->AdRxOkCnt++; - - if (priv->AdRxSignalStrength != -1) { - priv->AdRxSignalStrength = ((priv->AdRxSignalStrength * 7) + (SignalStrength * 3)) / 10; - } else { /* Initialization case. */ - priv->AdRxSignalStrength = SignalStrength; - } - - if (priv->LastRxPktAntenna) /* Main antenna. */ - priv->AdMainAntennaRxOkCnt++; - else /* Aux antenna. */ - priv->AdAuxAntennaRxOkCnt++; -} - /* Change Antenna Switch. */ -bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bAntennaSwitched = false; - - switch (u1bAntennaIndex) { - case 0: - /* Mac register, main antenna */ - write_nic_byte(dev, ANTSEL, 0x03); - /* base band */ - write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */ - write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */ - - bAntennaSwitched = true; - break; - - case 1: - /* Mac register, aux antenna */ - write_nic_byte(dev, ANTSEL, 0x00); - /* base band */ - write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */ - write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */ - - bAntennaSwitched = true; - - break; - - default: - printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex); - break; - } - - if (bAntennaSwitched) - priv->CurrAntennaIndex = u1bAntennaIndex; - - return bAntennaSwitched; -} - /* Toggle Antenna switch. */ -bool SwitchAntenna(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - bool bResult; - - if (priv->CurrAntennaIndex == 0) { - bResult = SetAntenna8185(dev, 1); - } else { - bResult = SetAntenna8185(dev, 0); - } - - return bResult; -} -/* - * Engine of SW Antenna Diversity mechanism. - * Since 8187 has no Tx part information, - * this implementation is only dependend on Rx part information. - */ -void SwAntennaDiversity(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bSwCheckSS = false; - if (bSwCheckSS) { - priv->AdTickCount++; - - printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n", - priv->AdTickCount, priv->AdCheckPeriod); - printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n", - priv->AdRxSignalStrength, priv->AdRxSsThreshold); - } - - /* Case 1. No Link. */ - if (priv->ieee80211->state != IEEE80211_LINKED) { - priv->bAdSwitchedChecking = false; - /* I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. */ - SwitchAntenna(dev); - - /* Case 2. Linked but no packet receive.d */ - } else if (priv->AdRxOkCnt == 0) { - priv->bAdSwitchedChecking = false; - SwitchAntenna(dev); - - /* Case 3. Evaluate last antenna switch action and undo it if necessary. */ - } else if (priv->bAdSwitchedChecking == true) { - priv->bAdSwitchedChecking = false; - - /* Adjust Rx signal strength threshold. */ - priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2; - - priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? - priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold; - if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) { - /* Rx signal strength is not improved after we swtiched antenna. => Swich back. */ - /* Increase Antenna Diversity checking period due to bad decision. */ - priv->AdCheckPeriod *= 2; - /* Increase Antenna Diversity checking period. */ - if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod) - priv->AdCheckPeriod = priv->AdMaxCheckPeriod; - - /* Wrong decision => switch back. */ - SwitchAntenna(dev); - } else { - /* Rx Signal Strength is improved. */ - - /* Reset Antenna Diversity checking period to its min value. */ - priv->AdCheckPeriod = priv->AdMinCheckPeriod; - } - - } - /* Case 4. Evaluate if we shall switch antenna now. */ - /* Cause Table Speed is very fast in TRC Dell Lab, we check it every time. */ - else { - priv->AdTickCount = 0; - - /* - * We evaluate RxOk counts for each antenna first and than - * evaluate signal strength. - * The following operation can overcome the disability of CCA on both two antennas - * When signal strength was extremely low or high. - * 2008.01.30. - */ - - /* - * Evaluate RxOk count from each antenna if we shall switch default antenna now. - */ - if ((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt) - && (priv->CurrAntennaIndex == 0)) { - /* We set Main antenna as default but RxOk count was less than Aux ones. */ - - /* Switch to Aux antenna. */ - SwitchAntenna(dev); - priv->bHWAdSwitched = true; - } else if ((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt) - && (priv->CurrAntennaIndex == 1)) { - /* We set Aux antenna as default but RxOk count was less than Main ones. */ - - /* Switch to Main antenna. */ - SwitchAntenna(dev); - priv->bHWAdSwitched = true; - } else { - /* Default antenna is better. */ - - /* Still need to check current signal strength. */ - priv->bHWAdSwitched = false; - } - /* - * We evaluate Rx signal strength ONLY when default antenna - * didn't change by HW evaluation. - * 2008.02.27. - * - * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05 - * For example, Throughput of aux is better than main antenna(about 10M v.s 2M), - * but AdRxSignalStrength is less than main. - * Our guess is that main antenna have lower throughput and get many change - * to receive more CCK packets(ex.Beacon) which have stronger SignalStrength. - */ - if ((!priv->bHWAdSwitched) && (bSwCheckSS)) { - /* Evaluate Rx signal strength if we shall switch antenna now. */ - if (priv->AdRxSignalStrength < priv->AdRxSsThreshold) { - /* Rx signal strength is weak => Switch Antenna. */ - priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength; - priv->bAdSwitchedChecking = true; - - SwitchAntenna(dev); - } else { - /* Rx signal strength is OK. */ - priv->bAdSwitchedChecking = false; - /* Increase Rx signal strength threshold if necessary. */ - if ((priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && /* Signal is much stronger than current threshold */ - priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { /* Current threhold is not yet reach upper limit. */ - - priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2; - priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ? - priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */ - } - - /* Reduce Antenna Diversity checking period if possible. */ - if (priv->AdCheckPeriod > priv->AdMinCheckPeriod) - priv->AdCheckPeriod /= 2; - } - } - } - /* Reset antenna diversity Rx related statistics. */ - priv->AdRxOkCnt = 0; - priv->AdMainAntennaRxOkCnt = 0; - priv->AdAuxAntennaRxOkCnt = 0; -} - - /* Return TRUE if we shall perform Tx Power Tracking Mechanism, FALSE otherwise. */ -bool CheckTxPwrTracking(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - if (!priv->bTxPowerTrack) - return false; - - /* if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah */ - if (priv->bToUpdateTxPwr) - return false; - - return true; -} - - - /* Timer callback function of SW Antenna Diversity. */ -void SwAntennaDiversityTimerCallback(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - enum rt_rf_power_state rtState; - - /* We do NOT need to switch antenna while RF is off. */ - rtState = priv->eRFPowerState; - do { - if (rtState == RF_OFF) { - break; - } else if (rtState == RF_SLEEP) { - /* Don't access BB/RF under Disable PLL situation. */ - break; - } - SwAntennaDiversity(dev); - - } while (false); - - if (priv->up) { - priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD); - add_timer(&priv->SwAntennaDiversityTimer); - } -} - diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h deleted file mode 100644 index cb4046f346ef..000000000000 --- a/drivers/staging/rtl8187se/r8180_dm.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef R8180_DM_H -#define R8180_DM_H - -#include "r8180.h" -/* #include "r8180_hw.h" */ -/* #include "r8180_93cx6.h" */ -void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength); -bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex); -bool SwitchAntenna(struct net_device *dev); -void SwAntennaDiversity(struct net_device *dev); -void SwAntennaDiversityTimerCallback(struct net_device *dev); -bool CheckDig(struct net_device *dev); -bool CheckHighPower(struct net_device *dev); -void rtl8180_hw_dig_wq(struct work_struct *work); -void rtl8180_tx_pw_wq(struct work_struct *work); -void rtl8180_rate_adapter(struct work_struct *work); -void TxPwrTracking87SE(struct net_device *dev); -bool CheckTxPwrTracking(struct net_device *dev); -void rtl8180_rate_adapter(struct work_struct *work); -void timer_rate_adaptive(unsigned long data); - - -#endif diff --git a/drivers/staging/rtl8187se/r8180_hw.h b/drivers/staging/rtl8187se/r8180_hw.h deleted file mode 100644 index e59d74f8ecfc..000000000000 --- a/drivers/staging/rtl8187se/r8180_hw.h +++ /dev/null @@ -1,588 +0,0 @@ -/* - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004-2005 - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official Realtek driver. - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - Parts of this driver are based on the Intel Pro Wireless - 2100 GPL driver. - - We want to tanks the Authors of those projects - and the Ndiswrapper project Authors. -*/ - -/* Mariusz Matuszek added full registers definition with Realtek's name */ - -/* this file contains register definitions for the rtl8180 MAC controller */ -#ifndef R8180_HW -#define R8180_HW - - -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT9 0x00000200 -#define BIT11 0x00000800 -#define BIT13 0x00002000 -#define BIT15 0x00008000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -#define MAX_SLEEP_TIME (10000) -#define MIN_SLEEP_TIME (50) - -#define BB_HOST_BANG_EN (1<<2) -#define BB_HOST_BANG_CLK (1<<1) - -#define MAC0 0 -#define MAC4 4 - -#define CMD 0x37 -#define CMD_RST_SHIFT 4 -#define CMD_RX_ENABLE_SHIFT 3 -#define CMD_TX_ENABLE_SHIFT 2 - -#define EPROM_CMD 0x50 -#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4)) -#define EPROM_CMD_OPERATING_MODE_SHIFT 6 -#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) -#define EPROM_CMD_CONFIG 0x3 -#define EPROM_CMD_NORMAL 0 -#define EPROM_CMD_LOAD 1 -#define EPROM_CMD_PROGRAM 2 -#define EPROM_CS_SHIFT 3 -#define EPROM_CK_SHIFT 2 -#define EPROM_W_SHIFT 1 -#define EPROM_R_SHIFT 0 -#define CONFIG2_DMA_POLLING_MODE_SHIFT 3 - -#define INTA_TXOVERFLOW (1<<15) -#define INTA_TIMEOUT (1<<14) -#define INTA_HIPRIORITYDESCERR (1<<9) -#define INTA_HIPRIORITYDESCOK (1<<8) -#define INTA_NORMPRIORITYDESCERR (1<<7) -#define INTA_NORMPRIORITYDESCOK (1<<6) -#define INTA_RXOVERFLOW (1<<5) -#define INTA_RXDESCERR (1<<4) -#define INTA_LOWPRIORITYDESCERR (1<<3) -#define INTA_LOWPRIORITYDESCOK (1<<2) -#define INTA_RXOK (1) -#define INTA_MASK 0x3c - -#define RXRING_ADDR 0xe4 /* page 0 */ -#define PGSELECT 0x5e -#define PGSELECT_PG_SHIFT 0 -#define RX_CONF 0x44 -#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \ -(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23)) -#define RX_CHECK_BSSID_SHIFT 23 -#define ACCEPT_PWR_FRAME_SHIFT 22 -#define ACCEPT_MNG_FRAME_SHIFT 20 -#define ACCEPT_CTL_FRAME_SHIFT 19 -#define ACCEPT_DATA_FRAME_SHIFT 18 -#define ACCEPT_ICVERR_FRAME_SHIFT 12 -#define ACCEPT_CRCERR_FRAME_SHIFT 5 -#define ACCEPT_BCAST_FRAME_SHIFT 3 -#define ACCEPT_MCAST_FRAME_SHIFT 2 -#define ACCEPT_ALLMAC_FRAME_SHIFT 0 -#define ACCEPT_NICMAC_FRAME_SHIFT 1 - -#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15)) -#define RX_FIFO_THRESHOLD_SHIFT 13 -#define RX_FIFO_THRESHOLD_NONE 7 -#define RX_AUTORESETPHY_SHIFT 28 - -#define TX_CONF 0x40 -#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30 -#define TX_LOOPBACK_SHIFT 17 -#define TX_LOOPBACK_NONE 0 -#define TX_LOOPBACK_CONTINUE 3 -#define TX_LOOPBACK_MASK ((1<<17)|(1<<18)) -#define TX_DPRETRY_SHIFT 0 -#define R8180_MAX_RETRY 255 -#define TX_RTSRETRY_SHIFT 8 -#define TX_NOICV_SHIFT 19 -#define TX_NOCRC_SHIFT 16 -#define TX_DMA_POLLING 0xd9 -#define TX_DMA_POLLING_BEACON_SHIFT 7 -#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6 -#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5 -#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4 -#define TX_MANAGEPRIORITY_RING_ADDR 0x0C -#define TX_BKPRIORITY_RING_ADDR 0x10 -#define TX_BEPRIORITY_RING_ADDR 0x14 -#define TX_VIPRIORITY_RING_ADDR 0x20 -#define TX_VOPRIORITY_RING_ADDR 0x24 -#define TX_HIGHPRIORITY_RING_ADDR 0x28 -#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10)) -#define MAX_RX_DMA_2048 7 -#define MAX_RX_DMA_1024 6 -#define MAX_RX_DMA_SHIFT 10 -#define INT_TIMEOUT 0x48 -#define CONFIG3_CLKRUN_SHIFT 2 -#define CONFIG3_ANAPARAM_W_SHIFT 6 -#define ANAPARAM 0x54 -#define BEACON_INTERVAL 0x70 -#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \ -(1<<6)|(1<<7)|(1<<8)|(1<<9)) -#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \ -(1<<8)|(1<<9)) -#define ATIM 0x72 -#define EPROM_CS_SHIFT 3 -#define EPROM_CK_SHIFT 2 -#define PHY_ADR 0x7c -#define SECURITY 0x5f /* 1209 this is sth wrong */ -#define SECURITY_WEP_TX_ENABLE_SHIFT 1 -#define SECURITY_WEP_RX_ENABLE_SHIFT 0 -#define SECURITY_ENCRYP_104 1 -#define SECURITY_ENCRYP_SHIFT 4 -#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5)) -#define KEY0 0x90 /* 1209 this is sth wrong */ -#define CONFIG2_ANTENNA_SHIFT 6 -#define TX_BEACON_RING_ADDR 0x4c -#define CONFIG0_WEP40_SHIFT 7 -#define CONFIG0_WEP104_SHIFT 6 -#define AGCRESET_SHIFT 5 - - - -/* - * Operational registers offsets in PCI (I/O) space. - * RealTek names are used. - */ - -#define TSFTR 0x0018 - -#define TLPDA 0x0020 - -#define BSSID 0x002E - -#define CR 0x0037 - -#define RF_SW_CONFIG 0x8 /* store data which is transmitted to RF for driver */ -#define RF_SW_CFG_SI BIT1 -#define EIFS 0x2D /* Extended InterFrame Space Timer, in unit of 4 us. */ - -#define BRSR 0x34 /* Basic rate set */ - -#define IMR 0x006C -#define ISR 0x003C - -#define TCR 0x0040 - -#define RCR 0x0044 - -#define TimerInt 0x0048 - -#define CR9346 0x0050 - -#define CONFIG0 0x0051 -#define CONFIG2 0x0053 - -#define MSR 0x0058 - -#define CONFIG3 0x0059 -#define CONFIG4 0x005A - /* SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6 */ - /* Mac0x60 = 0x000004C6 power save parameters */ - #define ANAPARM_ASIC_ON 0xB0054D00 - #define ANAPARM2_ASIC_ON 0x000004C6 - - #define ANAPARM_ON ANAPARM_ASIC_ON - #define ANAPARM2_ON ANAPARM2_ASIC_ON - -#define TESTR 0x005B - -#define PSR 0x005E - -#define BcnItv 0x0070 - -#define AtimWnd 0x0072 - -#define BintrItv 0x0074 - -#define PhyAddr 0x007C -#define PhyDataR 0x007E - -/* following are for rtl8185 */ -#define RFPinsOutput 0x80 -#define RFPinsEnable 0x82 -#define RF_TIMING 0x8c -#define RFPinsSelect 0x84 -#define ANAPARAM2 0x60 -#define RF_PARA 0x88 -#define RFPinsInput 0x86 -#define GP_ENABLE 0x90 -#define GPIO 0x91 -#define SW_CONTROL_GPIO 0x400 -#define TX_ANTENNA 0x9f -#define TX_GAIN_OFDM 0x9e -#define TX_GAIN_CCK 0x9d -#define WPA_CONFIG 0xb0 -#define TX_AGC_CTL 0x9c -#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0 -#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1 -#define TX_AGC_CTL_FEEDBACK_ANT 2 -#define RESP_RATE 0x34 -#define SIFS 0xb4 -#define DIFS 0xb5 - -#define SLOT 0xb6 -#define CW_CONF 0xbc -#define CW_CONF_PERPACKET_RETRY_SHIFT 1 -#define CW_CONF_PERPACKET_CW_SHIFT 0 -#define CW_VAL 0xbd -#define MAX_RESP_RATE_SHIFT 4 -#define MIN_RESP_RATE_SHIFT 0 -#define RATE_FALLBACK 0xbe - -#define CONFIG5 0x00D8 - -#define PHYPR 0xDA /* 0xDA - 0x0B PHY Parameter Register. */ - -#define FEMR 0x1D4 /* Function Event Mask register */ - -#define FFER 0x00FC -#define FFER_END 0x00FF - - - -/* - * Bitmasks for specific register functions. - * Names are derived from the register name and function name. - * - * _[] - * - * this leads to some awkward names... - */ - -#define BRSR_BPLCP ((1 << 8)) -#define BRSR_MBR ((1 << 1)|(1 << 0)) -#define BRSR_MBR_8185 ((1 << 11)|(1 << 10)|(1 << 9)|(1 << 8)|(1 << 7)|(1 << 6)|(1 << 5)|(1 << 4)|(1 << 3)|(1 << 2)|(1 << 1)|(1 << 0)) -#define BRSR_MBR0 ((1 << 0)) -#define BRSR_MBR1 ((1 << 1)) - -#define CR_RST ((1 << 4)) -#define CR_RE ((1 << 3)) -#define CR_TE ((1 << 2)) -#define CR_MulRW ((1 << 0)) - -#define IMR_Dot11hInt ((1 << 25)) /*802.11h Measurement Interrupt */ -#define IMR_BcnDmaInt ((1 << 24)) /*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt??? */ -#define IMR_WakeInt ((1 << 23)) /*Wake Up Interrupt */ -#define IMR_TXFOVW ((1 << 22)) /*Tx FIFO Overflow Interrupt */ -#define IMR_TimeOut1 ((1 << 21)) /*Time Out Interrupt 1 */ -#define IMR_BcnInt ((1 << 20)) /*Beacon Time out Interrupt */ -#define IMR_ATIMInt ((1 << 19)) /*ATIM Time Out Interrupt */ -#define IMR_TBDER ((1 << 18)) /*Tx Beacon Descriptor Error Interrupt */ -#define IMR_TBDOK ((1 << 17)) /*Tx Beacon Descriptor OK Interrupt */ -#define IMR_THPDER ((1 << 16)) /*Tx High Priority Descriptor Error Interrupt */ -#define IMR_THPDOK ((1 << 15)) /*Tx High Priority Descriptor OK Interrupt */ -#define IMR_TVODER ((1 << 14)) /*Tx AC_VO Descriptor Error Interrupt */ -#define IMR_TVODOK ((1 << 13)) /*Tx AC_VO Descriptor OK Interrupt */ -#define IMR_FOVW ((1 << 12)) /*Rx FIFO Overflow Interrupt */ -#define IMR_RDU ((1 << 11)) /*Rx Descriptor Unavailable Interrupt */ -#define IMR_TVIDER ((1 << 10)) /*Tx AC_VI Descriptor Error Interrupt */ -#define IMR_TVIDOK ((1 << 9)) /*Tx AC_VI Descriptor OK Interrupt */ -#define IMR_RER ((1 << 8)) /*Rx Error Interrupt */ -#define IMR_ROK ((1 << 7)) /*Receive OK Interrupt */ -#define IMR_TBEDER ((1 << 6)) /*Tx AC_BE Descriptor Error Interrupt */ -#define IMR_TBEDOK ((1 << 5)) /*Tx AC_BE Descriptor OK Interrupt */ -#define IMR_TBKDER ((1 << 4)) /*Tx AC_BK Descriptor Error Interrupt */ -#define IMR_TBKDOK ((1 << 3)) /*Tx AC_BK Descriptor OK Interrupt */ -#define IMR_RQoSOK ((1 << 2)) /*Rx QoS OK Interrupt */ -#define IMR_TimeOut2 ((1 << 1)) /*Time Out Interrupt 2 */ -#define IMR_TimeOut3 ((1 << 0)) /*Time Out Interrupt 3 */ -#define IMR_TMGDOK ((1 << 30)) -#define ISR_Dot11hInt ((1 << 25)) /*802.11h Measurement Interrupt */ -#define ISR_BcnDmaInt ((1 << 24)) /*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt??? */ -#define ISR_WakeInt ((1 << 23)) /*Wake Up Interrupt */ -#define ISR_TXFOVW ((1 << 22)) /*Tx FIFO Overflow Interrupt */ -#define ISR_TimeOut1 ((1 << 21)) /*Time Out Interrupt 1 */ -#define ISR_BcnInt ((1 << 20)) /*Beacon Time out Interrupt */ -#define ISR_ATIMInt ((1 << 19)) /*ATIM Time Out Interrupt */ -#define ISR_TBDER ((1 << 18)) /*Tx Beacon Descriptor Error Interrupt */ -#define ISR_TBDOK ((1 << 17)) /*Tx Beacon Descriptor OK Interrupt */ -#define ISR_THPDER ((1 << 16)) /*Tx High Priority Descriptor Error Interrupt */ -#define ISR_THPDOK ((1 << 15)) /*Tx High Priority Descriptor OK Interrupt */ -#define ISR_TVODER ((1 << 14)) /*Tx AC_VO Descriptor Error Interrupt */ -#define ISR_TVODOK ((1 << 13)) /*Tx AC_VO Descriptor OK Interrupt */ -#define ISR_FOVW ((1 << 12)) /*Rx FIFO Overflow Interrupt */ -#define ISR_RDU ((1 << 11)) /*Rx Descriptor Unavailable Interrupt */ -#define ISR_TVIDER ((1 << 10)) /*Tx AC_VI Descriptor Error Interrupt */ -#define ISR_TVIDOK ((1 << 9)) /*Tx AC_VI Descriptor OK Interrupt */ -#define ISR_RER ((1 << 8)) /*Rx Error Interrupt */ -#define ISR_ROK ((1 << 7)) /*Receive OK Interrupt */ -#define ISR_TBEDER ((1 << 6)) /*Tx AC_BE Descriptor Error Interrupt */ -#define ISR_TBEDOK ((1 << 5)) /*Tx AC_BE Descriptor OK Interrupt */ -#define ISR_TBKDER ((1 << 4)) /*Tx AC_BK Descriptor Error Interrupt */ -#define ISR_TBKDOK ((1 << 3)) /*Tx AC_BK Descriptor OK Interrupt */ -#define ISR_RQoSOK ((1 << 2)) /*Rx QoS OK Interrupt */ -#define ISR_TimeOut2 ((1 << 1)) /*Time Out Interrupt 2 */ -#define ISR_TimeOut3 ((1 << 0)) /*Time Out Interrupt 3 */ - -/* these definition is used for Tx/Rx test temporarily */ -#define ISR_TLPDER ISR_TVIDER -#define ISR_TLPDOK ISR_TVIDOK -#define ISR_TNPDER ISR_TVODER -#define ISR_TNPDOK ISR_TVODOK -#define ISR_TimeOut ISR_TimeOut1 -#define ISR_RXFOVW ISR_FOVW - - -#define HW_VERID_R8180_F 3 -#define HW_VERID_R8180_ABCD 2 -#define HW_VERID_R8185_ABC 4 -#define HW_VERID_R8185_D 5 -#define HW_VERID_R8185B_B 6 - -#define TCR_CWMIN ((1 << 31)) -#define TCR_SWSEQ ((1 << 30)) -#define TCR_HWVERID_MASK ((1 << 27)|(1 << 26)|(1 << 25)) -#define TCR_HWVERID_SHIFT 25 -#define TCR_SAT ((1 << 24)) -#define TCR_PLCP_LEN TCR_SAT /* rtl8180 */ -#define TCR_MXDMA_MASK ((1 << 23)|(1 << 22)|(1 << 21)) -#define TCR_MXDMA_1024 6 -#define TCR_MXDMA_2048 7 -#define TCR_MXDMA_SHIFT 21 -#define TCR_DISCW ((1 << 20)) -#define TCR_ICV ((1 << 19)) -#define TCR_LBK ((1 << 18)|(1 << 17)) -#define TCR_LBK1 ((1 << 18)) -#define TCR_LBK0 ((1 << 17)) -#define TCR_CRC ((1 << 16)) -#define TCR_DPRETRY_MASK ((1 << 15)|(1 << 14)|(1 << 13)|(1 << 12)|(1 << 11)|(1 << 10)|(1 << 9)|(1 << 8)) -#define TCR_RTSRETRY_MASK ((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)|(1 << 6)|(1 << 7)) -#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 /* rtl8185 */ - -#define RCR_ONLYERLPKT ((1 << 31)) -#define RCR_CS_SHIFT 29 -#define RCR_CS_MASK ((1 << 30) | (1 << 29)) -#define RCR_ENMARP ((1 << 28)) -#define RCR_CBSSID ((1 << 23)) -#define RCR_APWRMGT ((1 << 22)) -#define RCR_ADD3 ((1 << 21)) -#define RCR_AMF ((1 << 20)) -#define RCR_ACF ((1 << 19)) -#define RCR_ADF ((1 << 18)) -#define RCR_RXFTH ((1 << 15)|(1 << 14)|(1 << 13)) -#define RCR_RXFTH2 ((1 << 15)) -#define RCR_RXFTH1 ((1 << 14)) -#define RCR_RXFTH0 ((1 << 13)) -#define RCR_AICV ((1 << 12)) -#define RCR_MXDMA ((1 << 10)|(1 << 9)|(1 << 8)) -#define RCR_MXDMA2 ((1 << 10)) -#define RCR_MXDMA1 ((1 << 9)) -#define RCR_MXDMA0 ((1 << 8)) -#define RCR_9356SEL ((1 << 6)) -#define RCR_ACRC32 ((1 << 5)) -#define RCR_AB ((1 << 3)) -#define RCR_AM ((1 << 2)) -#define RCR_APM ((1 << 1)) -#define RCR_AAP ((1 << 0)) - -#define CR9346_EEM ((1 << 7)|(1 << 6)) -#define CR9346_EEM1 ((1 << 7)) -#define CR9346_EEM0 ((1 << 6)) -#define CR9346_EECS ((1 << 3)) -#define CR9346_EESK ((1 << 2)) -#define CR9346_EED1 ((1 << 1)) -#define CR9346_EED0 ((1 << 0)) - -#define CONFIG3_PARM_En ((1 << 6)) -#define CONFIG3_FuncRegEn ((1 << 1)) - -#define CONFIG4_PWRMGT ((1 << 5)) - -#define MSR_LINK_MASK ((1 << 2)|(1 << 3)) -#define MSR_LINK_MANAGED 2 -#define MSR_LINK_NONE 0 -#define MSR_LINK_SHIFT 2 -#define MSR_LINK_ADHOC 1 -#define MSR_LINK_MASTER 3 - -#define BcnItv_BcnItv (0x01FF) - -#define AtimWnd_AtimWnd (0x01FF) - -#define BintrItv_BintrItv (0x01FF) - -#define FEMR_INTR ((1 << 15)) -#define FEMR_WKUP ((1 << 14)) -#define FEMR_GWAKE ((1 << 4)) - -#define FFER_INTR ((1 << 15)) -#define FFER_GWAKE ((1 << 4)) - -/* Three wire mode. */ -#define SW_THREE_WIRE 0 -#define HW_THREE_WIRE 2 -/* RTL8187S by amy */ -#define HW_THREE_WIRE_PI 5 -#define HW_THREE_WIRE_SI 6 -/* by amy */ -#define TCR_LRL_OFFSET 0 -#define TCR_SRL_OFFSET 8 -#define TCR_MXDMA_OFFSET 21 -#define TCR_DISReqQsize_OFFSET 28 -#define TCR_DurProcMode_OFFSET 30 - -#define RCR_MXDMA_OFFSET 8 -#define RCR_FIFO_OFFSET 13 - -#define AckTimeOutReg 0x79 /* ACK timeout register, in unit of 4 us. */ - -#define RFTiming 0x8C - -#define TPPollStop 0x93 - -#define TXAGC_CTL 0x9C /*< RJ_TODO_8185B> TX_AGC_CONTROL (0x9C seems be removed at 8185B, see p37). */ -#define CCK_TXAGC 0x9D -#define OFDM_TXAGC 0x9E -#define ANTSEL 0x9F - -#define ACM_CONTROL 0x00BF /* ACM Control Registe */ - -#define IntMig 0xE2 /* Interrupt Migration (0xE2 ~ 0xE3) */ - -#define TID_AC_MAP 0xE8 /* TID to AC Mapping Register */ - -#define ANAPARAM3 0xEE /* How to use it? */ - -#define AC_VO_PARAM 0xF0 /* AC_VO Parameters Record */ -#define AC_VI_PARAM 0xF4 /* AC_VI Parameters Record */ -#define AC_BE_PARAM 0xF8 /* AC_BE Parameters Record */ -#define AC_BK_PARAM 0xFC /* AC_BK Parameters Record */ - -#define GPIOCtrl 0x16B /*GPIO Control Register. */ -#define ARFR 0x1E0 /* Auto Rate Fallback Register (0x1e0 ~ 0x1e2) */ - -#define RFSW_CTRL 0x272 /* 0x272-0x273. */ -#define SW_3W_DB0 0x274 /* Software 3-wire data buffer bit 31~0. */ -#define SW_3W_DB1 0x278 /* Software 3-wire data buffer bit 63~32. */ -#define SW_3W_CMD0 0x27C /* Software 3-wire Control/Status Register. */ -#define SW_3W_CMD1 0x27D /* Software 3-wire Control/Status Register. */ - -#define PI_DATA_READ 0X360 /* 0x360 - 0x361 Parallel Interface Data Register. */ -#define SI_DATA_READ 0x362 /* 0x362 - 0x363 Serial Interface Data Register. */ - -/* ----------------------------------------------------------------------------- - 8185B TPPollStop bits (offset 0x93, 1 byte) ----------------------------------------------------------------------------- -*/ -#define TPPOLLSTOP_BQ (0x01 << 7) -#define TPPOLLSTOP_AC_VIQ (0x01 << 4) - -#define MSR_LINK_ENEDCA (1<<4) - -/* ----------------------------------------------------------------------------- - 8187B AC_XX_PARAM bits ----------------------------------------------------------------------------- -*/ -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 -#define AC_PARAM_ECW_MAX_OFFSET 12 -#define AC_PARAM_ECW_MIN_OFFSET 8 -#define AC_PARAM_AIFS_OFFSET 0 - -/* ----------------------------------------------------------------------------- - 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte) ----------------------------------------------------------------------------- -*/ -#define VOQ_ACM_EN (0x01 << 7) /*BIT7 */ -#define VIQ_ACM_EN (0x01 << 6) /*BIT6 */ -#define BEQ_ACM_EN (0x01 << 5) /*BIT5 */ -#define ACM_HW_EN (0x01 << 4) /*BIT4 */ -#define VOQ_ACM_CTL (0x01 << 2) /*BIT2 */ /* Set to 1 when AC_VO used time reaches or exceeds the admitted time */ -#define VIQ_ACM_CTL (0x01 << 1) /*BIT1 */ /* Set to 1 when AC_VI used time reaches or exceeds the admitted time */ -#define BEQ_ACM_CTL (0x01 << 0) /*BIT0 */ /* Set to 1 when AC_BE used time reaches or exceeds the admitted time */ - - -/* ----------------------------------------------------------------------------- - 8185B SW_3W_CMD bits (Offset 0x27C-0x27D, 16bit) ----------------------------------------------------------------------------- -*/ -#define SW_3W_CMD0_HOLD ((1 << 7)) -#define SW_3W_CMD1_RE ((1 << 0)) /* BIT8 */ -#define SW_3W_CMD1_WE ((1 << 1)) /* BIT9 */ -#define SW_3W_CMD1_DONE ((1 << 2)) /* BIT10 */ - -#define BB_HOST_BANG_RW (1 << 3) - -/* ----------------------------------------------------------------------------- - 8185B RATE_FALLBACK_CTL bits (Offset 0xBE, 8bit) ----------------------------------------------------------------------------- -*/ -#define RATE_FALLBACK_CTL_ENABLE ((1 << 7)) -#define RATE_FALLBACK_CTL_ENABLE_RTSCTS ((1 << 6)) -/* Auto rate fallback per 2^n retry. */ -#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00 -#define RATE_FALLBACK_CTL_AUTO_STEP1 0x01 -#define RATE_FALLBACK_CTL_AUTO_STEP2 0x02 -#define RATE_FALLBACK_CTL_AUTO_STEP3 0x03 - - -#define RTL8225z2_ANAPARAM_OFF 0x55480658 -#define RTL8225z2_ANAPARAM2_OFF 0x72003f70 -/* by amy for power save */ -#define RF_CHANGE_BY_HW BIT30 -#define RF_CHANGE_BY_PS BIT29 -#define RF_CHANGE_BY_IPS BIT28 -/* by amy for power save */ -/* by amy for antenna */ -#define EEPROM_SW_REVD_OFFSET 0x3f - -/* BIT[8-9] is for SW Antenna Diversity. - * Only the value EEPROM_SW_AD_ENABLE means enable, other values are disable. - */ -#define EEPROM_SW_AD_MASK 0x0300 -#define EEPROM_SW_AD_ENABLE 0x0100 - -/* BIT[10-11] determine if Antenna 1 is the Default Antenna. - * Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE. - */ -#define EEPROM_DEF_ANT_MASK 0x0C00 -#define EEPROM_DEF_ANT_1 0x0400 -/*by amy for antenna */ -/* {by amy 080312 */ -/* 0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10. */ -#define EEPROM_RSV 0x7C -#define EEPROM_XTAL_CAL_XOUT_MASK 0x0F /* 0x7C[3:0], Crystal calibration for Xout. */ -#define EEPROM_XTAL_CAL_XIN_MASK 0xF0 /* 0x7C[7:4], Crystal calibration for Xin. */ -#define EEPROM_THERMAL_METER_MASK 0x0F00 /* 0x7D[3:0], Thermal meter reference level. */ -#define EEPROM_XTAL_CAL_ENABLE 0x1000 /* 0x7D[4], Crystal calibration enabled/disabled BIT. */ -#define EEPROM_THERMAL_METER_ENABLE 0x2000 /* 0x7D[5], Thermal meter enabled/disabled BIT. */ -#define EN_LPF_CAL 0x238 /* Enable LPF Calibration. */ -#define PWR_METER_EN BIT1 -/* where are false alarm counters in 8185B? */ -#define CCK_FALSE_ALARM 0xD0 -/* by amy 080312} */ - -/* YJ,add for Country IE, 080630 */ -#define EEPROM_COUNTRY_CODE 0x2E -/* YJ,add,080630,end */ - -#endif diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h deleted file mode 100644 index 7df73927b3cc..000000000000 --- a/drivers/staging/rtl8187se/r8180_rtl8225.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This is part of the rtl8180-sa2400 driver released under the GPL (See file - * COPYING for details). - * - * Copyright (c) 2005 Andrea Merello - * - * This files contains programming code for the rtl8225 radio frontend. - * - * *Many* thanks to Realtek Corp. for their great support! - */ - -#include "r8180.h" - -#define RTL8225_ANAPARAM_ON 0xa0000b59 -#define RTL8225_ANAPARAM_OFF 0xa00beb59 -#define RTL8225_ANAPARAM2_OFF 0x840dec11 -#define RTL8225_ANAPARAM2_ON 0x860dec11 -#define RTL8225_ANAPARAM_SLEEP 0xa00bab59 -#define RTL8225_ANAPARAM2_SLEEP 0x840dec11 - -void rtl8225z2_rf_init(struct net_device *dev); -void rtl8225z2_rf_set_chan(struct net_device *dev, short ch); -void rtl8225z2_rf_close(struct net_device *dev); - -void RF_WriteReg(struct net_device *dev, u8 offset, u16 data); -u16 RF_ReadReg(struct net_device *dev, u8 offset); - -void rtl8180_set_mode(struct net_device *dev, int mode); -void rtl8180_set_mode(struct net_device *dev, int mode); -bool SetZebraRFPowerState8185(struct net_device *dev, - enum rt_rf_power_state eRFPowerState); -void rtl8225z4_rf_sleep(struct net_device *dev); -void rtl8225z4_rf_wakeup(struct net_device *dev); - diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c deleted file mode 100644 index 47104fa05c55..000000000000 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ /dev/null @@ -1,811 +0,0 @@ -/* - * This is part of the rtl8180-sa2400 driver - * released under the GPL (See file COPYING for details). - * Copyright (c) 2005 Andrea Merello - * - * This files contains programming code for the rtl8225 - * radio frontend. - * - * *Many* thanks to Realtek Corp. for their great support! - */ - -#include "r8180_hw.h" -#include "r8180_rtl8225.h" -#include "r8180_93cx6.h" - -#include "ieee80211/dot11d.h" - -static void write_rtl8225(struct net_device *dev, u8 adr, u16 data) -{ - int i; - u16 out, select; - u8 bit; - u32 bangdata = (data << 4) | (adr & 0xf); - - out = read_nic_word(dev, RFPinsOutput) & 0xfff3; - - write_nic_word(dev, RFPinsEnable, - (read_nic_word(dev, RFPinsEnable) | 0x7)); - - select = read_nic_word(dev, RFPinsSelect); - - write_nic_word(dev, RFPinsSelect, select | 0x7 | - SW_CONTROL_GPIO); - - force_pci_posting(dev); - udelay(10); - - write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN); - - force_pci_posting(dev); - udelay(2); - - write_nic_word(dev, RFPinsOutput, out); - - force_pci_posting(dev); - udelay(10); - - for (i = 15; i >= 0; i--) { - bit = (bangdata & (1 << i)) >> i; - - write_nic_word(dev, RFPinsOutput, bit | out); - - write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); - write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); - - i--; - bit = (bangdata & (1 << i)) >> i; - - write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); - write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK); - - write_nic_word(dev, RFPinsOutput, bit | out); - - } - - write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN); - - force_pci_posting(dev); - udelay(10); - - write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN); - - write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO); - - rtl8185_rf_pins_enable(dev); -} - -static const u8 rtl8225_agc[] = { - 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, - 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, - 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, - 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, - 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, - 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, - 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, - 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, - 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, - 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, - 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, - 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, - 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, -}; - -static const u32 rtl8225_chan[] = { - 0, - 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380, - 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A, -}; - -static const u8 rtl8225z2_gain_bg[] = { - 0x23, 0x15, 0xa5, /* -82-1dBm */ - 0x23, 0x15, 0xb5, /* -82-2dBm */ - 0x23, 0x15, 0xc5, /* -82-3dBm */ - 0x33, 0x15, 0xc5, /* -78dBm */ - 0x43, 0x15, 0xc5, /* -74dBm */ - 0x53, 0x15, 0xc5, /* -70dBm */ - 0x63, 0x15, 0xc5, /* -66dBm */ -}; - -static const u8 rtl8225z2_gain_a[] = { - 0x13, 0x27, 0x5a, /* -82dBm */ - 0x23, 0x23, 0x58, /* -82dBm */ - 0x33, 0x1f, 0x56, /* -82dBm */ - 0x43, 0x1b, 0x54, /* -78dBm */ - 0x53, 0x17, 0x51, /* -74dBm */ - 0x63, 0x24, 0x4f, /* -70dBm */ - 0x73, 0x0f, 0x4c, /* -66dBm */ -}; - -static const u16 rtl8225z2_rxgain[] = { - 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, - 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, - 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, - 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, - 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, - 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, - 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, - 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, - 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, - 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, - 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, - 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb - -}; - -static void rtl8225z2_set_gain(struct net_device *dev, short gain) -{ - const u8 *rtl8225_gain; - struct r8180_priv *priv = ieee80211_priv(dev); - u8 mode = priv->ieee80211->mode; - - if (mode == IEEE_B || mode == IEEE_G) - rtl8225_gain = rtl8225z2_gain_bg; - else - rtl8225_gain = rtl8225z2_gain_a; - - write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]); - write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]); - write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]); - write_phy_ofdm(dev, 0x21, 0x37); -} - -static u32 read_rtl8225(struct net_device *dev, u8 adr) -{ - u32 data2Write = ((u32)(adr & 0x1f)) << 27; - u32 dataRead; - u32 mask; - u16 oval, oval2, oval3, tmp; - int i; - short bit, rw; - u8 wLength = 6; - u8 rLength = 12; - u8 low2high = 0; - - oval = read_nic_word(dev, RFPinsOutput); - oval2 = read_nic_word(dev, RFPinsEnable); - oval3 = read_nic_word(dev, RFPinsSelect); - - write_nic_word(dev, RFPinsEnable, (oval2|0xf)); - write_nic_word(dev, RFPinsSelect, (oval3|0xf)); - - dataRead = 0; - - oval &= ~0xf; - - write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN); - udelay(4); - - write_nic_word(dev, RFPinsOutput, oval); - udelay(5); - - rw = 0; - - mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1)); - - for (i = 0; i < wLength/2; i++) { - bit = ((data2Write&mask) != 0) ? 1 : 0; - write_nic_word(dev, RFPinsOutput, bit | oval | rw); - udelay(1); - - write_nic_word(dev, RFPinsOutput, - bit | oval | BB_HOST_BANG_CLK | rw); - udelay(2); - write_nic_word(dev, RFPinsOutput, - bit | oval | BB_HOST_BANG_CLK | rw); - udelay(2); - - mask = (low2high) ? (mask<<1) : (mask>>1); - - if (i == 2) { - rw = BB_HOST_BANG_RW; - write_nic_word(dev, RFPinsOutput, - bit | oval | BB_HOST_BANG_CLK | rw); - udelay(2); - write_nic_word(dev, RFPinsOutput, bit | oval | rw); - udelay(2); - break; - } - - bit = ((data2Write&mask) != 0) ? 1 : 0; - - write_nic_word(dev, RFPinsOutput, - oval | bit | rw | BB_HOST_BANG_CLK); - udelay(2); - write_nic_word(dev, RFPinsOutput, - oval | bit | rw | BB_HOST_BANG_CLK); - udelay(2); - - write_nic_word(dev, RFPinsOutput, oval | bit | rw); - udelay(1); - - mask = (low2high) ? (mask<<1) : (mask>>1); - } - - write_nic_word(dev, RFPinsOutput, rw|oval); - udelay(2); - mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1)); - - /* - * We must set data pin to HW controlled, otherwise RF can't driver it - * and value RF register won't be able to read back properly. - */ - write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01))); - - for (i = 0; i < rLength; i++) { - write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1); - - write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); - udelay(2); - write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); - udelay(2); - write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); - udelay(2); - tmp = read_nic_word(dev, RFPinsInput); - - dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0); - - write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2); - - mask = (low2high) ? (mask<<1) : (mask>>1); - } - - write_nic_word(dev, RFPinsOutput, - BB_HOST_BANG_EN | BB_HOST_BANG_RW | oval); - udelay(2); - - write_nic_word(dev, RFPinsEnable, oval2); - write_nic_word(dev, RFPinsSelect, oval3); /* Set To SW Switch */ - write_nic_word(dev, RFPinsOutput, 0x3a0); - - return dataRead; -} - -void rtl8225z2_rf_close(struct net_device *dev) -{ - RF_WriteReg(dev, 0x4, 0x1f); - - force_pci_posting(dev); - mdelay(1); - - rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF); - rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF); -} - -/* - * Map dBm into Tx power index according to current HW model, for example, - * RF and PA, and current wireless mode. - */ -static s8 DbmToTxPwrIdx(struct r8180_priv *priv, - enum wireless_mode mode, s32 PowerInDbm) -{ - bool bUseDefault = true; - s8 TxPwrIdx = 0; - - /* - * OFDM Power in dBm = Index * 0.5 + 0 - * CCK Power in dBm = Index * 0.25 + 13 - */ - s32 tmp = 0; - - if (mode == WIRELESS_MODE_G) { - bUseDefault = false; - tmp = (2 * PowerInDbm); - - if (tmp < 0) - TxPwrIdx = 0; - else if (tmp > 40) /* 40 means 20 dBm. */ - TxPwrIdx = 40; - else - TxPwrIdx = (s8)tmp; - } else if (mode == WIRELESS_MODE_B) { - bUseDefault = false; - tmp = (4 * PowerInDbm) - 52; - - if (tmp < 0) - TxPwrIdx = 0; - else if (tmp > 28) /* 28 means 20 dBm. */ - TxPwrIdx = 28; - else - TxPwrIdx = (s8)tmp; - } - - /* - * TRUE if we want to use a default implementation. - * We shall set it to FALSE when we have exact translation formula - * for target IC. 070622, by rcnjko. - */ - if (bUseDefault) { - if (PowerInDbm < 0) - TxPwrIdx = 0; - else if (PowerInDbm > 35) - TxPwrIdx = 35; - else - TxPwrIdx = (u8)PowerInDbm; - } - - return TxPwrIdx; -} - -void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u8 max_cck_power_level; - u8 max_ofdm_power_level; - u8 min_ofdm_power_level; - char cck_power_level = (char)(0xff & priv->chtxpwr[ch]); - char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]); - - if (IS_DOT11D_ENABLE(priv->ieee80211) && - IS_DOT11D_STATE_DONE(priv->ieee80211)) { - u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch); - u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, - MaxTxPwrInDbm); - u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, - MaxTxPwrInDbm); - - if (cck_power_level > CckMaxPwrIdx) - cck_power_level = CckMaxPwrIdx; - if (ofdm_power_level > OfdmMaxPwrIdx) - ofdm_power_level = OfdmMaxPwrIdx; - } - - max_cck_power_level = 15; - max_ofdm_power_level = 25; - min_ofdm_power_level = 10; - - if (cck_power_level > 35) - cck_power_level = 35; - - write_nic_byte(dev, CCK_TXAGC, cck_power_level); - force_pci_posting(dev); - mdelay(1); - - if (ofdm_power_level > 35) - ofdm_power_level = 35; - - if (priv->up == 0) { - write_phy_ofdm(dev, 2, 0x42); - write_phy_ofdm(dev, 5, 0x00); - write_phy_ofdm(dev, 6, 0x40); - write_phy_ofdm(dev, 7, 0x00); - write_phy_ofdm(dev, 8, 0x40); - } - - write_nic_byte(dev, OFDM_TXAGC, ofdm_power_level); - - if (ofdm_power_level <= 11) { - write_phy_ofdm(dev, 0x07, 0x5c); - write_phy_ofdm(dev, 0x09, 0x5c); - } - - if (ofdm_power_level <= 17) { - write_phy_ofdm(dev, 0x07, 0x54); - write_phy_ofdm(dev, 0x09, 0x54); - } else { - write_phy_ofdm(dev, 0x07, 0x50); - write_phy_ofdm(dev, 0x09, 0x50); - } - - force_pci_posting(dev); - mdelay(1); -} - -void rtl8225z2_rf_set_chan(struct net_device *dev, short ch) -{ - rtl8225z2_SetTXPowerLevel(dev, ch); - - RF_WriteReg(dev, 0x7, rtl8225_chan[ch]); - - if ((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch]) - RF_WriteReg(dev, 0x7, rtl8225_chan[ch]); - - mdelay(1); - - force_pci_posting(dev); - mdelay(10); -} - -static void rtl8225_host_pci_init(struct net_device *dev) -{ - write_nic_word(dev, RFPinsOutput, 0x480); - - rtl8185_rf_pins_enable(dev); - - write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); - - write_nic_byte(dev, GP_ENABLE, 0); - - force_pci_posting(dev); - mdelay(200); - - /* bit 6 is for RF on/off detection */ - write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6))); -} - -void rtl8225z2_rf_init(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int i; - short channel = 1; - u16 brsr; - u32 data; - - priv->chan = channel; - - rtl8225_host_pci_init(dev); - - write_nic_dword(dev, RF_TIMING, 0x000a8008); - - brsr = read_nic_word(dev, BRSR); - - write_nic_word(dev, BRSR, 0xffff); - - write_nic_dword(dev, RF_PARA, 0x100044); - - rtl8180_set_mode(dev, EPROM_CMD_CONFIG); - write_nic_byte(dev, CONFIG3, 0x44); - rtl8180_set_mode(dev, EPROM_CMD_NORMAL); - - rtl8185_rf_pins_enable(dev); - - write_rtl8225(dev, 0x0, 0x2bf); mdelay(1); - write_rtl8225(dev, 0x1, 0xee0); mdelay(1); - write_rtl8225(dev, 0x2, 0x44d); mdelay(1); - write_rtl8225(dev, 0x3, 0x441); mdelay(1); - write_rtl8225(dev, 0x4, 0x8c3); mdelay(1); - write_rtl8225(dev, 0x5, 0xc72); mdelay(1); - write_rtl8225(dev, 0x6, 0xe6); mdelay(1); - write_rtl8225(dev, 0x7, rtl8225_chan[channel]); mdelay(1); - write_rtl8225(dev, 0x8, 0x3f); mdelay(1); - write_rtl8225(dev, 0x9, 0x335); mdelay(1); - write_rtl8225(dev, 0xa, 0x9d4); mdelay(1); - write_rtl8225(dev, 0xb, 0x7bb); mdelay(1); - write_rtl8225(dev, 0xc, 0x850); mdelay(1); - write_rtl8225(dev, 0xd, 0xcdf); mdelay(1); - write_rtl8225(dev, 0xe, 0x2b); mdelay(1); - write_rtl8225(dev, 0xf, 0x114); - - mdelay(100); - - write_rtl8225(dev, 0x0, 0x1b7); - - for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { - write_rtl8225(dev, 0x1, i + 1); - write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]); - } - - write_rtl8225(dev, 0x3, 0x80); - write_rtl8225(dev, 0x5, 0x4); - - write_rtl8225(dev, 0x0, 0xb7); - - write_rtl8225(dev, 0x2, 0xc4d); - - /* FIXME!! rtl8187 we have to check if calibrarion - * is successful and eventually cal. again (repeat - * the two write on reg 2) - */ - data = read_rtl8225(dev, 6); - if (!(data & 0x00000080)) { - write_rtl8225(dev, 0x02, 0x0c4d); - force_pci_posting(dev); mdelay(200); - write_rtl8225(dev, 0x02, 0x044d); - force_pci_posting(dev); mdelay(100); - data = read_rtl8225(dev, 6); - if (!(data & 0x00000080)) - DMESGW("RF Calibration Failed!!!!\n"); - } - - mdelay(200); - - write_rtl8225(dev, 0x0, 0x2bf); - - for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { - write_phy_ofdm(dev, 0xb, rtl8225_agc[i]); - mdelay(1); - - /* enable writing AGC table */ - write_phy_ofdm(dev, 0xa, i + 0x80); - mdelay(1); - } - - force_pci_posting(dev); - mdelay(1); - - write_phy_ofdm(dev, 0x00, 0x01); mdelay(1); - write_phy_ofdm(dev, 0x01, 0x02); mdelay(1); - write_phy_ofdm(dev, 0x02, 0x62); mdelay(1); - write_phy_ofdm(dev, 0x03, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x04, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x05, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x06, 0x40); mdelay(1); - write_phy_ofdm(dev, 0x07, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x08, 0x40); mdelay(1); - write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1); - write_phy_ofdm(dev, 0x0a, 0x08); mdelay(1); - write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1); - write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1); - write_phy_ofdm(dev, 0x0d, 0x43); - write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1); - write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1); - write_phy_ofdm(dev, 0x10, 0x84); mdelay(1); - write_phy_ofdm(dev, 0x11, 0x07); mdelay(1); - write_phy_ofdm(dev, 0x12, 0x20); mdelay(1); - write_phy_ofdm(dev, 0x13, 0x20); mdelay(1); - write_phy_ofdm(dev, 0x14, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x15, 0x40); mdelay(1); - write_phy_ofdm(dev, 0x16, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x17, 0x40); mdelay(1); - write_phy_ofdm(dev, 0x18, 0xef); mdelay(1); - write_phy_ofdm(dev, 0x19, 0x19); mdelay(1); - write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1); - write_phy_ofdm(dev, 0x1b, 0x15); mdelay(1); - write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1); - write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1); - write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1); - write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1); - write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1); - write_phy_ofdm(dev, 0x21, 0x17); mdelay(1); - write_phy_ofdm(dev, 0x22, 0x16); mdelay(1); - write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME maybe not needed */ - write_phy_ofdm(dev, 0x24, 0x46); mdelay(1); - write_phy_ofdm(dev, 0x25, 0x00); mdelay(1); - write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); - write_phy_ofdm(dev, 0x27, 0x88); mdelay(1); - - rtl8225z2_set_gain(dev, 4); - - write_phy_cck(dev, 0x0, 0x98); mdelay(1); - write_phy_cck(dev, 0x3, 0x20); mdelay(1); - write_phy_cck(dev, 0x4, 0x7e); mdelay(1); - write_phy_cck(dev, 0x5, 0x12); mdelay(1); - write_phy_cck(dev, 0x6, 0xfc); mdelay(1); - write_phy_cck(dev, 0x7, 0x78); mdelay(1); - write_phy_cck(dev, 0x8, 0x2e); mdelay(1); - write_phy_cck(dev, 0x10, 0x93); mdelay(1); - write_phy_cck(dev, 0x11, 0x88); mdelay(1); - write_phy_cck(dev, 0x12, 0x47); mdelay(1); - write_phy_cck(dev, 0x13, 0xd0); - write_phy_cck(dev, 0x19, 0x00); - write_phy_cck(dev, 0x1a, 0xa0); - write_phy_cck(dev, 0x1b, 0x08); - write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */ - write_phy_cck(dev, 0x41, 0x8d); mdelay(1); - write_phy_cck(dev, 0x42, 0x15); mdelay(1); - write_phy_cck(dev, 0x43, 0x18); mdelay(1); - write_phy_cck(dev, 0x44, 0x36); mdelay(1); - write_phy_cck(dev, 0x45, 0x35); mdelay(1); - write_phy_cck(dev, 0x46, 0x2e); mdelay(1); - write_phy_cck(dev, 0x47, 0x25); mdelay(1); - write_phy_cck(dev, 0x48, 0x1c); mdelay(1); - write_phy_cck(dev, 0x49, 0x12); mdelay(1); - write_phy_cck(dev, 0x4a, 0x09); mdelay(1); - write_phy_cck(dev, 0x4b, 0x04); mdelay(1); - write_phy_cck(dev, 0x4c, 0x05); mdelay(1); - - write_nic_byte(dev, 0x5b, 0x0d); mdelay(1); - - rtl8225z2_SetTXPowerLevel(dev, channel); - - /* RX antenna default to A */ - write_phy_cck(dev, 0x11, 0x9b); mdelay(1); /* B: 0xDB */ - write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* B: 0x10 */ - - rtl8185_tx_antenna(dev, 0x03); /* B: 0x00 */ - - /* switch to high-speed 3-wire - * last digit. 2 for both cck and ofdm - */ - write_nic_dword(dev, 0x94, 0x15c00002); - rtl8185_rf_pins_enable(dev); - - rtl8225z2_rf_set_chan(dev, priv->chan); -} - -#define MAX_DOZE_WAITING_TIMES_85B 20 -#define MAX_POLLING_24F_TIMES_87SE 10 -#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5 - -bool SetZebraRFPowerState8185(struct net_device *dev, - enum rt_rf_power_state eRFPowerState) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u8 btCR9346, btConfig3; - bool bActionAllowed = true, bTurnOffBB = true; - u8 u1bTmp; - int i; - bool bResult = true; - u8 QueueID; - - if (priv->SetRFPowerStateInProgress == true) - return false; - - priv->SetRFPowerStateInProgress = true; - - btCR9346 = read_nic_byte(dev, CR9346); - write_nic_byte(dev, CR9346, (btCR9346 | 0xC0)); - - btConfig3 = read_nic_byte(dev, CONFIG3); - write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En)); - - switch (eRFPowerState) { - case RF_ON: - write_nic_word(dev, 0x37C, 0x00EC); - - /* turn on AFE */ - write_nic_byte(dev, 0x54, 0x00); - write_nic_byte(dev, 0x62, 0x00); - - /* turn on RF */ - RF_WriteReg(dev, 0x0, 0x009f); udelay(500); - RF_WriteReg(dev, 0x4, 0x0972); udelay(500); - - /* turn on RF again */ - RF_WriteReg(dev, 0x0, 0x009f); udelay(500); - RF_WriteReg(dev, 0x4, 0x0972); udelay(500); - - /* turn on BB */ - write_phy_ofdm(dev, 0x10, 0x40); - write_phy_ofdm(dev, 0x12, 0x40); - - /* Avoid power down at init time. */ - write_nic_byte(dev, CONFIG4, priv->RFProgType); - - u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6)))); - break; - case RF_SLEEP: - for (QueueID = 0, i = 0; QueueID < 6;) { - if (get_curr_tx_free_desc(dev, QueueID) == - priv->txringcount) { - QueueID++; - continue; - } else { - priv->TxPollingTimes++; - if (priv->TxPollingTimes >= - LPS_MAX_SLEEP_WAITING_TIMES_87SE) { - bActionAllowed = false; - break; - } else - udelay(10); - } - } - - if (bActionAllowed) { - /* turn off BB RXIQ matrix to cut off rx signal */ - write_phy_ofdm(dev, 0x10, 0x00); - write_phy_ofdm(dev, 0x12, 0x00); - - /* turn off RF */ - RF_WriteReg(dev, 0x4, 0x0000); - RF_WriteReg(dev, 0x0, 0x0000); - - /* turn off AFE except PLL */ - write_nic_byte(dev, 0x62, 0xff); - write_nic_byte(dev, 0x54, 0xec); - - mdelay(1); - - { - int i = 0; - while (true) { - u8 tmp24F = read_nic_byte(dev, 0x24f); - - if ((tmp24F == 0x01) || - (tmp24F == 0x09)) { - bTurnOffBB = true; - break; - } else { - udelay(10); - i++; - priv->TxPollingTimes++; - - if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) { - bTurnOffBB = false; - break; - } else - udelay(10); - } - } - } - - if (bTurnOffBB) { - /* turn off BB */ - u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, - (u1bTmp | BIT5 | BIT6)); - - /* turn off AFE PLL */ - write_nic_byte(dev, 0x54, 0xFC); - write_nic_word(dev, 0x37C, 0x00FC); - } - } - break; - case RF_OFF: - for (QueueID = 0, i = 0; QueueID < 6;) { - if (get_curr_tx_free_desc(dev, QueueID) == - priv->txringcount) { - QueueID++; - continue; - } else { - udelay(10); - i++; - } - - if (i >= MAX_DOZE_WAITING_TIMES_85B) - break; - } - - /* turn off BB RXIQ matrix to cut off rx signal */ - write_phy_ofdm(dev, 0x10, 0x00); - write_phy_ofdm(dev, 0x12, 0x00); - - /* turn off RF */ - RF_WriteReg(dev, 0x4, 0x0000); - RF_WriteReg(dev, 0x0, 0x0000); - - /* turn off AFE except PLL */ - write_nic_byte(dev, 0x62, 0xff); - write_nic_byte(dev, 0x54, 0xec); - - mdelay(1); - - { - int i = 0; - - while (true) { - u8 tmp24F = read_nic_byte(dev, 0x24f); - - if ((tmp24F == 0x01) || (tmp24F == 0x09)) { - bTurnOffBB = true; - break; - } else { - bTurnOffBB = false; - udelay(10); - i++; - } - - if (i > MAX_POLLING_24F_TIMES_87SE) - break; - } - } - - if (bTurnOffBB) { - /* turn off BB */ - u1bTmp = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6)); - - /* turn off AFE PLL (80M) */ - write_nic_byte(dev, 0x54, 0xFC); - write_nic_word(dev, 0x37C, 0x00FC); - } - break; - } - - btConfig3 &= ~(CONFIG3_PARM_En); - write_nic_byte(dev, CONFIG3, btConfig3); - - btCR9346 &= ~(0xC0); - write_nic_byte(dev, CR9346, btCR9346); - - if (bResult && bActionAllowed) - priv->eRFPowerState = eRFPowerState; - - priv->SetRFPowerStateInProgress = false; - - return bResult && bActionAllowed; -} - -void rtl8225z4_rf_sleep(struct net_device *dev) -{ - MgntActSet_RF_State(dev, RF_SLEEP, RF_CHANGE_BY_PS); -} - -void rtl8225z4_rf_wakeup(struct net_device *dev) -{ - MgntActSet_RF_State(dev, RF_ON, RF_CHANGE_BY_PS); -} diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c deleted file mode 100644 index b55249170f18..000000000000 --- a/drivers/staging/rtl8187se/r8180_wx.c +++ /dev/null @@ -1,1409 +0,0 @@ -/* - This file contains wireless extension handlers. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004-2005 - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part - of the official realtek driver. - - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - - We want to thanks the Authors of those projects and the Ndiswrapper - project Authors. -*/ - - -#include "r8180.h" -#include "r8180_hw.h" - -#include -#include "ieee80211/dot11d.h" - -static u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, - 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; - -#define RATE_COUNT ARRAY_SIZE(rtl8180_rates) - -static struct rtl8187se_channel_list default_channel_plan[] = { - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* FCC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* IC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* ETSI */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Spain. Change to ETSI. */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* France. Change to ETSI. */ - {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* MKK */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, 56, 60, 64}, 22}, /* MKK1 */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */ - {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14} /* For Global Domain. 1-11:active scan, 12-14 passive scan.*/ /* +YJ, 080626 */ -}; -static int r8180_wx_get_freq(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b); -} - - -static int r8180_wx_set_key(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct iw_point *erq = &(wrqu->encoding); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - if (erq->length > 0) { - u32 *tkey = (u32 *) key; - priv->key0[0] = tkey[0]; - priv->key0[1] = tkey[1]; - priv->key0[2] = tkey[2]; - priv->key0[3] = tkey[3] & 0xff; - DMESG("Setting wep key to %x %x %x %x", - tkey[0], tkey[1], tkey[2], tkey[3]); - rtl8180_set_hw_wep(dev); - } - return 0; -} - - -static int r8180_wx_set_beaconinterval(struct net_device *dev, - struct iw_request_info *aa, - union iwreq_data *wrqu, char *b) -{ - int *parms = (int *)b; - int bi = parms[0]; - - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - DMESG("setting beacon interval to %x", bi); - - priv->ieee80211->current_network.beacon_interval = bi; - rtl8180_commit(dev); - up(&priv->wx_sem); - - return 0; -} - - - -static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b); -} - - - -static int r8180_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra); -} - - - -static int r8180_wx_set_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra); - - up(&priv->wx_sem); - - return ret; -} - - -static int r8180_wx_set_crcmon(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int *parms = (int *)extra; - int enable = (parms[0] > 0); - short prev = priv->crcmon; - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - if (enable) - priv->crcmon = 1; - else - priv->crcmon = 0; - - DMESG("bad CRC in monitor mode are %s", - priv->crcmon ? "accepted" : "rejected"); - - if (prev != priv->crcmon && priv->up) { - rtl8180_down(dev); - rtl8180_up(dev); - } - - up(&priv->wx_sem); - - return 0; -} - - -static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret; - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - if (priv->bInactivePs) { - if (wrqu->mode == IW_MODE_ADHOC) - IPSLeave(dev); - } - ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b); - - up(&priv->wx_sem); - return ret; -} - -/* YJ,add,080819,for hidden ap */ -struct iw_range_with_scan_capa { - /* Informative stuff (to choose between different interface) */ - - __u32 throughput; /* To give an idea... */ - - /* In theory this value should be the maximum benchmarked - * TCP/IP throughput, because with most of these devices the - * bit rate is meaningless (overhead an co) to estimate how - * fast the connection will go and pick the fastest one. - * I suggest people to play with Netperf or any benchmark... - */ - - /* NWID (or domain id) */ - __u32 min_nwid; /* Minimal NWID we are able to set */ - __u32 max_nwid; /* Maximal NWID we are able to set */ - - /* Old Frequency (backward compat - moved lower ) */ - __u16 old_num_channels; - __u8 old_num_frequency; - - /* Scan capabilities */ - __u8 scan_capa; -}; -/* YJ,add,080819,for hidden ap */ - - -static int rtl8180_wx_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - struct r8180_priv *priv = ieee80211_priv(dev); - u16 val; - int i; - - wrqu->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - - /* Let's try to keep this struct in the same order as in - * linux/include/wireless.h - */ - - /* TODO: See what values we can set, and remove the ones we can't - * set, or fill them with some default data. - */ - - /* ~5 Mb/s real (802.11b) */ - range->throughput = 5 * 1000 * 1000; - - /* TODO: Not used in 802.11b? */ -/* range->min_nwid; */ /* Minimal NWID we are able to set */ - /* TODO: Not used in 802.11b? */ -/* range->max_nwid; */ /* Maximal NWID we are able to set */ - - /* Old Frequency (backward compat - moved lower ) */ -/* range->old_num_channels; */ -/* range->old_num_frequency; */ -/* range->old_freq[6]; */ /* Filler to keep "version" at the same offset */ - if (priv->rf_set_sens != NULL) - range->sensitivity = priv->max_sens; /* signal level threshold range */ - - range->max_qual.qual = 100; - /* TODO: Find real max RSSI and stick here */ - range->max_qual.level = 0; - range->max_qual.noise = -98; - range->max_qual.updated = 7; /* Updated all three */ - - range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ - range->avg_qual.level = 20 + -98; - range->avg_qual.noise = 0; - range->avg_qual.updated = 7; /* Updated all three */ - - range->num_bitrates = RATE_COUNT; - - for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) - range->bitrate[i] = rtl8180_rates[i]; - - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->pm_capa = 0; - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 16; - - range->num_channels = 14; - - for (i = 0, val = 0; i < 14; i++) { - - /* Include only legal frequencies for some countries */ - if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { - range->freq[val].i = i + 1; - range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; - range->freq[val].e = 1; - val++; - } else { - /* FIXME: do we need to set anything for channels */ - /* we don't use ? */ - } - - if (val == IW_MAX_FREQUENCIES) - break; - } - - range->num_frequency = val; - range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | - IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; - - return 0; -} - - -static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret; - struct ieee80211_device *ieee = priv->ieee80211; - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { - struct iw_scan_req *req = (struct iw_scan_req *)b; - if (req->essid_len) { - ieee->current_network.ssid_len = req->essid_len; - memcpy(ieee->current_network.ssid, req->essid, req->essid_len); - } - } - - down(&priv->wx_sem); - if (priv->up) { - priv->ieee80211->actscanning = true; - if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) { - IPSLeave(dev); - ieee80211_softmac_ips_scan_syncro(priv->ieee80211); - ret = 0; - } else { - /* prevent scan in BusyTraffic */ - /* FIXME: Need to consider last scan time */ - if ((priv->link_detect.b_busy_traffic) && (true)) { - ret = 0; - printk("Now traffic is busy, please try later!\n"); - } else - /* prevent scan in BusyTraffic,end */ - ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b); - } - } else - ret = -1; - - up(&priv->wx_sem); - - return ret; -} - - -static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - down(&priv->wx_sem); - if (priv->up) - ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b); - else - ret = -1; - - up(&priv->wx_sem); - return ret; -} - - -static int r8180_wx_set_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - int ret; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - if (priv->bInactivePs) - IPSLeave(dev); - - ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b); - - up(&priv->wx_sem); - return ret; -} - - -static int r8180_wx_get_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - down(&priv->wx_sem); - - ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); - - up(&priv->wx_sem); - - return ret; -} - - -static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); - - up(&priv->wx_sem); - return ret; -} - - -static int r8180_wx_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); -} - -static int r8180_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - if (wrqu->frag.disabled) - priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - else { - if (wrqu->frag.value < MIN_FRAG_THRESHOLD || - wrqu->frag.value > MAX_FRAG_THRESHOLD) - return -EINVAL; - - priv->ieee80211->fts = wrqu->frag.value & ~0x1; - } - - return 0; -} - - -static int r8180_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - wrqu->frag.value = priv->ieee80211->fts; - wrqu->frag.fixed = 0; /* no auto select */ - wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); - - return 0; -} - - -static int r8180_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, char *extra) -{ - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra); - - up(&priv->wx_sem); - return ret; - -} - - -static int r8180_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra); -} - - -static int r8180_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - - down(&priv->wx_sem); - - if (priv->hw_wep) - ret = r8180_wx_set_key(dev, info, wrqu, key); - else { - DMESG("Setting SW wep key"); - ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key); - } - - up(&priv->wx_sem); - return ret; -} - - -static int r8180_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); -} - - -static int r8180_wx_set_scan_type(struct net_device *dev, - struct iw_request_info *aa, - union iwreq_data *wrqu, char *p) -{ - - struct r8180_priv *priv = ieee80211_priv(dev); - int *parms = (int *)p; - int mode = parms[0]; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - priv->ieee80211->active_scan = mode; - - return 1; -} - -static int r8180_wx_set_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int err = 0; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - if (wrqu->retry.flags & IW_RETRY_LIFETIME || - wrqu->retry.disabled) { - err = -EINVAL; - goto exit; - } - if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { - err = -EINVAL; - goto exit; - } - - if (wrqu->retry.value > R8180_MAX_RETRY) { - err = -EINVAL; - goto exit; - } - if (wrqu->retry.flags & IW_RETRY_MAX) { - priv->retry_rts = wrqu->retry.value; - DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); - - } else { - priv->retry_data = wrqu->retry.value; - DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); - } - - /* FIXME ! - * We might try to write directly the TX config register - * or to restart just the (R)TX process. - * I'm unsure if whole reset is really needed - */ - - rtl8180_commit(dev); -exit: - up(&priv->wx_sem); - - return err; -} - -static int r8180_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - - wrqu->retry.disabled = 0; /* can't be disabled */ - - if ((wrqu->retry.flags & IW_RETRY_TYPE) == - IW_RETRY_LIFETIME) - return -EINVAL; - - if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - wrqu->retry.value = priv->retry_rts; - } else { - wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN; - wrqu->retry.value = priv->retry_data; - } - - return 0; -} - -static int r8180_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - if (priv->rf_set_sens == NULL) - return -1; /* we have not this support for this radio */ - wrqu->sens.value = priv->sens; - return 0; -} - - -static int r8180_wx_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - - struct r8180_priv *priv = ieee80211_priv(dev); - - short err = 0; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - if (priv->rf_set_sens == NULL) { - err = -1; /* we have not this support for this radio */ - goto exit; - } - if (priv->rf_set_sens(dev, wrqu->sens.value) == 0) - priv->sens = wrqu->sens.value; - else - err = -EINVAL; - -exit: - up(&priv->wx_sem); - - return err; -} - - -static int r8180_wx_set_rawtx(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); - - up(&priv->wx_sem); - - return ret; - -} - -static int r8180_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - down(&priv->wx_sem); - - ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra); - - up(&priv->wx_sem); - - return ret; -} - -static int r8180_wx_set_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8180_priv *priv = ieee80211_priv(dev); - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags); - if (wrqu->power.disabled == 0) { - wrqu->power.flags |= IW_POWER_ALL_R; - wrqu->power.flags |= IW_POWER_TIMEOUT; - wrqu->power.value = 1000; - } - - ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra); - - up(&priv->wx_sem); - - return ret; -} - -static int r8180_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - if (wrqu->rts.disabled) - priv->rts = DEFAULT_RTS_THRESHOLD; - else { - if (wrqu->rts.value < MIN_RTS_THRESHOLD || - wrqu->rts.value > MAX_RTS_THRESHOLD) - return -EINVAL; - - priv->rts = wrqu->rts.value; - } - - return 0; -} -static int r8180_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - - - wrqu->rts.value = priv->rts; - wrqu->rts.fixed = 0; /* no auto select */ - wrqu->rts.disabled = (wrqu->rts.value == 0); - - return 0; -} -static int dummy(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - return -1; -} - -static int r8180_wx_get_iwmode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee; - int ret = 0; - - - - down(&priv->wx_sem); - - ieee = priv->ieee80211; - - strcpy(extra, "802.11"); - if (ieee->modulation & IEEE80211_CCK_MODULATION) { - strcat(extra, "b"); - if (ieee->modulation & IEEE80211_OFDM_MODULATION) - strcat(extra, "/g"); - } else if (ieee->modulation & IEEE80211_OFDM_MODULATION) - strcat(extra, "g"); - - up(&priv->wx_sem); - - return ret; -} -static int r8180_wx_set_iwmode(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - int *param = (int *)extra; - int ret = 0; - int modulation = 0, mode = 0; - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - if (*param == 1) { - modulation |= IEEE80211_CCK_MODULATION; - mode = IEEE_B; - printk(KERN_INFO "B mode!\n"); - } else if (*param == 2) { - modulation |= IEEE80211_OFDM_MODULATION; - mode = IEEE_G; - printk(KERN_INFO "G mode!\n"); - } else if (*param == 3) { - modulation |= IEEE80211_CCK_MODULATION; - modulation |= IEEE80211_OFDM_MODULATION; - mode = IEEE_B|IEEE_G; - printk(KERN_INFO "B/G mode!\n"); - } - - if (ieee->proto_started) { - ieee80211_stop_protocol(ieee); - ieee->mode = mode; - ieee->modulation = modulation; - ieee80211_start_protocol(ieee); - } else { - ieee->mode = mode; - ieee->modulation = modulation; - } - - up(&priv->wx_sem); - - return ret; -} -static int r8180_wx_get_preamble(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - - - down(&priv->wx_sem); - - - - *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */ - up(&priv->wx_sem); - - return 0; -} -static int r8180_wx_set_preamble(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret = 0; - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - if (*extra < 0 || *extra > 2) - ret = -1; - else - priv->plcp_preamble_mode = *((short *)extra); - - - - up(&priv->wx_sem); - - return ret; -} -static int r8180_wx_get_siglevel(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret = 0; - - - - down(&priv->wx_sem); - /* Modify by hikaru 6.5 */ - *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */ - - - - up(&priv->wx_sem); - - return ret; -} -static int r8180_wx_get_sigqual(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret = 0; - - - - down(&priv->wx_sem); - /* Modify by hikaru 6.5 */ - *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */ - - - - up(&priv->wx_sem); - - return ret; -} -static int r8180_wx_reset_stats(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - down(&priv->wx_sem); - - priv->stats.txrdu = 0; - priv->stats.rxrdu = 0; - priv->stats.rxnolast = 0; - priv->stats.rxnodata = 0; - priv->stats.rxnopointer = 0; - priv->stats.txnperr = 0; - priv->stats.txresumed = 0; - priv->stats.rxerr = 0; - priv->stats.rxoverflow = 0; - priv->stats.rxint = 0; - - priv->stats.txnpokint = 0; - priv->stats.txhpokint = 0; - priv->stats.txhperr = 0; - priv->stats.ints = 0; - priv->stats.shints = 0; - priv->stats.txoverflow = 0; - priv->stats.rxdmafail = 0; - priv->stats.txbeacon = 0; - priv->stats.txbeaconerr = 0; - priv->stats.txlpokint = 0; - priv->stats.txlperr = 0; - priv->stats.txretry = 0;/* 20060601 */ - priv->stats.rxcrcerrmin = 0 ; - priv->stats.rxcrcerrmid = 0; - priv->stats.rxcrcerrmax = 0; - priv->stats.rxicverr = 0; - - up(&priv->wx_sem); - - return 0; - -} -static int r8180_wx_radio_on(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - - down(&priv->wx_sem); - priv->rf_wakeup(dev); - - up(&priv->wx_sem); - - return 0; - -} - -static int r8180_wx_radio_off(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - - down(&priv->wx_sem); - priv->rf_sleep(dev); - - up(&priv->wx_sem); - - return 0; - -} -static int r8180_wx_get_channelplan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - - - - down(&priv->wx_sem); - *extra = priv->channel_plan; - - - - up(&priv->wx_sem); - - return 0; -} -static int r8180_wx_set_channelplan(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int *val = (int *)extra; - int i; - printk("-----in fun %s\n", __func__); - - if (priv->ieee80211->bHwRadioOff) - return 0; - - /* unsigned long flags; */ - down(&priv->wx_sem); - if (default_channel_plan[*val].len != 0) { - priv->channel_plan = *val; - /* Clear old channel map 8 */ - for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) - GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0; - - /* Set new channel map */ - for (i = 1; i <= default_channel_plan[*val].len; i++) - GET_DOT11D_INFO(priv->ieee80211)->channel_map[default_channel_plan[*val].channel[i-1]] = 1; - - } - up(&priv->wx_sem); - - return 0; -} - -static int r8180_wx_get_version(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - /* struct ieee80211_device *ieee; */ - - down(&priv->wx_sem); - strcpy(extra, "1020.0808"); - up(&priv->wx_sem); - - return 0; -} - -/* added by amy 080818 */ -/*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */ -static int r8180_wx_set_forcerate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - u8 forcerate = *extra; - - down(&priv->wx_sem); - - printk("==============>%s(): forcerate is %d\n", __func__, forcerate); - if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) || - (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) || - (forcerate == 96) || (forcerate == 108)) { - priv->ForcedDataRate = 1; - priv->ieee80211->rate = forcerate * 5; - } else if (forcerate == 0) { - priv->ForcedDataRate = 0; - printk("OK! return rate adaptive\n"); - } else - printk("ERR: wrong rate\n"); - up(&priv->wx_sem); - return 0; -} - -static int r8180_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - - struct r8180_priv *priv = ieee80211_priv(dev); - - int ret = 0; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra); - up(&priv->wx_sem); - return ret; - -} -static int r8180_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - int ret = 0; - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra); - up(&priv->wx_sem); - return ret; -} - -static int r8180_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct r8180_priv *priv = ieee80211_priv(dev); - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - - down(&priv->wx_sem); -#if 1 - ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); -#endif - up(&priv->wx_sem); - return ret; -} -static int r8180_wx_set_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct r8180_priv *priv = ieee80211_priv(dev); - - - if (priv->ieee80211->bHwRadioOff) - return 0; - - down(&priv->wx_sem); -#if 1 - ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length); -#endif - up(&priv->wx_sem); - return ret; - - -} - -static const iw_handler r8180_wx_handlers[] = { - IW_HANDLER(SIOCGIWNAME, r8180_wx_get_name), - IW_HANDLER(SIOCSIWNWID, dummy), - IW_HANDLER(SIOCGIWNWID, dummy), - IW_HANDLER(SIOCSIWFREQ, r8180_wx_set_freq), - IW_HANDLER(SIOCGIWFREQ, r8180_wx_get_freq), - IW_HANDLER(SIOCSIWMODE, r8180_wx_set_mode), - IW_HANDLER(SIOCGIWMODE, r8180_wx_get_mode), - IW_HANDLER(SIOCSIWSENS, r8180_wx_set_sens), - IW_HANDLER(SIOCGIWSENS, r8180_wx_get_sens), - IW_HANDLER(SIOCGIWRANGE, rtl8180_wx_get_range), - IW_HANDLER(SIOCSIWSPY, dummy), - IW_HANDLER(SIOCGIWSPY, dummy), - IW_HANDLER(SIOCSIWAP, r8180_wx_set_wap), - IW_HANDLER(SIOCGIWAP, r8180_wx_get_wap), - IW_HANDLER(SIOCSIWMLME, r8180_wx_set_mlme), - IW_HANDLER(SIOCGIWAPLIST, dummy), /* deprecated */ - IW_HANDLER(SIOCSIWSCAN, r8180_wx_set_scan), - IW_HANDLER(SIOCGIWSCAN, r8180_wx_get_scan), - IW_HANDLER(SIOCSIWESSID, r8180_wx_set_essid), - IW_HANDLER(SIOCGIWESSID, r8180_wx_get_essid), - IW_HANDLER(SIOCSIWNICKN, dummy), - IW_HANDLER(SIOCGIWNICKN, dummy), - IW_HANDLER(SIOCSIWRATE, r8180_wx_set_rate), - IW_HANDLER(SIOCGIWRATE, r8180_wx_get_rate), - IW_HANDLER(SIOCSIWRTS, r8180_wx_set_rts), - IW_HANDLER(SIOCGIWRTS, r8180_wx_get_rts), - IW_HANDLER(SIOCSIWFRAG, r8180_wx_set_frag), - IW_HANDLER(SIOCGIWFRAG, r8180_wx_get_frag), - IW_HANDLER(SIOCSIWTXPOW, dummy), - IW_HANDLER(SIOCGIWTXPOW, dummy), - IW_HANDLER(SIOCSIWRETRY, r8180_wx_set_retry), - IW_HANDLER(SIOCGIWRETRY, r8180_wx_get_retry), - IW_HANDLER(SIOCSIWENCODE, r8180_wx_set_enc), - IW_HANDLER(SIOCGIWENCODE, r8180_wx_get_enc), - IW_HANDLER(SIOCSIWPOWER, r8180_wx_set_power), - IW_HANDLER(SIOCGIWPOWER, r8180_wx_get_power), - IW_HANDLER(SIOCSIWGENIE, r8180_wx_set_gen_ie), - IW_HANDLER(SIOCSIWAUTH, r8180_wx_set_auth), - IW_HANDLER(SIOCSIWENCODEEXT, r8180_wx_set_enc_ext), -}; - -static const struct iw_priv_args r8180_private_args[] = { - { - SIOCIWFIRSTPRIV + 0x0, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" - }, - { SIOCIWFIRSTPRIV + 0x1, - 0, 0, "dummy" - - }, - { - SIOCIWFIRSTPRIV + 0x2, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint" - }, - { SIOCIWFIRSTPRIV + 0x3, - 0, 0, "dummy" - - }, - { - SIOCIWFIRSTPRIV + 0x4, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" - - }, - { SIOCIWFIRSTPRIV + 0x5, - 0, 0, "dummy" - - }, - { - SIOCIWFIRSTPRIV + 0x6, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" - - }, - { SIOCIWFIRSTPRIV + 0x7, - 0, 0, "dummy" - - }, - { - SIOCIWFIRSTPRIV + 0x8, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode" - }, - { - SIOCIWFIRSTPRIV + 0x9, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode" - }, - { - SIOCIWFIRSTPRIV + 0xA, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble" - }, - { - SIOCIWFIRSTPRIV + 0xB, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble" - }, - { SIOCIWFIRSTPRIV + 0xC, - 0, 0, "dummy" - }, - { - SIOCIWFIRSTPRIV + 0xD, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi" - }, - { SIOCIWFIRSTPRIV + 0xE, - 0, 0, "dummy" - }, - { - SIOCIWFIRSTPRIV + 0xF, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual" - }, - { - SIOCIWFIRSTPRIV + 0x10, - 0, 0, "resetstats" - }, - { - SIOCIWFIRSTPRIV + 0x11, - 0, 0, "dummy" - }, - { - SIOCIWFIRSTPRIV + 0x12, - 0, 0, "radioon" - }, - { - SIOCIWFIRSTPRIV + 0x13, - 0, 0, "radiooff" - }, - { - SIOCIWFIRSTPRIV + 0x14, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel" - }, - { - SIOCIWFIRSTPRIV + 0x15, - 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel" - }, - { - SIOCIWFIRSTPRIV + 0x16, - 0, 0, "dummy" - }, - { - SIOCIWFIRSTPRIV + 0x17, - 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion" - }, - { - SIOCIWFIRSTPRIV + 0x18, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate" - }, -}; - - -static iw_handler r8180_private_handler[] = { - r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ - dummy, - r8180_wx_set_beaconinterval, - dummy, - /* r8180_wx_set_monitor_type, */ - r8180_wx_set_scan_type, - dummy, - r8180_wx_set_rawtx, - dummy, - r8180_wx_set_iwmode, - r8180_wx_get_iwmode, - r8180_wx_set_preamble, - r8180_wx_get_preamble, - dummy, - r8180_wx_get_siglevel, - dummy, - r8180_wx_get_sigqual, - r8180_wx_reset_stats, - dummy,/* r8180_wx_get_stats */ - r8180_wx_radio_on, - r8180_wx_radio_off, - r8180_wx_set_channelplan, - r8180_wx_get_channelplan, - dummy, - r8180_wx_get_version, - r8180_wx_set_forcerate, -}; - -static inline int is_same_network(struct ieee80211_network *src, - struct ieee80211_network *dst, - struct ieee80211_device *ieee) -{ - /* A network is only a duplicate if the channel, BSSID, ESSID - * and the capability field (in particular IBSS and BSS) all match. - * We treat all with the same BSSID and channel - * as one network - */ - if (src->channel != dst->channel) - return 0; - - if (memcmp(src->bssid, dst->bssid, ETH_ALEN) != 0) - return 0; - - if (ieee->iw_mode != IW_MODE_INFRA) { - if (src->ssid_len != dst->ssid_len) - return 0; - if (memcmp(src->ssid, dst->ssid, src->ssid_len) != 0) - return 0; - } - - if ((src->capability & WLAN_CAPABILITY_IBSS) != - (dst->capability & WLAN_CAPABILITY_IBSS)) - return 0; - if ((src->capability & WLAN_CAPABILITY_BSS) != - (dst->capability & WLAN_CAPABILITY_BSS)) - return 0; - - return 1; -} - -/* WB modified to show signal to GUI on 18-01-2008 */ -static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - struct iw_statistics *wstats = &priv->wstats; - int tmp_level = 0; - int tmp_qual = 0; - int tmp_noise = 0; - - if (ieee->state < IEEE80211_LINKED) { - wstats->qual.qual = 0; - wstats->qual.level = 0; - wstats->qual.noise = 0; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; - } - - tmp_level = (&ieee->current_network)->stats.signal; - tmp_qual = (&ieee->current_network)->stats.signalstrength; - tmp_noise = (&ieee->current_network)->stats.noise; - - wstats->qual.level = tmp_level; - wstats->qual.qual = tmp_qual; - wstats->qual.noise = tmp_noise; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; -} - -struct iw_handler_def r8180_wx_handlers_def = { - .standard = r8180_wx_handlers, - .num_standard = ARRAY_SIZE(r8180_wx_handlers), - .private = r8180_private_handler, - .num_private = ARRAY_SIZE(r8180_private_handler), - .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args), - .get_wireless_stats = r8180_get_wireless_stats, - .private_args = (struct iw_priv_args *)r8180_private_args, -}; - - diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h deleted file mode 100644 index d471520ac772..000000000000 --- a/drivers/staging/rtl8187se/r8180_wx.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - This is part of rtl8180 OpenSource driver - v 0.3 - Copyright (C) Andrea Merello 2004 - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the official realtek driver - Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to thanks the Authors of such projects and the Ndiswrapper project Authors. -*/ - -/* this file (will) contains wireless extension handlers*/ - -#ifndef R8180_WX_H -#define R8180_WX_H -#include -#include "ieee80211/ieee80211.h" -extern struct iw_handler_def r8180_wx_handlers_def; - -#endif diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c deleted file mode 100644 index cc6f100814f3..000000000000 --- a/drivers/staging/rtl8187se/r8185b_init.c +++ /dev/null @@ -1,1464 +0,0 @@ -/* - * Copyright (c) Realtek Semiconductor Corp. All rights reserved. - * - * Module Name: - * r8185b_init.c - * - * Abstract: - * Hardware Initialization and Hardware IO for RTL8185B - * - * Major Change History: - * When Who What - * ---------- --------------- ------------------------------- - * 2006-11-15 Xiong Created - * - * Notes: - * This file is ported from RTL8185B Windows driver. - * - * - */ - -/*--------------------------Include File------------------------------------*/ -#include -#include "r8180_hw.h" -#include "r8180.h" -#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */ -#include "r8180_93cx6.h" /* Card EEPROM */ -#include "r8180_wx.h" -#include "ieee80211/dot11d.h" -/* #define CONFIG_RTL8180_IO_MAP */ -#define TC_3W_POLL_MAX_TRY_CNT 5 - -static u8 MAC_REG_TABLE[][2] = { - /* - * PAGE 0: - * 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in - * HwConfigureRTL8185() - * 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). - * 0x1F0~0x1F8 set in MacConfig_85BASIC() - */ - {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42}, - {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03}, - {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03}, - {0x94, 0x0F}, {0x95, 0x32}, - {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00}, - {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32}, - {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4}, - {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00}, - {0xff, 0x00}, - - /* - * PAGE 1: - * For Flextronics system Logo PCIHCT failure: - * 0x1C4~0x1CD set no-zero value to avoid PCI configuration - * space 0x45[7]=1 - */ - {0x5e, 0x01}, - {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24}, - {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF}, - {0x82, 0xFF}, {0x83, 0x03}, - /* lzm add 080826 */ - {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, - /* lzm add 080826 */ - {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22}, - {0xe2, 0x00}, - - - /* PAGE 2: */ - {0x5e, 0x02}, - {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5}, - {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff}, - {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08}, - {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f}, - {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f}, - {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff}, - {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00}, - - /* PAGE 0: */ - {0x5e, 0x00}, {0x9f, 0x03} - }; - - -static u8 ZEBRA_AGC[] = { - 0, - 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, - 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, - 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x48, 0x47, 0x46, 0x45, - 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x17, 0x18, 0x18, - 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, - 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, - 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, - 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F - }; - -static u32 ZEBRA_RF_RX_GAIN_TABLE[] = { - 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6, - 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057, - 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3, - 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3, - 0x0183, 0x0163, 0x0143, 0x0123, 0x0103 - }; - -static u8 OFDM_CONFIG[] = { - /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */ - /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */ - /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */ - /* 0x00 */ - 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50, - 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00, - /* 0x10 */ - 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26, - 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB, - /* 0x20 */ - 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00, - 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00, - /* 0x30 */ - 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e, - 0xD8, 0x3C, 0x7B, 0x10, 0x10 - }; - - /*--------------------------------------------------------------- - * Hardware IO - * the code is ported from Windows source code - *--------------------------------------------------------------- - */ - -static u8 PlatformIORead1Byte(struct net_device *dev, u32 offset) -{ - return read_nic_byte(dev, offset); -} - -static void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data) -{ - write_nic_byte(dev, offset, data); - /* - * To make sure write operation is completed, - * 2005.11.09, by rcnjko. - */ - read_nic_byte(dev, offset); -} - -static void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data) -{ - write_nic_word(dev, offset, data); - /* - * To make sure write operation is completed, - * 2005.11.09, by rcnjko. - */ - read_nic_word(dev, offset); -} - -static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data) -{ - if (offset == PhyAddr) { - /* For Base Band configuration. */ - unsigned char cmdByte; - unsigned long dataBytes; - unsigned char idx; - u8 u1bTmp; - - cmdByte = (u8)(data & 0x000000ff); - dataBytes = data>>8; - - /* - * 071010, rcnjko: - * The critical section is only BB read/write race - * condition. Assumption: - * 1. We assume NO one will access BB at DIRQL, otherwise, - * system will crash for - * acquiring the spinlock in such context. - * 2. PlatformIOWrite4Byte() MUST NOT be recursive. - */ - /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */ - - for (idx = 0; idx < 30; idx++) { - /* Make sure command bit is clear before access it. */ - u1bTmp = PlatformIORead1Byte(dev, PhyAddr); - if ((u1bTmp & BIT7) == 0) - break; - else - mdelay(10); - } - - for (idx = 0; idx < 3; idx++) - PlatformIOWrite1Byte(dev, offset+1+idx, - ((u8 *)&dataBytes)[idx]); - - write_nic_byte(dev, offset, cmdByte); - - /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */ - } else { - write_nic_dword(dev, offset, data); - /* - * To make sure write operation is completed, 2005.11.09, - * by rcnjko. - */ - read_nic_dword(dev, offset); - } -} - -static void SetOutputEnableOfRfPins(struct net_device *dev) -{ - write_nic_word(dev, RFPinsEnable, 0x1bff); -} - -static bool HwHSSIThreeWire(struct net_device *dev, - u8 *pDataBuf, - bool write) -{ - u8 TryCnt; - u8 u1bTmp; - - /* Check if WE and RE are cleared. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { - u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0) - break; - - udelay(10); - } - if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) { - netdev_err(dev, - "HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", - u1bTmp); - return false; - } - - /* RTL8187S HSSI Read/Write Function */ - u1bTmp = read_nic_byte(dev, RF_SW_CONFIG); - u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */ - write_nic_byte(dev, RF_SW_CONFIG, u1bTmp); - - /* jong: HW SI read must set reg84[3]=0. */ - u1bTmp = read_nic_byte(dev, RFPinsSelect); - u1bTmp &= ~BIT3; - write_nic_byte(dev, RFPinsSelect, u1bTmp); - /* Fill up data buffer for write operation. */ - - /* SI - reg274[3:0] : RF register's Address */ - if (write) - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - else - write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf)); - - /* Set up command: WE or RE. */ - if (write) - write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE); - else - write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE); - - - /* Check if DONE is set. */ - for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) { - u1bTmp = read_nic_byte(dev, SW_3W_CMD1); - if (u1bTmp & SW_3W_CMD1_DONE) - break; - - udelay(10); - } - - write_nic_byte(dev, SW_3W_CMD1, 0); - - /* Read back data for read operation. */ - if (!write) { - /* Serial Interface : reg363_362[11:0] */ - *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ); - *((u16 *)pDataBuf) &= 0x0FFF; - } - - return true; -} - -void RF_WriteReg(struct net_device *dev, u8 offset, u16 data) -{ - u16 reg = (data << 4) | (offset & 0x0f); - HwHSSIThreeWire(dev, (u8 *)®, true); -} - -u16 RF_ReadReg(struct net_device *dev, u8 offset) -{ - u16 reg = offset & 0x0f; - HwHSSIThreeWire(dev, (u8 *)®, false); - return reg; -} - -static u8 ReadBBPortUchar(struct net_device *dev, u32 addr) -{ - PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f); - return PlatformIORead1Byte(dev, PhyDataR); -} - -/* by Owen on 04/07/14 for writing BB register successfully */ -static void WriteBBPortUchar(struct net_device *dev, u32 Data) -{ - PlatformIOWrite4Byte(dev, PhyAddr, Data); - ReadBBPortUchar(dev, Data); -} - -/* - * Description: - * Perform Antenna settings with antenna diversity on 87SE. - * Created by Roger, 2008.01.25. - */ -bool SetAntennaConfig87SE(struct net_device *dev, - u8 DefaultAnt, /* 0: Main, 1: Aux. */ - bool bAntDiversity) /* 1:Enable, 0: Disable. */ -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bAntennaSwitched = true; - /* 0x00 = disabled, 0x80 = enabled */ - u8 ant_diversity_offset = 0x00; - - /* - * printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", - * DefaultAnt, bAntDiversity); - */ - - /* Threshold for antenna diversity. */ - write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */ - - if (bAntDiversity) /* Enable Antenna Diversity. */ - ant_diversity_offset = 0x80; - - if (DefaultAnt == 1) { /* aux Antenna */ - /* Mac register, aux antenna */ - write_nic_byte(dev, ANTSEL, 0x00); - - /* Config CCK RX antenna. */ - write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */ - - /* Reg01 : 47 | ant_diversity_offset */ - write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset); - - /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */ - /* Reg18 : 32 */ - write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset); - } else { /* main Antenna */ - /* Mac register, main antenna */ - write_nic_byte(dev, ANTSEL, 0x03); - - /* Config CCK RX antenna. */ - write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */ - /* Reg01 : 47 */ - write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset); - - /* Config OFDM RX antenna. */ - write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */ - /*Reg18 : 32 */ - write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset); - } - priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */ - return bAntennaSwitched; -} -/* - *-------------------------------------------------------------- - * Hardware Initialization. - * the code is ported from Windows source code - *-------------------------------------------------------------- - */ - -static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev) -{ - - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u32 i; - u32 addr, data; - u32 u4bRegOffset, u4bRegValue; - u16 u4bRF23, u4bRF24; - u8 u1b24E; - int d_cut = 0; - - -/* - *=========================================================================== - * 87S_PCIE :: RADIOCFG.TXT - *=========================================================================== - */ - - - /* Page1 : reg16-reg30 */ - RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */ - u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1); - u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1); - - if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) { - d_cut = 1; - netdev_info(dev, "card type changed from C- to D-cut\n"); - } - - /* Page0 : reg0-reg15 */ - - RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */ - RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1); - RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */ - RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */ - RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); - RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1); - RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1); - RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1); - RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1); - RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1); - RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1); - RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1); - RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); - RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1); - RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1); - - /* Page1 : reg16-reg30 */ - RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); - RF_WriteReg(dev, 0x03, 0x0806); mdelay(1); - RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1); - RF_WriteReg(dev, 0x05, 0x059b); mdelay(1); - RF_WriteReg(dev, 0x06, 0x0081); mdelay(1); - RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1); -/* - * Don't write RF23/RF24 to make a difference between 87S C cut and D cut. - * asked by SD3 stevenl. - */ - RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); - RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1); - - if (d_cut) { - RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - /* RX LO buffer */ - RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); - } else { - RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1); - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - /* RX LO buffer */ - RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); - } - - RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); - RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */ - RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1); - RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1); - - for (i = 0; i <= 36; i++) { - RF_WriteReg(dev, 0x01, i); mdelay(1); - RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1); - } - - RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */ - RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */ - /* switch to reg16-reg30, and HSSI disable 137 */ - RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - /* Z4 synthesizer loop filter setting, 392 */ - RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - /* switch to reg0-reg15, and HSSI disable */ - RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - /* CBC on, Tx Rx disable, High gain */ - RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - /* Z4 setted channel 1 */ - RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */ - mdelay(200); /* Deay 200 ms. */ /* 0xfd */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - /* switch to reg16-reg30 137, and HSSI disable 137 */ - RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); - mdelay(10); /* Deay 10 ms. */ /* 0xfd */ - - RF_WriteReg(dev, 0x07, 0x0000); mdelay(1); - RF_WriteReg(dev, 0x07, 0x0180); mdelay(1); - RF_WriteReg(dev, 0x07, 0x0220); mdelay(1); - RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1); - - /* DAC calibration off 20070702 */ - RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1); - RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1); - /* For crystal calibration, added by Roger, 2007.12.11. */ - if (priv->bXtalCalibration) { /* reg 30. */ - /* - * enable crystal calibration. - * RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0]. - * (2)PA Pwr delay timer[15:14], default: 2.4us, - * set BIT15=0 - * (3)RF signal on/off when calibration[13], default: on, - * set BIT13=0. - * So we should minus 4 BITs offset. - */ - RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | - (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1); - netdev_info(dev, "ZEBRA_Config_85BASIC_HardCode(): (%02x)\n", - (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | - BIT11 | BIT9); - } else { - /* using default value. Xin=6, Xout=6. */ - RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); - } - /* switch to reg0-reg15, and HSSI enable */ - RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); - /* Rx BB start calibration, 00c//+edward */ - RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); - /* temperature meter off */ - RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); - RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */ - mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ - mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ - mdelay(10); /* Deay 10 ms.*/ /* 0xfe */ - /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); - /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); - /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); - /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); - /* Rx mode*/ /*+edward */ - RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); - /* power save parameters. */ - u1b24E = read_nic_byte(dev, 0x24E); - write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6)))); - - /*====================================================================== - * - *====================================================================== - * CCKCONF.TXT - *====================================================================== - * - * [POWER SAVE] Power Saving Parameters by jong. 2007-11-27 - * CCK reg0x00[7]=1'b1 :power saving for TX (default) - * CCK reg0x00[6]=1'b1: power saving for RX (default) - * CCK reg0x06[4]=1'b1: turn off channel estimation related - * circuits if not doing channel estimation. - * CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1 - * CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0 - */ - - write_phy_cck(dev, 0x00, 0xc8); - write_phy_cck(dev, 0x06, 0x1c); - write_phy_cck(dev, 0x10, 0x78); - write_phy_cck(dev, 0x2e, 0xd0); - write_phy_cck(dev, 0x2f, 0x06); - write_phy_cck(dev, 0x01, 0x46); - - /* power control */ - write_nic_byte(dev, CCK_TXAGC, 0x10); - write_nic_byte(dev, OFDM_TXAGC, 0x1B); - write_nic_byte(dev, ANTSEL, 0x03); - - - - /* - *====================================================================== - * AGC.txt - *====================================================================== - */ - - write_phy_ofdm(dev, 0x00, 0x12); - - for (i = 0; i < 128; i++) { - - data = ZEBRA_AGC[i+1]; - data = data << 8; - data = data | 0x0000008F; - - addr = i + 0x80; /* enable writing AGC table */ - addr = addr << 8; - addr = addr | 0x0000008E; - - WriteBBPortUchar(dev, data); - WriteBBPortUchar(dev, addr); - WriteBBPortUchar(dev, 0x0000008E); - } - - PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */ - - /* - *====================================================================== - * - *====================================================================== - * OFDMCONF.TXT - *====================================================================== - */ - - for (i = 0; i < 60; i++) { - u4bRegOffset = i; - u4bRegValue = OFDM_CONFIG[i]; - - WriteBBPortUchar(dev, - (0x00000080 | - (u4bRegOffset & 0x7f) | - ((u4bRegValue & 0xff) << 8))); - } - - /* - *====================================================================== - * by amy for antenna - *====================================================================== - */ - /* - * Config Sw/Hw Combinational Antenna Diversity. Added by Roger, - * 2008.02.26. - */ - SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, - priv->bSwAntennaDiverity); -} - - -void UpdateInitialGain(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - /* lzm add 080826 */ - if (priv->eRFPowerState != RF_ON) { - /* Don't access BB/RF under disable PLL situation. - * RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - - * pHalData->eRFPowerState!=RF_ON\n")); - * Back to the original state - */ - priv->InitialGain = priv->InitialGainBackUp; - return; - } - - switch (priv->InitialGain) { - case 1: /* m861dBm */ - write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); - break; - - case 2: /* m862dBm */ - write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); - break; - - case 3: /* m863dBm */ - write_phy_ofdm(dev, 0x17, 0x36); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); - break; - - case 4: /* m864dBm */ - write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); - break; - - case 5: /* m82dBm */ - write_phy_ofdm(dev, 0x17, 0x46); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1); - break; - - case 6: /* m78dBm */ - write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x96); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); - break; - - case 7: /* m74dBm */ - write_phy_ofdm(dev, 0x17, 0x56); mdelay(1); - write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); - break; - - case 8: - write_phy_ofdm(dev, 0x17, 0x66); mdelay(1); - write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1); - break; - - default: /* MP */ - write_phy_ofdm(dev, 0x17, 0x26); mdelay(1); - write_phy_ofdm(dev, 0x24, 0x86); mdelay(1); - write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1); - break; - } -} -/* - * Description: - * Tx Power tracking mechanism routine on 87SE. - * Created by Roger, 2007.12.11. - */ -static void InitTxPwrTracking87SE(struct net_device *dev) -{ - u32 u4bRfReg; - - u4bRfReg = RF_ReadReg(dev, 0x02); - - /* Enable Thermal meter indication. */ - RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1); -} - -static void PhyConfig8185(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - write_nic_dword(dev, RCR, priv->ReceiveConfig); - priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03; - /* RF config */ - ZEBRA_Config_85BASIC_HardCode(dev); - /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, - * 2007-06-06. - */ - if (priv->bDigMechanism) { - if (priv->InitialGain == 0) - priv->InitialGain = 4; - } - - /* - * Enable thermal meter indication to implement TxPower tracking - * on 87SE. We initialize thermal meter here to avoid unsuccessful - * configuration. Added by Roger, 2007.12.11. - */ - if (priv->bTxPowerTrack) - InitTxPwrTracking87SE(dev); - - priv->InitialGainBackUp = priv->InitialGain; - UpdateInitialGain(dev); - - return; -} - -static void HwConfigureRTL8185(struct net_device *dev) -{ - /* - * RTL8185_TODO: Determine Retrylimit, TxAGC, - * AutoRateFallback control. - */ - u8 bUNIVERSAL_CONTROL_RL = 0; - u8 bUNIVERSAL_CONTROL_AGC = 1; - u8 bUNIVERSAL_CONTROL_ANT = 1; - u8 bAUTO_RATE_FALLBACK_CTL = 1; - u8 val8; - write_nic_word(dev, BRSR, 0x0fff); - /* Retry limit */ - val8 = read_nic_byte(dev, CW_CONF); - - if (bUNIVERSAL_CONTROL_RL) - val8 = val8 & 0xfd; - else - val8 = val8 | 0x02; - - write_nic_byte(dev, CW_CONF, val8); - - /* Tx AGC */ - val8 = read_nic_byte(dev, TXAGC_CTL); - if (bUNIVERSAL_CONTROL_AGC) { - write_nic_byte(dev, CCK_TXAGC, 128); - write_nic_byte(dev, OFDM_TXAGC, 128); - val8 = val8 & 0xfe; - } else { - val8 = val8 | 0x01; - } - - - write_nic_byte(dev, TXAGC_CTL, val8); - - /* Tx Antenna including Feedback control */ - val8 = read_nic_byte(dev, TXAGC_CTL); - - if (bUNIVERSAL_CONTROL_ANT) { - write_nic_byte(dev, ANTSEL, 0x00); - val8 = val8 & 0xfd; - } else { - val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */ - } - - write_nic_byte(dev, TXAGC_CTL, val8); - - /* Auto Rate fallback control */ - val8 = read_nic_byte(dev, RATE_FALLBACK); - val8 &= 0x7c; - if (bAUTO_RATE_FALLBACK_CTL) { - val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1; - - /* We shall set up the ARFR according - * to user's setting. - */ - PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */ - } - write_nic_byte(dev, RATE_FALLBACK, val8); -} - -static void MacConfig_85BASIC_HardCode(struct net_device *dev) -{ - /* - *====================================================================== - * MACREG.TXT - *====================================================================== - */ - int nLinesRead = 0; - u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0; - int i; - - nLinesRead = sizeof(MAC_REG_TABLE)/2; - - for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */ - u4bRegOffset = MAC_REG_TABLE[i][0]; - u4bRegValue = MAC_REG_TABLE[i][1]; - - if (u4bRegOffset == 0x5e) - u4bPageIndex = u4bRegValue; - else - u4bRegOffset |= (u4bPageIndex << 8); - - write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue); - } - /* ================================================================= */ -} - -static void MacConfig_85BASIC(struct net_device *dev) -{ - - u8 u1DA; - MacConfig_85BASIC_HardCode(dev); - - /* ================================================================= */ - - /* Follow TID_AC_MAP of WMac. */ - write_nic_word(dev, TID_AC_MAP, 0xfa50); - - /* Interrupt Migration, Jong suggested we use set 0x0000 first, - * 2005.12.14, by rcnjko. - */ - write_nic_word(dev, IntMig, 0x0000); - - /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */ - PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000); - PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000); - PlatformIOWrite1Byte(dev, 0x1F8, 0x00); - - /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */ - - /* - * power save parameter based on - * "87SE power save parameters 20071127.doc", as follow. - */ - - /* Enable DA10 TX power saving */ - u1DA = read_nic_byte(dev, PHYPR); - write_nic_byte(dev, PHYPR, (u1DA | BIT2)); - - /* POWER: */ - write_nic_word(dev, 0x360, 0x1000); - write_nic_word(dev, 0x362, 0x1000); - - /* AFE. */ - write_nic_word(dev, 0x370, 0x0560); - write_nic_word(dev, 0x372, 0x0560); - write_nic_word(dev, 0x374, 0x0DA4); - write_nic_word(dev, 0x376, 0x0DA4); - write_nic_word(dev, 0x378, 0x0560); - write_nic_word(dev, 0x37A, 0x0560); - write_nic_word(dev, 0x37C, 0x00EC); - write_nic_word(dev, 0x37E, 0x00EC); /* +edward */ - write_nic_byte(dev, 0x24E, 0x01); -} - -static u8 GetSupportedWirelessMode8185(struct net_device *dev) -{ - return WIRELESS_MODE_B | WIRELESS_MODE_G; -} - -static void -ActUpdateChannelAccessSetting(struct net_device *dev, - enum wireless_mode mode, - struct chnl_access_setting *chnl_access_setting) -{ - AC_CODING eACI; - - /* - * - * TODO: We still don't know how to set up these registers, - * just follow WMAC to verify 8185B FPAG. - * - * - * Jong said CWmin/CWmax register are not functional in 8185B, - * so we shall fill channel access realted register into AC - * parameter registers, - * even in nQBss. - */ - - /* Suggested by Jong, 2005.12.08. */ - chnl_access_setting->sifs_timer = 0x22; - chnl_access_setting->difs_timer = 0x1C; /* 2006.06.02, by rcnjko. */ - chnl_access_setting->slot_time_timer = 9; /* 2006.06.02, by rcnjko. */ - /* - * Suggested by wcchu, it is the default value of EIFS register, - * 2005.12.08. - */ - chnl_access_setting->eifs_timer = 0x5B; - chnl_access_setting->cwmin_index = 3; /* 2006.06.02, by rcnjko. */ - chnl_access_setting->cwmax_index = 7; /* 2006.06.02, by rcnjko. */ - - write_nic_byte(dev, SIFS, chnl_access_setting->sifs_timer); - /* - * Rewrited from directly use PlatformEFIOWrite1Byte(), - * by Annie, 2006-03-29. - */ - write_nic_byte(dev, SLOT, chnl_access_setting->slot_time_timer); - - write_nic_byte(dev, EIFS, chnl_access_setting->eifs_timer); - - /* - * Suggested by wcchu, it is the default value of EIFS - * register, 2005.12.08. - */ - write_nic_byte(dev, AckTimeOutReg, 0x5B); - - for (eACI = 0; eACI < AC_MAX; eACI++) - write_nic_byte(dev, ACM_CONTROL, 0); -} - -static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev); - - if ((btWirelessMode & btSupportedWirelessMode) == 0) { - /* - * Don't switch to unsupported wireless mode, 2006.02.15, - * by rcnjko. - */ - DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n", - btWirelessMode, btSupportedWirelessMode); - return; - } - - /* 1. Assign wireless mode to switch if necessary. */ - if (btWirelessMode == WIRELESS_MODE_AUTO) { - if ((btSupportedWirelessMode & WIRELESS_MODE_A)) { - btWirelessMode = WIRELESS_MODE_A; - } else if (btSupportedWirelessMode & WIRELESS_MODE_G) { - btWirelessMode = WIRELESS_MODE_G; - - } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) { - btWirelessMode = WIRELESS_MODE_B; - } else { - DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n", - btSupportedWirelessMode); - btWirelessMode = WIRELESS_MODE_B; - } - } - - /* - * 2. Swtich band: RF or BB specific actions, - * for example, refresh tables in omc8255, or change initial gain if - * necessary. Nothing to do for Zebra to switch band. Update current - * wireless mode if we switch to specified band successfully. - */ - - ieee->mode = (enum wireless_mode)btWirelessMode; - - /* 3. Change related setting. */ - if (ieee->mode == WIRELESS_MODE_A) - DMESG("WIRELESS_MODE_A\n"); - else if (ieee->mode == WIRELESS_MODE_B) - DMESG("WIRELESS_MODE_B\n"); - else if (ieee->mode == WIRELESS_MODE_G) - DMESG("WIRELESS_MODE_G\n"); - - ActUpdateChannelAccessSetting(dev, ieee->mode, - &priv->ChannelAccessSetting); -} - -void rtl8185b_irq_enable(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - priv->irq_enabled = 1; - write_nic_dword(dev, IMR, priv->IntrMask); -} - -static void MgntDisconnectIBSS(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u8 i; - - for (i = 0; i < 6; i++) - priv->ieee80211->current_network.bssid[i] = 0x55; - - - - priv->ieee80211->state = IEEE80211_NOLINK; - /* - * Stop Beacon. - * - * Vista add a Adhoc profile, HW radio off until - * OID_DOT11_RESET_REQUEST Driver would set MSR=NO_LINK, - * then HW Radio ON, MgntQueue Stuck. Because Bcn DMA isn't - * complete, mgnt queue would stuck until Bcn packet send. - * - * Disable Beacon Queue Own bit, suggested by jong - */ - ieee80211_stop_send_beacons(priv->ieee80211); - - priv->ieee80211->link_change(dev); - notify_wx_assoc_event(priv->ieee80211); -} - -static void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - u8 i; - - SendDisassociation(priv->ieee80211, asSta, asRsn); - - if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) { - /* ShuChen TODO: change media status. */ - - for (i = 0; i < 6; i++) - priv->ieee80211->current_network.bssid[i] = 0x22; - - ieee80211_disassociate(priv->ieee80211); - } -} - -static void MgntDisconnectAP(struct net_device *dev, u8 asRsn) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - /* - * Commented out by rcnjko, 2005.01.27: - * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE(). - * - * 2004/09/15, kcwu, the key should be cleared, or the new - * handshaking will not success - * - * In WPA WPA2 need to Clear all key ... because new key will set - * after new handshaking. 2004.10.11, by rcnjko. - */ - MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, - asRsn); - - priv->ieee80211->state = IEEE80211_NOLINK; -} - -static bool MgntDisconnect(struct net_device *dev, u8 asRsn) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - /* - * Schedule an workitem to wake up for ps mode, 070109, by rcnjko. - */ - - if (IS_DOT11D_ENABLE(priv->ieee80211)) - Dot11d_Reset(priv->ieee80211); - /* In adhoc mode, update beacon frame. */ - if (priv->ieee80211->state == IEEE80211_LINKED) { - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - MgntDisconnectIBSS(dev); - - if (priv->ieee80211->iw_mode == IW_MODE_INFRA) { - /* - * We clear key here instead of MgntDisconnectAP() - * because that MgntActSet_802_11_DISASSOCIATE() - * is an interface called by OS, e.g. - * OID_802_11_DISASSOCIATE in Windows while as - * MgntDisconnectAP() is used to handle - * disassociation related things to AP, e.g. send - * Disassoc frame to AP. 2005.01.27, by rcnjko. - */ - MgntDisconnectAP(dev, asRsn); - } - /* Indicate Disconnect, 2005.02.23, by rcnjko. */ - } - return true; -} -/* - * Description: - * Chang RF Power State. - * Note that, only MgntActSet_RF_State() is allowed to set - * HW_VAR_RF_STATE. - * - * Assumption: - * PASSIVE LEVEL. - */ -static bool SetRFPowerState(struct net_device *dev, - enum rt_rf_power_state eRFPowerState) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bResult = false; - - if (eRFPowerState == priv->eRFPowerState) - return bResult; - - bResult = SetZebraRFPowerState8185(dev, eRFPowerState); - - return bResult; -} - -bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet, - u32 ChangeSource) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - bool bActionAllowed = false; - bool bConnectBySSID = false; - enum rt_rf_power_state rtState; - u16 RFWaitCounter = 0; - unsigned long flag; - /* - * Prevent the race condition of RF state change. By Bruce, - * 2007-11-28. Only one thread can change the RF state at one time, - * and others should wait to be executed. - */ - while (true) { - spin_lock_irqsave(&priv->rf_ps_lock, flag); - if (priv->RFChangeInProgress) { - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - /* Set RF after the previous action is done. */ - while (priv->RFChangeInProgress) { - RFWaitCounter++; - udelay(1000); /* 1 ms */ - - /* - * Wait too long, return FALSE to avoid - * to be stuck here. - */ - if (RFWaitCounter > 1000) { /* 1sec */ - netdev_info(dev, "MgntActSet_RF_State(): Wait too long to set RF\n"); - /* TODO: Reset RF state? */ - return false; - } - } - } else { - priv->RFChangeInProgress = true; - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - break; - } - } - rtState = priv->eRFPowerState; - - switch (StateToSet) { - case RF_ON: - /* - * Turn On RF no matter the IPS setting because we need to - * update the RF state to Ndis under Vista, or the Windows - * does not allow the driver to perform site survey any - * more. By Bruce, 2007-10-02. - */ - priv->RfOffReason &= (~ChangeSource); - - if (!priv->RfOffReason) { - priv->RfOffReason = 0; - bActionAllowed = true; - - if (rtState == RF_OFF && - ChangeSource >= RF_CHANGE_BY_HW) - bConnectBySSID = true; - } - break; - - case RF_OFF: - /* 070125, rcnjko: we always keep connected in AP mode. */ - - if (priv->RfOffReason > RF_CHANGE_BY_IPS) { - /* - * 060808, Annie: - * Disconnect to current BSS when radio off. - * Asked by QuanTa. - * - * Calling MgntDisconnect() instead of - * MgntActSet_802_11_DISASSOCIATE(), because - * we do NOT need to set ssid to dummy ones. - */ - MgntDisconnect(dev, disas_lv_ss); - /* - * Clear content of bssDesc[] and bssDesc4Query[] - * to avoid reporting old bss to UI. - */ - } - - priv->RfOffReason |= ChangeSource; - bActionAllowed = true; - break; - case RF_SLEEP: - priv->RfOffReason |= ChangeSource; - bActionAllowed = true; - break; - default: - break; - } - - if (bActionAllowed) { - /* Config HW to the specified mode. */ - SetRFPowerState(dev, StateToSet); - } - - /* Release RF spinlock */ - spin_lock_irqsave(&priv->rf_ps_lock, flag); - priv->RFChangeInProgress = false; - spin_unlock_irqrestore(&priv->rf_ps_lock, flag); - return bActionAllowed; -} - -static void InactivePowerSave(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - /* - * This flag "bSwRfProcessing", indicates the status of IPS - * procedure, should be set if the IPS workitem is really - * scheduled. The old code, sets this flag before scheduling the - * IPS workitem and however, at the same time the previous IPS - * workitem did not end yet, fails to schedule the current - * workitem. Thus, bSwRfProcessing blocks the IPS procedure of - * switching RF. - */ - priv->bSwRfProcessing = true; - - MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS); - - /* - * To solve CAM values miss in RF OFF, rewrite CAM values after - * RF ON. By Bruce, 2007-09-20. - */ - - priv->bSwRfProcessing = false; -} - -/* - * Description: - * Enter the inactive power save mode. RF will be off - */ -void IPSEnter(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - enum rt_rf_power_state rtState; - if (priv->bInactivePs) { - rtState = priv->eRFPowerState; - - /* - * Do not enter IPS in the following conditions: - * (1) RF is already OFF or - * Sleep (2) bSwRfProcessing (indicates the IPS is still - * under going) (3) Connected (only disconnected can - * trigger IPS)(4) IBSS (send Beacon) - * (5) AP mode (send Beacon) - */ - if (rtState == RF_ON && !priv->bSwRfProcessing - && (priv->ieee80211->state != IEEE80211_LINKED)) { - priv->eInactivePowerState = RF_OFF; - InactivePowerSave(dev); - } - } -} -void IPSLeave(struct net_device *dev) -{ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - enum rt_rf_power_state rtState; - if (priv->bInactivePs) { - rtState = priv->eRFPowerState; - if ((rtState == RF_OFF || rtState == RF_SLEEP) && - !priv->bSwRfProcessing - && priv->RfOffReason <= RF_CHANGE_BY_IPS) { - priv->eInactivePowerState = RF_ON; - InactivePowerSave(dev); - } - } -} - -void rtl8185b_adapter_start(struct net_device *dev) -{ - struct r8180_priv *priv = ieee80211_priv(dev); - struct ieee80211_device *ieee = priv->ieee80211; - - u8 SupportedWirelessMode; - u8 InitWirelessMode; - u8 bInvalidWirelessMode = 0; - u8 tmpu8; - u8 btCR9346; - u8 TmpU1b; - u8 btPSR; - - write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0)); - rtl8180_reset(dev); - - priv->dma_poll_mask = 0; - priv->dma_poll_stop_mask = 0; - - HwConfigureRTL8185(dev); - write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); - write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff); - /* default network type to 'No Link' */ - write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); - write_nic_word(dev, BcnItv, 100); - write_nic_word(dev, AtimWnd, 2); - PlatformIOWrite2Byte(dev, FEMR, 0xFFFF); - write_nic_byte(dev, WPA_CONFIG, 0); - MacConfig_85BASIC(dev); - /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, - * by rcnjko. - */ - /* BT_DEMO_BOARD type */ - PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a); - - /* - *--------------------------------------------------------------------- - * Set up PHY related. - *--------------------------------------------------------------------- - */ - /* Enable Config3.PARAM_En to revise AnaaParm. */ - write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */ - tmpu8 = read_nic_byte(dev, CONFIG3); - write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En)); - /* Turn on Analog power. */ - /* Asked for by William, otherwise, MAC 3-wire can't work, - * 2006.06.27, by rcnjko. - */ - write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON); - write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON); - write_nic_word(dev, ANAPARAM3, 0x0010); - - write_nic_byte(dev, CONFIG3, tmpu8); - write_nic_byte(dev, CR9346, 0x00); - /* enable EEM0 and EEM1 in 9346CR */ - btCR9346 = read_nic_byte(dev, CR9346); - write_nic_byte(dev, CR9346, (btCR9346 | 0xC0)); - - /* B cut use LED1 to control HW RF on/off */ - TmpU1b = read_nic_byte(dev, CONFIG5); - TmpU1b = TmpU1b & ~BIT3; - write_nic_byte(dev, CONFIG5, TmpU1b); - - /* disable EEM0 and EEM1 in 9346CR */ - btCR9346 &= ~(0xC0); - write_nic_byte(dev, CR9346, btCR9346); - - /* Enable Led (suggested by Jong) */ - /* B-cut RF Radio on/off 5e[3]=0 */ - btPSR = read_nic_byte(dev, PSR); - write_nic_byte(dev, PSR, (btPSR | BIT3)); - /* setup initial timing for RFE. */ - write_nic_word(dev, RFPinsOutput, 0x0480); - SetOutputEnableOfRfPins(dev); - write_nic_word(dev, RFPinsSelect, 0x2488); - - /* PHY config. */ - PhyConfig8185(dev); - - /* - * We assume RegWirelessMode has already been initialized before, - * however, we has to validate the wireless mode here and provide a - * reasonable initialized value if necessary. 2005.01.13, - * by rcnjko. - */ - SupportedWirelessMode = GetSupportedWirelessMode8185(dev); - if ((ieee->mode != WIRELESS_MODE_B) && - (ieee->mode != WIRELESS_MODE_G) && - (ieee->mode != WIRELESS_MODE_A) && - (ieee->mode != WIRELESS_MODE_AUTO)) { - /* It should be one of B, G, A, or AUTO. */ - bInvalidWirelessMode = 1; - } else { - /* One of B, G, A, or AUTO. */ - /* Check if the wireless mode is supported by RF. */ - if ((ieee->mode != WIRELESS_MODE_AUTO) && - (ieee->mode & SupportedWirelessMode) == 0) { - bInvalidWirelessMode = 1; - } - } - - if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) { - /* Auto or other invalid value. */ - /* Assigne a wireless mode to initialize. */ - if ((SupportedWirelessMode & WIRELESS_MODE_A)) { - InitWirelessMode = WIRELESS_MODE_A; - } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) { - InitWirelessMode = WIRELESS_MODE_G; - } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) { - InitWirelessMode = WIRELESS_MODE_B; - } else { - DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", - SupportedWirelessMode); - InitWirelessMode = WIRELESS_MODE_B; - } - - /* Initialize RegWirelessMode if it is not a valid one. */ - if (bInvalidWirelessMode) - ieee->mode = (enum wireless_mode)InitWirelessMode; - - } else { - /* One of B, G, A. */ - InitWirelessMode = ieee->mode; - } - priv->eRFPowerState = RF_OFF; - priv->RfOffReason = 0; - { - MgntActSet_RF_State(dev, RF_ON, 0); - } - /* - * If inactive power mode is enabled, disable rf while in - * disconnected state. - */ - if (priv->bInactivePs) - MgntActSet_RF_State(dev , RF_OFF, RF_CHANGE_BY_IPS); - - ActSetWirelessMode8185(dev, (u8)(InitWirelessMode)); - - /* ----------------------------------------------------------------- */ - - rtl8185b_irq_enable(dev); - - netif_start_queue(dev); -} - -void rtl8185b_rx_enable(struct net_device *dev) -{ - u8 cmd; - /* for now we accept data, management & ctl frame*/ - struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); - - - if (dev->flags & IFF_PROMISC) - DMESG("NIC in promisc mode"); - - if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || dev->flags & - IFF_PROMISC) { - priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM); - priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP; - } - - if (priv->ieee80211->iw_mode == IW_MODE_MONITOR) - priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | - RCR_APWRMGT | RCR_AICV; - - - if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR) - priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32; - - write_nic_dword(dev, RCR, priv->ReceiveConfig); - - fix_rx_fifo(dev); - - cmd = read_nic_byte(dev, CMD); - write_nic_byte(dev, CMD, cmd | (1<TransmitConfig); - byte = read_nic_byte(dev, MSR); - byte |= MSR_LINK_ENEDCA; - write_nic_byte(dev, MSR, byte); - - fix_tx_fifo(dev); - - cmd = read_nic_byte(dev, CMD); - write_nic_byte(dev, CMD, cmd | (1< Date: Tue, 15 Apr 2014 15:50:19 +0200 Subject: [PATCH 339/797] net: phy: add minimal support for QSGMII PHY This commit adds the necessary definitions for the PHY layer to recognize "qsgmii" as a valid PHY interface. A QSMII interface, as defined at http://en.wikipedia.org/wiki/Media_Independent_Interface#Quad_Serial_Gigabit_Media_Independent_Interface, is "is a method of combining four SGMII lines into a 5Gbit/s interface. QSGMII, like SGMII, uses LVDS signalling for the TX and RX data and a single LVDS clock signal. QSGMII uses significantly fewer signal lines than four SGMII busses." This type of MAC <-> PHY connection might require special handling on the MAC driver side, so it should be possible to express this type of MAC <-> PHY connection, for example in the Device Tree. Signed-off-by: Thomas Petazzoni Cc: devicetree@vger.kernel.org Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- Documentation/devicetree/bindings/net/ethernet.txt | 2 +- include/linux/phy.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt index 9ecd43d8792c..3fc360523bc9 100644 --- a/Documentation/devicetree/bindings/net/ethernet.txt +++ b/Documentation/devicetree/bindings/net/ethernet.txt @@ -10,7 +10,7 @@ The following properties are common to the Ethernet controllers: - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than the maximum frame size (there's contradiction in ePAPR). - phy-mode: string, operation mode of the PHY interface; supported values are - "mii", "gmii", "sgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id", + "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto standard property; - phy-connection-type: the same as "phy-mode" property but described in ePAPR; diff --git a/include/linux/phy.h b/include/linux/phy.h index 24126c4b27b5..4d0221fd0688 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -75,6 +75,7 @@ typedef enum { PHY_INTERFACE_MODE_SMII, PHY_INTERFACE_MODE_XGMII, PHY_INTERFACE_MODE_MOCA, + PHY_INTERFACE_MODE_QSGMII, PHY_INTERFACE_MODE_MAX, } phy_interface_t; @@ -116,6 +117,8 @@ static inline const char *phy_modes(phy_interface_t interface) return "xgmii"; case PHY_INTERFACE_MODE_MOCA: return "moca"; + case PHY_INTERFACE_MODE_QSGMII: + return "qsgmii"; default: return "unknown"; } -- GitLab From 3f1dd4bcfe2c19a336e01e32a928fcdb8cc43e5c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 15 Apr 2014 15:50:20 +0200 Subject: [PATCH 340/797] net: mvneta: properly configure the MAC <-> PHY connection in all situations Commit 5445eaf309ff ('mvneta: Try to fix mvneta when compiled as module') fixed the mvneta driver to make it work properly when loaded as a module in SGMII configuration, which was tested successful by the author on the Armada XP OpenBlocks AX3, which uses SGMII. However, some other platforms, namely the Armada XP GP don't use SGMII, but a QSGMII connection between the MAC and the PHY, and this case was not supported by the mvneta driver, which was relying on configuration put in place by the bootloader. While this works when the mvneta driver is built-in (because clocks are not gated), it breaks when mvneta is built as a module, because the clock is gated (all configuration is lost) and then re-enabled when the mvneta driver is loaded. In order to support all of RGMII, SGMII and QSGMII, this commit reworks how the PHY interface configuration is done, and simplifies it: it removes the mvneta_port_sgmii_config() and mvneta_gmac_rgmii_set() functions, which were strange because mvneta_gmac_rgmii_set() was called in all cases, even for SGMII configurations. Also, the mvneta_gmac_rgmii_set() function was taking a boolean as argument, which was always true. Instead, all the PHY interface configuration logic is moved into the mvneta_port_power_up() function, in a much simpler 'switch' construct, with four cases: - QSGMII: the RGMIIEn bit, the PCSEn bit in GMAC_CTRL_2 are set, and the SERDES is configured in QSGMII. Technically speaking, configuring the SERDES of the first port would be sufficient, but it is simpler to do it on all ports. - SGMII: the RGMIIEn bit, the PCSEn bit in GMAC_CTRL_2 are set, and the SERDES is configured as SGMII. - RGMII: the RGMIIEn bit in GMAC_CTRL_2 is set. The PCSEn bit is kept cleared, and no SERDES configuration is done, because RGMII is not using SERDES lanes. - other: an error is returned. For this reason, the mvneta_port_power_up() now returns an int instead of nothing, and the return value is checked by mvneta_probe(). This has been successfully tested on: * Armada XP DB, which has two RGMII and two SGMII connections * Armada XP GP, which uses QSGMII for its four interfaces * Armada 370 Mirabox, which has two RGMII connections Signed-off-by: Thomas Petazzoni Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 73 +++++++++++++-------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index b248bcbdae63..14786c8bf99e 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -89,8 +89,9 @@ #define MVNETA_TX_IN_PRGRS BIT(1) #define MVNETA_TX_FIFO_EMPTY BIT(8) #define MVNETA_RX_MIN_FRAME_SIZE 0x247c -#define MVNETA_SGMII_SERDES_CFG 0x24A0 +#define MVNETA_SERDES_CFG 0x24A0 #define MVNETA_SGMII_SERDES_PROTO 0x0cc7 +#define MVNETA_QSGMII_SERDES_PROTO 0x0667 #define MVNETA_TYPE_PRIO 0x24bc #define MVNETA_FORCE_UNI BIT(21) #define MVNETA_TXQ_CMD_1 0x24e4 @@ -711,35 +712,6 @@ static void mvneta_rxq_bm_disable(struct mvneta_port *pp, mvreg_write(pp, MVNETA_RXQ_CONFIG_REG(rxq->id), val); } - - -/* Sets the RGMII Enable bit (RGMIIEn) in port MAC control register */ -static void mvneta_gmac_rgmii_set(struct mvneta_port *pp, int enable) -{ - u32 val; - - val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); - - if (enable) - val |= MVNETA_GMAC2_PORT_RGMII; - else - val &= ~MVNETA_GMAC2_PORT_RGMII; - - mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); -} - -/* Config SGMII port */ -static void mvneta_port_sgmii_config(struct mvneta_port *pp) -{ - u32 val; - - val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); - val |= MVNETA_GMAC2_PCS_ENABLE; - mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); - - mvreg_write(pp, MVNETA_SGMII_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); -} - /* Start the Ethernet port RX and TX activity */ static void mvneta_port_up(struct mvneta_port *pp) { @@ -2749,26 +2721,44 @@ static void mvneta_conf_mbus_windows(struct mvneta_port *pp, } /* Power up the port */ -static void mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) +static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode) { - u32 val; + u32 ctrl; /* MAC Cause register should be cleared */ mvreg_write(pp, MVNETA_UNIT_INTR_CAUSE, 0); - if (phy_mode == PHY_INTERFACE_MODE_SGMII) - mvneta_port_sgmii_config(pp); + ctrl = mvreg_read(pp, MVNETA_GMAC_CTRL_2); - mvneta_gmac_rgmii_set(pp, 1); + /* Even though it might look weird, when we're configured in + * SGMII or QSGMII mode, the RGMII bit needs to be set. + */ + switch(phy_mode) { + case PHY_INTERFACE_MODE_QSGMII: + mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_QSGMII_SERDES_PROTO); + ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII; + break; + case PHY_INTERFACE_MODE_SGMII: + mvreg_write(pp, MVNETA_SERDES_CFG, MVNETA_SGMII_SERDES_PROTO); + ctrl |= MVNETA_GMAC2_PCS_ENABLE | MVNETA_GMAC2_PORT_RGMII; + break; + case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_ID: + ctrl |= MVNETA_GMAC2_PORT_RGMII; + break; + default: + return -EINVAL; + } /* Cancel Port Reset */ - val = mvreg_read(pp, MVNETA_GMAC_CTRL_2); - val &= ~MVNETA_GMAC2_PORT_RESET; - mvreg_write(pp, MVNETA_GMAC_CTRL_2, val); + ctrl &= ~MVNETA_GMAC2_PORT_RESET; + mvreg_write(pp, MVNETA_GMAC_CTRL_2, ctrl); while ((mvreg_read(pp, MVNETA_GMAC_CTRL_2) & MVNETA_GMAC2_PORT_RESET) != 0) continue; + + return 0; } /* Device initialization routine */ @@ -2879,7 +2869,12 @@ static int mvneta_probe(struct platform_device *pdev) dev_err(&pdev->dev, "can't init eth hal\n"); goto err_free_stats; } - mvneta_port_power_up(pp, phy_mode); + + err = mvneta_port_power_up(pp, phy_mode); + if (err < 0) { + dev_err(&pdev->dev, "can't power up port\n"); + goto err_deinit; + } dram_target_info = mv_mbus_dram_info(); if (dram_target_info) -- GitLab From ff8ebe6448e98df59a8c7e7e93876f8f3d6a8b19 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Tue, 8 Apr 2014 09:15:22 +0300 Subject: [PATCH 341/797] staging: goldfish: Call free_irq in error path If misc_register failed in goldfish_audio_probe, the already requested IRQ wouldn't get freed. Add a call to free_irq() like there is in goldfish_audio_remove(). Signed-off-by: Tuomas Tynkkynen Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/goldfish/goldfish_audio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c index f96dcec740ae..7ac2602242f1 100644 --- a/drivers/staging/goldfish/goldfish_audio.c +++ b/drivers/staging/goldfish/goldfish_audio.c @@ -334,6 +334,7 @@ static int goldfish_audio_probe(struct platform_device *pdev) return 0; err_misc_register_failed: + free_irq(data->irq, data); err_request_irq_failed: dma_free_coherent(&pdev->dev, COMBINED_BUFFER_SIZE, data->buffer_virt, data->buffer_phys); -- GitLab From ef35a4f44bdc6f8c9f99a561fd1fd318305a4d98 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 9 Apr 2014 19:45:46 +0900 Subject: [PATCH 342/797] staging: speakup: fix misuse of kstrtol() in handle_goto() A string of goto_buf has a number followed by x or y. e.g. "3x" means move 3 lines down. The kstrtol() returns an error(-EINVAL) with this string so go_pos has unsigned a value of that error. And also "*cp" has not expected value. And fix sparse warnings: drivers/staging/speakup/main.c:1901 handle_goto() warn: unsigned '(speakup_console[vc->vc_num]->go_pos)' is never less than zero. drivers/staging/speakup/main.c:1911 handle_goto() warn: unsigned '(speakup_console[vc->vc_num]->go_pos)' is never less than zero. Signed-off-by: Daeseok Youn Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/main.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c index ef5933b93590..3b6e5358c723 100644 --- a/drivers/staging/speakup/main.c +++ b/drivers/staging/speakup/main.c @@ -1855,8 +1855,9 @@ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) { static u_char goto_buf[8]; static int num; - int maxlen, go_pos; + int maxlen; char *cp; + if (type == KT_SPKUP && ch == SPEAKUP_GOTO) goto do_goto; if (type == KT_LATIN && ch == '\n') @@ -1891,25 +1892,24 @@ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key) spk_special_handler = NULL; return 1; } - go_pos = kstrtol(goto_buf, 10, (long *)&cp); - goto_pos = (u_long) go_pos; + + goto_pos = simple_strtoul(goto_buf, &cp, 10); + if (*cp == 'x') { if (*goto_buf < '0') goto_pos += spk_x; - else + else if (goto_pos > 0) goto_pos--; - if (goto_pos < 0) - goto_pos = 0; + if (goto_pos >= vc->vc_cols) goto_pos = vc->vc_cols - 1; goto_x = 1; } else { if (*goto_buf < '0') goto_pos += spk_y; - else + else if (goto_pos > 0) goto_pos--; - if (goto_pos < 0) - goto_pos = 0; + if (goto_pos >= vc->vc_rows) goto_pos = vc->vc_rows - 1; goto_x = 0; -- GitLab From d21bb45081484b95fb0c80f1afa492a7275689c2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Apr 2014 12:36:13 +0300 Subject: [PATCH 343/797] staging: unisys: use after free in error messages We dereference "bus" when we report the error so we have to move the kfree() down a couple lines. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/uislib/uislib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 8ea9c46e56ae..3152a2180c45 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -381,17 +381,17 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf) cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid; cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid; if (!VirtControlChanFunc) { - kfree(bus); LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, POSTCODE_SEVERITY_ERR); + kfree(bus); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE; } if (!VirtControlChanFunc(&cmd)) { - kfree(bus); LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error."); POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo, POSTCODE_SEVERITY_ERR); + kfree(bus); return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR; } -- GitLab From e6b1ea773e0a6dd611278d0d6f81ea6ff9d6938b Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 10 Apr 2014 12:45:45 +0300 Subject: [PATCH 344/797] Staging: unisys: use after free in list_for_each() These should be using the _safe version of list_for_each() because we free the current element and it leads to a use after free bug. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/visorchipset/visorchipset.h | 4 ++-- drivers/staging/unisys/visorchipset/visorchipset_main.c | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h index d4bf203cdfdf..d95825dc5414 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset.h +++ b/drivers/staging/unisys/visorchipset/visorchipset.h @@ -104,9 +104,9 @@ finddevice(struct list_head *list, U32 busNo, U32 devNo) static inline void delbusdevices(struct list_head *list, U32 busNo) { - VISORCHIPSET_DEVICE_INFO *p; + VISORCHIPSET_DEVICE_INFO *p, *tmp; - list_for_each_entry(p, list, entry) { + list_for_each_entry_safe(p, tmp, list, entry) { if (p->busNo == busNo) { list_del(&p->entry); kfree(p); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index 257c6e59b460..c475e256e34b 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -605,16 +605,16 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client); static void cleanup_controlvm_structures(void) { - VISORCHIPSET_BUS_INFO *bi; - VISORCHIPSET_DEVICE_INFO *di; + VISORCHIPSET_BUS_INFO *bi, *tmp_bi; + VISORCHIPSET_DEVICE_INFO *di, *tmp_di; - list_for_each_entry(bi, &BusInfoList, entry) { + list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) { busInfo_clear(bi); list_del(&bi->entry); kfree(bi); } - list_for_each_entry(di, &DevInfoList, entry) { + list_for_each_entry_safe(di, tmp_di, &DevInfoList, entry) { devInfo_clear(di); list_del(&di->entry); kfree(di); -- GitLab From 2c33d7cc3875e75311d24a3bfe8d40ca201da2da Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 10 Apr 2014 19:46:56 +0200 Subject: [PATCH 345/797] staging: r8723au: Add missing initialization of change_inx in sort algorithm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/staging/rtl8723au/core/rtw_wlan_util.c: In function ‘WMMOnAssocRsp23a’: drivers/staging/rtl8723au/core/rtw_wlan_util.c:684: warning: ‘change_inx’ may be used uninitialized in this function Depending on the uninitialized data on the stack, the array may not be sorted correctly. Signed-off-by: Geert Uytterhoeven Acked-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_wlan_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c index e743b053b8a2..99d81e612e7b 100644 --- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c @@ -681,7 +681,7 @@ void WMMOnAssocRsp23a(struct rtw_adapter *padapter) inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3; if (pregpriv->wifi_spec == 1) { - u32 j, tmp, change_inx; + u32 j, tmp, change_inx = false; /* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */ for (i = 0; i < 4; i++) { -- GitLab From b34aa86f12e8848ba453215602c8c50fa63c4cb3 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 10 Apr 2014 19:41:57 +0100 Subject: [PATCH 346/797] staging: comedi: fix circular locking dependency in comedi_mmap() Mmapping a comedi data buffer with lockdep checking enabled produced the following kernel debug messages: ====================================================== [ INFO: possible circular locking dependency detected ] 3.5.0-rc3-ija1+ #9 Tainted: G C ------------------------------------------------------- comedi_test/4160 is trying to acquire lock: (&dev->mutex#2){+.+.+.}, at: [] comedi_mmap+0x57/0x1d9 [comedi] but task is already holding lock: (&mm->mmap_sem){++++++}, at: [] vm_mmap_pgoff+0x41/0x76 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&mm->mmap_sem){++++++}: [] lock_acquire+0x97/0x105 [] might_fault+0x6d/0x90 [] do_devinfo_ioctl.isra.7+0x11e/0x14c [comedi] [] comedi_unlocked_ioctl+0x256/0xe48 [comedi] [] vfs_ioctl+0x18/0x34 [] do_vfs_ioctl+0x382/0x43c [] sys_ioctl+0x42/0x65 [] system_call_fastpath+0x16/0x1b -> #0 (&dev->mutex#2){+.+.+.}: [] __lock_acquire+0x101d/0x1591 [] lock_acquire+0x97/0x105 [] mutex_lock_nested+0x46/0x2a4 [] comedi_mmap+0x57/0x1d9 [comedi] [] mmap_region+0x281/0x492 [] do_mmap_pgoff+0x26b/0x2a7 [] vm_mmap_pgoff+0x5d/0x76 [] sys_mmap_pgoff+0xc7/0x10d [] sys_mmap+0x16/0x20 [] system_call_fastpath+0x16/0x1b other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&mm->mmap_sem); lock(&dev->mutex#2); lock(&mm->mmap_sem); lock(&dev->mutex#2); *** DEADLOCK *** To avoid the circular dependency, just try to get the lock in `comedi_mmap()` instead of blocking. Since the comedi device's main mutex is heavily used, do a down-read of its `attach_lock` rwsemaphore instead. Trying to down-read `attach_lock` should only fail if some task has down-write locked it, and that is only done while the comedi device is being attached to or detached from a low-level hardware device. Unfortunately, acquiring the `attach_lock` doesn't prevent another task replacing the comedi data buffer we are trying to mmap. The details of the buffer are held in a `struct comedi_buf_map` and pointed to by `s->async->buf_map` where `s` is the comedi subdevice whose buffer we are trying to map. The `struct comedi_buf_map` is already reference counted with a `struct kref`, so we can stop it being freed prematurely. Modify `comedi_mmap()` to call new function `comedi_buf_map_from_subdev_get()` to read the subdevice's current buffer map pointer and increment its reference instead of accessing `async->buf_map` directly. Call `comedi_buf_map_put()` to decrement the reference once the buffer map structure has been dealt with. (Note that `comedi_buf_map_put()` does nothing if passed a NULL pointer.) `comedi_buf_map_from_subdev_get()` checks the subdevice's buffer map pointer has been set and the buffer map has been initialized enough for `comedi_mmap()` to deal with it (specifically, check the `n_pages` member has been set to a non-zero value). If all is well, the buffer map's reference is incremented and a pointer to it is returned. The comedi subdevice's spin-lock is used to protect the checks. Also use the spin-lock in `__comedi_buf_alloc()` and `__comedi_buf_free()` to protect changes to the subdevice's buffer map structure pointer and the buffer map structure's `n_pages` member. (This checking of `n_pages` is a bit clunky and I [Ian Abbott] plan to deal with it in the future.) Signed-off-by: Ian Abbott Cc: # 3.14.x, 3.15.x Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/comedi_buf.c | 37 ++++++++++++++++++++++-- drivers/staging/comedi/comedi_fops.c | 18 +++++++++--- drivers/staging/comedi/comedi_internal.h | 2 ++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c index 924fce977985..257595016161 100644 --- a/drivers/staging/comedi/comedi_buf.c +++ b/drivers/staging/comedi/comedi_buf.c @@ -61,6 +61,8 @@ static void __comedi_buf_free(struct comedi_device *dev, struct comedi_subdevice *s) { struct comedi_async *async = s->async; + struct comedi_buf_map *bm; + unsigned long flags; if (async->prealloc_buf) { vunmap(async->prealloc_buf); @@ -68,8 +70,11 @@ static void __comedi_buf_free(struct comedi_device *dev, async->prealloc_bufsz = 0; } - comedi_buf_map_put(async->buf_map); + spin_lock_irqsave(&s->spin_lock, flags); + bm = async->buf_map; async->buf_map = NULL; + spin_unlock_irqrestore(&s->spin_lock, flags); + comedi_buf_map_put(bm); } static void __comedi_buf_alloc(struct comedi_device *dev, @@ -80,6 +85,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev, struct page **pages = NULL; struct comedi_buf_map *bm; struct comedi_buf_page *buf; + unsigned long flags; unsigned i; if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) { @@ -92,8 +98,10 @@ static void __comedi_buf_alloc(struct comedi_device *dev, if (!bm) return; - async->buf_map = bm; kref_init(&bm->refcount); + spin_lock_irqsave(&s->spin_lock, flags); + async->buf_map = bm; + spin_unlock_irqrestore(&s->spin_lock, flags); bm->dma_dir = s->async_dma_dir; if (bm->dma_dir != DMA_NONE) /* Need ref to hardware device to free buffer later. */ @@ -127,7 +135,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev, pages[i] = virt_to_page(buf->virt_addr); } + spin_lock_irqsave(&s->spin_lock, flags); bm->n_pages = i; + spin_unlock_irqrestore(&s->spin_lock, flags); /* vmap the prealloc_buf if all the pages were allocated */ if (i == n_pages) @@ -150,6 +160,29 @@ int comedi_buf_map_put(struct comedi_buf_map *bm) return 1; } +/* returns s->async->buf_map and increments its kref refcount */ +struct comedi_buf_map * +comedi_buf_map_from_subdev_get(struct comedi_subdevice *s) +{ + struct comedi_async *async = s->async; + struct comedi_buf_map *bm = NULL; + unsigned long flags; + + if (!async) + return NULL; + + spin_lock_irqsave(&s->spin_lock, flags); + bm = async->buf_map; + /* only want it if buffer pages allocated */ + if (bm && bm->n_pages) + comedi_buf_map_get(bm); + else + bm = NULL; + spin_unlock_irqrestore(&s->spin_lock, flags); + + return bm; +} + bool comedi_buf_is_mmapped(struct comedi_async *async) { struct comedi_buf_map *bm = async->buf_map; diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index ea6dc36d753b..acc80197e35e 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -1926,14 +1926,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) struct comedi_device *dev = file->private_data; struct comedi_subdevice *s; struct comedi_async *async; - struct comedi_buf_map *bm; + struct comedi_buf_map *bm = NULL; unsigned long start = vma->vm_start; unsigned long size; int n_pages; int i; int retval; - mutex_lock(&dev->mutex); + /* + * 'trylock' avoids circular dependency with current->mm->mmap_sem + * and down-reading &dev->attach_lock should normally succeed without + * contention unless the device is in the process of being attached + * or detached. + */ + if (!down_read_trylock(&dev->attach_lock)) + return -EAGAIN; if (!dev->attached) { dev_dbg(dev->class_dev, "no driver attached\n"); @@ -1973,7 +1980,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) } n_pages = size >> PAGE_SHIFT; - bm = async->buf_map; + + /* get reference to current buf map (if any) */ + bm = comedi_buf_map_from_subdev_get(s); if (!bm || n_pages > bm->n_pages) { retval = -EINVAL; goto done; @@ -1997,7 +2006,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma) retval = 0; done: - mutex_unlock(&dev->mutex); + up_read(&dev->attach_lock); + comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */ return retval; } diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h index 9a746570f161..a492f2d2436e 100644 --- a/drivers/staging/comedi/comedi_internal.h +++ b/drivers/staging/comedi/comedi_internal.h @@ -19,6 +19,8 @@ void comedi_buf_reset(struct comedi_async *async); bool comedi_buf_is_mmapped(struct comedi_async *async); void comedi_buf_map_get(struct comedi_buf_map *bm); int comedi_buf_map_put(struct comedi_buf_map *bm); +struct comedi_buf_map *comedi_buf_map_from_subdev_get( + struct comedi_subdevice *s); unsigned int comedi_buf_write_n_allocated(struct comedi_async *async); void comedi_device_cancel_all(struct comedi_device *dev); -- GitLab From 9452bf560273e4de2395ffdd79024debfb0c1290 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 9 Apr 2014 11:12:58 -0500 Subject: [PATCH 347/797] staging: r8188eu: Calling rtw_get_stainfo() with a NULL sta_addr will return NULL This makes the follow-on check for psta != NULL pointless and makes the whole exercise rather pointless. This is another case of why blindly zero-initializing variables when they are declared is bad. Reported-by: Jes Sorensen Signed-off-by: Larry Finger Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_recv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 636ec553ae83..01fcabcc8e56 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -545,7 +545,7 @@ static struct recv_frame *decryptor(struct adapter *padapter, static struct recv_frame *portctrl(struct adapter *adapter, struct recv_frame *precv_frame) { - u8 *psta_addr = NULL, *ptr; + u8 *psta_addr, *ptr; uint auth_alg; struct recv_frame *pfhdr; struct sta_info *psta; @@ -558,7 +558,6 @@ static struct recv_frame *portctrl(struct adapter *adapter, pstapriv = &adapter->stapriv; - psta = rtw_get_stainfo(pstapriv, psta_addr); auth_alg = adapter->securitypriv.dot11AuthAlgrthm; @@ -566,6 +565,7 @@ static struct recv_frame *portctrl(struct adapter *adapter, pfhdr = precv_frame; pattrib = &pfhdr->attrib; psta_addr = pattrib->ta; + psta = rtw_get_stainfo(pstapriv, psta_addr); prtnframe = NULL; -- GitLab From c11f1df5003d534fd067f0168bfad7befffb3b5c Mon Sep 17 00:00:00 2001 From: Sachin Prabhu Date: Tue, 11 Mar 2014 16:11:47 +0000 Subject: [PATCH 348/797] cifs: Wait for writebacks to complete before attempting write. Problem reported in Red Hat bz 1040329 for strict writes where we cache only when we hold oplock and write direct to the server when we don't. When we receive an oplock break, we first change the oplock value for the inode in cifsInodeInfo->oplock to indicate that we no longer hold the oplock before we enqueue a task to flush changes to the backing device. Once we have completed flushing the changes, we return the oplock to the server. There are 2 ways here where we can have data corruption 1) While we flush changes to the backing device as part of the oplock break, we can have processes write to the file. These writes check for the oplock, find none and attempt to write directly to the server. These direct writes made while we are flushing from cache could be overwritten by data being flushed from the cache causing data corruption. 2) While a thread runs in cifs_strict_writev, the machine could receive and process an oplock break after the thread has checked the oplock and found that it allows us to cache and before we have made changes to the cache. In that case, we end up with a dirty page in cache when we shouldn't have any. This will be flushed later and will overwrite all subsequent writes to the part of the file represented by this page. Before making any writes to the server, we need to confirm that we are not in the process of flushing data to the server and if we are, we should wait until the process is complete before we attempt the write. We should also wait for existing writes to complete before we process an oplock break request which changes oplock values. We add a version specific downgrade_oplock() operation to allow for differences in the oplock values set for the different smb versions. Cc: stable@vger.kernel.org Signed-off-by: Sachin Prabhu Reviewed-by: Jeff Layton Reviewed-by: Pavel Shilovsky Signed-off-by: Steve French --- fs/cifs/cifsfs.c | 14 ++++++++- fs/cifs/cifsglob.h | 8 +++++ fs/cifs/cifsproto.h | 3 ++ fs/cifs/file.c | 31 +++++++++++++++++-- fs/cifs/misc.c | 74 +++++++++++++++++++++++++++++++++++++++++++-- fs/cifs/smb1ops.c | 11 +++++++ fs/cifs/smb2misc.c | 18 +++++++++-- fs/cifs/smb2ops.c | 14 +++++++++ 8 files changed, 164 insertions(+), 9 deletions(-) diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index df9c9141c099..5be1f997ecde 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -253,6 +253,11 @@ cifs_alloc_inode(struct super_block *sb) cifs_set_oplock_level(cifs_inode, 0); cifs_inode->delete_pending = false; cifs_inode->invalid_mapping = false; + clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cifs_inode->flags); + clear_bit(CIFS_INODE_PENDING_WRITERS, &cifs_inode->flags); + clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cifs_inode->flags); + spin_lock_init(&cifs_inode->writers_lock); + cifs_inode->writers = 0; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ cifs_inode->server_eof = 0; cifs_inode->uniqueid = 0; @@ -732,19 +737,26 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos) { struct inode *inode = file_inode(iocb->ki_filp); + struct cifsInodeInfo *cinode = CIFS_I(inode); ssize_t written; int rc; + written = cifs_get_writer(cinode); + if (written) + return written; + written = generic_file_aio_write(iocb, iov, nr_segs, pos); if (CIFS_CACHE_WRITE(CIFS_I(inode))) - return written; + goto out; rc = filemap_fdatawrite(inode->i_mapping); if (rc) cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n", rc, inode); +out: + cifs_put_writer(cinode); return written; } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index c0f3718b77a8..30f6e9251a4a 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -228,6 +228,8 @@ struct smb_version_operations { /* verify the message */ int (*check_message)(char *, unsigned int); bool (*is_oplock_break)(char *, struct TCP_Server_Info *); + void (*downgrade_oplock)(struct TCP_Server_Info *, + struct cifsInodeInfo *, bool); /* process transaction2 response */ bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *, char *, int); @@ -1113,6 +1115,12 @@ struct cifsInodeInfo { unsigned int epoch; /* used to track lease state changes */ bool delete_pending; /* DELETE_ON_CLOSE is set */ bool invalid_mapping; /* pagecache is invalid */ + unsigned long flags; +#define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */ +#define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */ +#define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */ + spinlock_t writers_lock; + unsigned int writers; /* Number of writers on this inode */ unsigned long time; /* jiffies of last update of inode */ u64 server_eof; /* current file size on server -- protected by i_lock */ u64 uniqueid; /* server inode number */ diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index acc4ee8ed075..ca7980a1e303 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -127,6 +127,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec); extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset); extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); +extern int cifs_get_writer(struct cifsInodeInfo *cinode); +extern void cifs_put_writer(struct cifsInodeInfo *cinode); +extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode); extern int cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, const unsigned int xid); extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 8add25538a3b..d8ee76241b64 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2621,12 +2621,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); ssize_t written; + written = cifs_get_writer(cinode); + if (written) + return written; + if (CIFS_CACHE_WRITE(cinode)) { if (cap_unix(tcon->ses) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) - && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) - return generic_file_aio_write(iocb, iov, nr_segs, pos); - return cifs_writev(iocb, iov, nr_segs, pos); + && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { + written = generic_file_aio_write( + iocb, iov, nr_segs, pos); + goto out; + } + written = cifs_writev(iocb, iov, nr_segs, pos); + goto out; } /* * For non-oplocked files in strict cache mode we need to write the data @@ -2646,6 +2654,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov, inode); cinode->oplock = 0; } +out: + cifs_put_writer(cinode); return written; } @@ -3621,6 +3631,13 @@ static int cifs_launder_page(struct page *page) return rc; } +static int +cifs_pending_writers_wait(void *unused) +{ + schedule(); + return 0; +} + void cifs_oplock_break(struct work_struct *work) { struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, @@ -3628,8 +3645,15 @@ void cifs_oplock_break(struct work_struct *work) struct inode *inode = cfile->dentry->d_inode; struct cifsInodeInfo *cinode = CIFS_I(inode); struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); + struct TCP_Server_Info *server = tcon->ses->server; int rc = 0; + wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, + cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE); + + server->ops->downgrade_oplock(server, cinode, + test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags)); + if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && cifs_has_mand_locks(cinode)) { cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", @@ -3666,6 +3690,7 @@ void cifs_oplock_break(struct work_struct *work) cinode); cifs_dbg(FYI, "Oplock release rc = %d\n", rc); } + cifs_done_oplock_break(cinode); } /* diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 2f9f3790679d..3b0c62e622da 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -466,8 +466,22 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv) cifs_dbg(FYI, "file id match, oplock break\n"); pCifsInode = CIFS_I(netfile->dentry->d_inode); - cifs_set_oplock_level(pCifsInode, - pSMB->OplockLevel ? OPLOCK_READ : 0); + set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, + &pCifsInode->flags); + + /* + * Set flag if the server downgrades the oplock + * to L2 else clear. + */ + if (pSMB->OplockLevel) + set_bit( + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &pCifsInode->flags); + else + clear_bit( + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &pCifsInode->flags); + queue_work(cifsiod_wq, &netfile->oplock_break); netfile->oplock_break_cancelled = false; @@ -551,6 +565,62 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) cinode->oplock = 0; } +static int +cifs_oplock_break_wait(void *unused) +{ + schedule(); + return signal_pending(current) ? -ERESTARTSYS : 0; +} + +/* + * We wait for oplock breaks to be processed before we attempt to perform + * writes. + */ +int cifs_get_writer(struct cifsInodeInfo *cinode) +{ + int rc; + +start: + rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK, + cifs_oplock_break_wait, TASK_KILLABLE); + if (rc) + return rc; + + spin_lock(&cinode->writers_lock); + if (!cinode->writers) + set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); + cinode->writers++; + /* Check to see if we have started servicing an oplock break */ + if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) { + cinode->writers--; + if (cinode->writers == 0) { + clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); + wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); + } + spin_unlock(&cinode->writers_lock); + goto start; + } + spin_unlock(&cinode->writers_lock); + return 0; +} + +void cifs_put_writer(struct cifsInodeInfo *cinode) +{ + spin_lock(&cinode->writers_lock); + cinode->writers--; + if (cinode->writers == 0) { + clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags); + wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS); + } + spin_unlock(&cinode->writers_lock); +} + +void cifs_done_oplock_break(struct cifsInodeInfo *cinode) +{ + clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags); + wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK); +} + bool backup_cred(struct cifs_sb_info *cifs_sb) { diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 526fb89f9230..d1fdfa848703 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c @@ -372,6 +372,16 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr) return 0; } +static void +cifs_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, bool set_level2) +{ + if (set_level2) + cifs_set_oplock_level(cinode, OPLOCK_READ); + else + cifs_set_oplock_level(cinode, 0); +} + static bool cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server, char *buf, int malformed) @@ -1019,6 +1029,7 @@ struct smb_version_operations smb1_operations = { .clear_stats = cifs_clear_stats, .print_stats = cifs_print_stats, .is_oplock_break = is_valid_oplock_break, + .downgrade_oplock = cifs_downgrade_oplock, .check_trans2 = cifs_check_trans2, .need_neg = cifs_need_neg, .negotiate = cifs_negotiate, diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index fb3966265b6e..b8021fde987d 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c @@ -575,9 +575,21 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server) else cfile->oplock_break_cancelled = false; - server->ops->set_oplock_level(cinode, - rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0, - 0, NULL); + set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, + &cinode->flags); + + /* + * Set flag if the server downgrades the oplock + * to L2 else clear. + */ + if (rsp->OplockLevel) + set_bit( + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); + else + clear_bit( + CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, + &cinode->flags); queue_work(cifsiod_wq, &cfile->oplock_break); diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 192f51a12cf1..35ddc3ed119d 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c @@ -904,6 +904,17 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, return rc; } +static void +smb2_downgrade_oplock(struct TCP_Server_Info *server, + struct cifsInodeInfo *cinode, bool set_level2) +{ + if (set_level2) + server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II, + 0, NULL); + else + server->ops->set_oplock_level(cinode, 0, 0, NULL); +} + static void smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, unsigned int epoch, bool *purge_cache) @@ -1110,6 +1121,7 @@ struct smb_version_operations smb20_operations = { .clear_stats = smb2_clear_stats, .print_stats = smb2_print_stats, .is_oplock_break = smb2_is_valid_oplock_break, + .downgrade_oplock = smb2_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate, .negotiate_wsize = smb2_negotiate_wsize, @@ -1184,6 +1196,7 @@ struct smb_version_operations smb21_operations = { .clear_stats = smb2_clear_stats, .print_stats = smb2_print_stats, .is_oplock_break = smb2_is_valid_oplock_break, + .downgrade_oplock = smb2_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate, .negotiate_wsize = smb2_negotiate_wsize, @@ -1259,6 +1272,7 @@ struct smb_version_operations smb30_operations = { .print_stats = smb2_print_stats, .dump_share_caps = smb2_dump_share_caps, .is_oplock_break = smb2_is_valid_oplock_break, + .downgrade_oplock = smb2_downgrade_oplock, .need_neg = smb2_need_neg, .negotiate = smb2_negotiate, .negotiate_wsize = smb2_negotiate_wsize, -- GitLab From 60977fcc808664f82412bb37da7be17640ba99d9 Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 25 Mar 2014 19:46:36 -0500 Subject: [PATCH 349/797] Return correct error on query of xattr on file with empty xattrs xfstest 020 detected a problem with cifs xattr handling. When a file had an empty xattr list, we returned success (with an empty xattr value) on query of particular xattrs rather than returning ENODATA. This patch fixes it so that query of an xattr returns ENODATA when the xattr list is empty for the file. Signed-off-by: Steve French Reviewed-by: Jeff Layton --- fs/cifs/cifssmb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index f3264bd7a83d..6ce4e0954b98 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -6197,6 +6197,9 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon, cifs_dbg(FYI, "ea length %d\n", list_len); if (list_len <= 8) { cifs_dbg(FYI, "empty EA list returned from server\n"); + /* didn't find the named attribute */ + if (ea_name) + rc = -ENODATA; goto QAllEAsOut; } -- GitLab From 8e3ecc87695f4a7e9e217ebd55ca6a39b6a451b8 Mon Sep 17 00:00:00 2001 From: Cyril Roelandt Date: Fri, 4 Apr 2014 00:05:21 +0200 Subject: [PATCH 350/797] fs: cifs: remove unused variable. In SMB2_set_compression(), the "res_key" variable is only initialized to NULL and later kfreed. It is therefore useless and should be removed. Found with the following semantic patch: @@ identifier foo; identifier f; type T; @@ * f(...) { ... * T *foo = NULL; ... when forall when != foo * kfree(foo); ... } Signed-off-by: Cyril Roelandt Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 860344701067..3802f8c94acc 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1352,7 +1352,6 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid) { int rc; - char *res_key = NULL; struct compress_ioctl fsctl_input; char *ret_data = NULL; @@ -1365,7 +1364,6 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon, 2 /* in data len */, &ret_data /* out data */, NULL); cifs_dbg(FYI, "set compression rc %d\n", rc); - kfree(res_key); return rc; } -- GitLab From a2a4dc494a7b7135f460e38e788c4a58f65e4ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20B=C3=A4chler?= Date: Thu, 3 Apr 2014 21:55:37 +0200 Subject: [PATCH 351/797] fs: Don't return 0 from get_anon_bdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 9e30cc9595303b27b48 removed an internal mount. This has the side-effect that rootfs now has FSID 0. Many userspace utilities assume that st_dev in struct stat is never 0, so this change breaks a number of tools in early userspace. Since we don't know how many userspace programs are affected, make sure that FSID is at least 1. References: http://article.gmane.org/gmane.linux.kernel/1666905 References: http://permalink.gmane.org/gmane.linux.utilities.util-linux-ng/8557 Cc: 3.14 Signed-off-by: Thomas Bächler Acked-by: Tejun Heo Acked-by: H. Peter Anvin Tested-by: Alexandre Demers Signed-off-by: Greg Kroah-Hartman --- fs/super.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index e9dc3c3fe159..48377f7463c0 100644 --- a/fs/super.c +++ b/fs/super.c @@ -800,7 +800,10 @@ void emergency_remount(void) static DEFINE_IDA(unnamed_dev_ida); static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */ -static int unnamed_dev_start = 0; /* don't bother trying below it */ +/* Many userspace utilities consider an FSID of 0 invalid. + * Always return at least 1 from get_anon_bdev. + */ +static int unnamed_dev_start = 1; int get_anon_bdev(dev_t *p) { -- GitLab From 4afddd60a770560d370d6f85c5aef57c16bf7502 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 2 Apr 2014 16:40:52 -0400 Subject: [PATCH 352/797] kernfs: protect lazy kernfs_iattrs allocation with mutex kernfs_iattrs is allocated lazily when operations which require it take place; unfortunately, the lazy allocation and returning weren't properly synchronized and when there are multiple concurrent operations, it might end up returning kernfs_iattrs which hasn't finished initialization yet or different copies to different callers. Fix it by synchronizing with a mutex. This can be smarter with memory barriers but let's go there if it actually turns out to be necessary. Signed-off-by: Tejun Heo Link: http://lkml.kernel.org/g/533ABA32.9080602@oracle.com Reported-by: Sasha Levin Cc: stable@vger.kernel.org # 3.14 Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/inode.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index abb0f1f53d93..985217626e66 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c @@ -48,14 +48,18 @@ void __init kernfs_inode_init(void) static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) { + static DEFINE_MUTEX(iattr_mutex); + struct kernfs_iattrs *ret; struct iattr *iattrs; + mutex_lock(&iattr_mutex); + if (kn->iattr) - return kn->iattr; + goto out_unlock; kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL); if (!kn->iattr) - return NULL; + goto out_unlock; iattrs = &kn->iattr->ia_iattr; /* assign default attributes */ @@ -65,8 +69,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; simple_xattrs_init(&kn->iattr->xattrs); - - return kn->iattr; +out_unlock: + ret = kn->iattr; + mutex_unlock(&iattr_mutex); + return ret; } static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) -- GitLab From 33ac1257ff0dee2e9c7f009b1c1914b7990217b2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 10 Jan 2014 08:57:31 -0500 Subject: [PATCH 353/797] sysfs, driver-core: remove unused {sysfs|device}_schedule_callback_owner() All device_schedule_callback_owner() users are converted to use device_remove_file_self(). Remove now unused {sysfs|device}_schedule_callback_owner(). Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 33 --------------- fs/sysfs/file.c | 92 ------------------------------------------ include/linux/device.h | 11 +---- include/linux/sysfs.h | 9 ----- 4 files changed, 1 insertion(+), 144 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 0dd65281cc65..20da3ad1696b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -614,39 +614,6 @@ void device_remove_bin_file(struct device *dev, } EXPORT_SYMBOL_GPL(device_remove_bin_file); -/** - * device_schedule_callback_owner - helper to schedule a callback for a device - * @dev: device. - * @func: callback function to invoke later. - * @owner: module owning the callback routine - * - * Attribute methods must not unregister themselves or their parent device - * (which would amount to the same thing). Attempts to do so will deadlock, - * since unregistration is mutually exclusive with driver callbacks. - * - * Instead methods can call this routine, which will attempt to allocate - * and schedule a workqueue request to call back @func with @dev as its - * argument in the workqueue's process context. @dev will be pinned until - * @func returns. - * - * This routine is usually called via the inline device_schedule_callback(), - * which automatically sets @owner to THIS_MODULE. - * - * Returns 0 if the request was submitted, -ENOMEM if storage could not - * be allocated, -ENODEV if a reference to @owner isn't available. - * - * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an - * underlying sysfs routine (since it is intended for use by attribute - * methods), and if sysfs isn't available you'll get nothing but -ENOSYS. - */ -int device_schedule_callback_owner(struct device *dev, - void (*func)(struct device *), struct module *owner) -{ - return sysfs_schedule_callback(&dev->kobj, - (void (*)(void *)) func, dev, owner); -} -EXPORT_SYMBOL_GPL(device_schedule_callback_owner); - static void klist_children_get(struct klist_node *n) { struct device_private *p = to_device_private_parent(n); diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 1b8b91b67fdb..28cc1acd5439 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -453,95 +453,3 @@ void sysfs_remove_bin_file(struct kobject *kobj, kernfs_remove_by_name(kobj->sd, attr->attr.name); } EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); - -struct sysfs_schedule_callback_struct { - struct list_head workq_list; - struct kobject *kobj; - void (*func)(void *); - void *data; - struct module *owner; - struct work_struct work; -}; - -static struct workqueue_struct *sysfs_workqueue; -static DEFINE_MUTEX(sysfs_workq_mutex); -static LIST_HEAD(sysfs_workq); -static void sysfs_schedule_callback_work(struct work_struct *work) -{ - struct sysfs_schedule_callback_struct *ss = container_of(work, - struct sysfs_schedule_callback_struct, work); - - (ss->func)(ss->data); - kobject_put(ss->kobj); - module_put(ss->owner); - mutex_lock(&sysfs_workq_mutex); - list_del(&ss->workq_list); - mutex_unlock(&sysfs_workq_mutex); - kfree(ss); -} - -/** - * sysfs_schedule_callback - helper to schedule a callback for a kobject - * @kobj: object we're acting for. - * @func: callback function to invoke later. - * @data: argument to pass to @func. - * @owner: module owning the callback code - * - * sysfs attribute methods must not unregister themselves or their parent - * kobject (which would amount to the same thing). Attempts to do so will - * deadlock, since unregistration is mutually exclusive with driver - * callbacks. - * - * Instead methods can call this routine, which will attempt to allocate - * and schedule a workqueue request to call back @func with @data as its - * argument in the workqueue's process context. @kobj will be pinned - * until @func returns. - * - * Returns 0 if the request was submitted, -ENOMEM if storage could not - * be allocated, -ENODEV if a reference to @owner isn't available, - * -EAGAIN if a callback has already been scheduled for @kobj. - */ -int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), - void *data, struct module *owner) -{ - struct sysfs_schedule_callback_struct *ss, *tmp; - - if (!try_module_get(owner)) - return -ENODEV; - - mutex_lock(&sysfs_workq_mutex); - list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list) - if (ss->kobj == kobj) { - module_put(owner); - mutex_unlock(&sysfs_workq_mutex); - return -EAGAIN; - } - mutex_unlock(&sysfs_workq_mutex); - - if (sysfs_workqueue == NULL) { - sysfs_workqueue = create_singlethread_workqueue("sysfsd"); - if (sysfs_workqueue == NULL) { - module_put(owner); - return -ENOMEM; - } - } - - ss = kmalloc(sizeof(*ss), GFP_KERNEL); - if (!ss) { - module_put(owner); - return -ENOMEM; - } - kobject_get(kobj); - ss->kobj = kobj; - ss->func = func; - ss->data = data; - ss->owner = owner; - INIT_WORK(&ss->work, sysfs_schedule_callback_work); - INIT_LIST_HEAD(&ss->workq_list); - mutex_lock(&sysfs_workq_mutex); - list_add_tail(&ss->workq_list, &sysfs_workq); - mutex_unlock(&sysfs_workq_mutex); - queue_work(sysfs_workqueue, &ss->work); - return 0; -} -EXPORT_SYMBOL_GPL(sysfs_schedule_callback); diff --git a/include/linux/device.h b/include/linux/device.h index 233bbbeb768d..d1d1c055b48e 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -566,12 +566,6 @@ extern int __must_check device_create_bin_file(struct device *dev, const struct bin_attribute *attr); extern void device_remove_bin_file(struct device *dev, const struct bin_attribute *attr); -extern int device_schedule_callback_owner(struct device *dev, - void (*func)(struct device *dev), struct module *owner); - -/* This is a macro to avoid include problems with THIS_MODULE */ -#define device_schedule_callback(dev, func) \ - device_schedule_callback_owner(dev, func, THIS_MODULE) /* device resource management */ typedef void (*dr_release_t)(struct device *dev, void *res); @@ -932,10 +926,7 @@ extern int device_online(struct device *dev); extern struct device *__root_device_register(const char *name, struct module *owner); -/* - * This is a macro to avoid include problems with THIS_MODULE, - * just as per what is done for device_schedule_callback() above. - */ +/* This is a macro to avoid include problems with THIS_MODULE */ #define root_device_register(name) \ __root_device_register(name, THIS_MODULE) diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 084354b0e814..5ffaa3443712 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -179,9 +179,6 @@ struct sysfs_ops { #ifdef CONFIG_SYSFS -int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), - void *data, struct module *owner); - int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns); void sysfs_remove_dir(struct kobject *kobj); int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name, @@ -255,12 +252,6 @@ static inline void sysfs_enable_ns(struct kernfs_node *kn) #else /* CONFIG_SYSFS */ -static inline int sysfs_schedule_callback(struct kobject *kobj, - void (*func)(void *), void *data, struct module *owner) -{ - return -ENOSYS; -} - static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns) { return 0; -- GitLab From c98235cb8584a72e95786e17d695a8e5fafcd766 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 15 Apr 2014 18:09:24 -0400 Subject: [PATCH 354/797] mlx4_en: don't use napi_synchronize inside mlx4_en_netpoll The mlx4 driver is triggering schedules while atomic inside mlx4_en_netpoll: spin_lock_irqsave(&cq->lock, flags); napi_synchronize(&cq->napi); ^^^^^ msleep here mlx4_en_process_rx_cq(dev, cq, 0); spin_unlock_irqrestore(&cq->lock, flags); This was part of a patch by Alexander Guller from Mellanox in 2011, but it still isn't upstream. Signed-off-by: Chris Mason cc: stable@vger.kernel.org Acked-By: Amir Vadai Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_cq.c | 1 - drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 6 +----- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c index 70e95324a97d..c2cd8d31bcad 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c @@ -66,7 +66,6 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv, cq->ring = ring; cq->is_tx = mode; - spin_lock_init(&cq->lock); /* Allocate HW buffers on provided NUMA node. * dev->numa_node is used in mtt range allocation flow. diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index f085c2df5e69..7e4b1720c3d1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1304,15 +1304,11 @@ static void mlx4_en_netpoll(struct net_device *dev) { struct mlx4_en_priv *priv = netdev_priv(dev); struct mlx4_en_cq *cq; - unsigned long flags; int i; for (i = 0; i < priv->rx_ring_num; i++) { cq = priv->rx_cq[i]; - spin_lock_irqsave(&cq->lock, flags); - napi_synchronize(&cq->napi); - mlx4_en_process_rx_cq(dev, cq, 0); - spin_unlock_irqrestore(&cq->lock, flags); + napi_schedule(&cq->napi); } } #endif diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 7a733c287744..04d9b6fe3e80 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -319,7 +319,6 @@ struct mlx4_en_cq { struct mlx4_cq mcq; struct mlx4_hwq_resources wqres; int ring; - spinlock_t lock; struct net_device *dev; struct napi_struct napi; int size; -- GitLab From 6a662719c9868b3d6c7d26b3a085f0cd3cc15e64 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Tue, 15 Apr 2014 16:25:34 -0700 Subject: [PATCH 355/797] ipv4, fib: pass LOOPBACK_IFINDEX instead of 0 to flowi4_iif MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As suggested by Julian: Simply, flowi4_iif must not contain 0, it does not look logical to ignore all ip rules with specified iif. because in fib_rule_match() we do: if (rule->iifindex && (rule->iifindex != fl->flowi_iif)) goto out; flowi4_iif should be LOOPBACK_IFINDEX by default. We need to move LOOPBACK_IFINDEX to include/net/flow.h: 1) It is mostly used by flowi_iif 2) Fix the following compile error if we use it in flow.h by the patches latter: In file included from include/linux/netfilter.h:277:0, from include/net/netns/netfilter.h:5, from include/net/net_namespace.h:21, from include/linux/netdevice.h:43, from include/linux/icmpv6.h:12, from include/linux/ipv6.h:61, from include/net/ipv6.h:16, from include/linux/sunrpc/clnt.h:27, from include/linux/nfs_fs.h:30, from init/do_mounts.c:32: include/net/flow.h: In function ‘flowi4_init_output’: include/net/flow.h:84:32: error: ‘LOOPBACK_IFINDEX’ undeclared (first use in this function) Cc: Eric Biederman Cc: Julian Anastasov Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- include/net/flow.h | 10 +++++++++- include/net/net_namespace.h | 9 +-------- net/ipv4/fib_frontend.c | 2 +- net/ipv4/fib_semantics.c | 1 + net/ipv4/ipmr.c | 2 +- net/ipv4/netfilter/ipt_rpfilter.c | 5 +---- net/ipv6/ip6mr.c | 2 +- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/include/net/flow.h b/include/net/flow.h index 64fd24836650..8109a159d1b3 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -11,6 +11,14 @@ #include #include +/* + * ifindex generation is per-net namespace, and loopback is + * always the 1st device in ns (see net_dev_init), thus any + * loopback device should get ifindex 1 + */ + +#define LOOPBACK_IFINDEX 1 + struct flowi_common { int flowic_oif; int flowic_iif; @@ -80,7 +88,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif, __be16 dport, __be16 sport) { fl4->flowi4_oif = oif; - fl4->flowi4_iif = 0; + fl4->flowi4_iif = LOOPBACK_IFINDEX; fl4->flowi4_mark = mark; fl4->flowi4_tos = tos; fl4->flowi4_scope = scope; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 79387f73f875..5f9eb260990f 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -131,14 +132,6 @@ struct net { atomic_t fnhe_genid; }; -/* - * ifindex generation is per-net namespace, and loopback is - * always the 1st device in ns (see net_dev_init), thus any - * loopback device should get ifindex 1 - */ - -#define LOOPBACK_IFINDEX 1 - #include /* Init's network namespace */ diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 1a629f870274..255aa9946fe7 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -250,7 +250,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, bool dev_match; fl4.flowi4_oif = 0; - fl4.flowi4_iif = oif; + fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX; fl4.daddr = src; fl4.saddr = dst; fl4.flowi4_tos = tos; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index b53f0bf84dca..8a043f03c88e 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -631,6 +631,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, .daddr = nh->nh_gw, .flowi4_scope = cfg->fc_scope + 1, .flowi4_oif = nh->nh_oif, + .flowi4_iif = LOOPBACK_IFINDEX, }; /* It is not necessary, but requires a bit of thinking */ diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 28863570dd60..d84dc8d4c916 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -455,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) struct mr_table *mrt; struct flowi4 fl4 = { .flowi4_oif = dev->ifindex, - .flowi4_iif = skb->skb_iif, + .flowi4_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, .flowi4_mark = skb->mark, }; int err; diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c index c49dcd0284a0..4bfaedf9b34e 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c @@ -89,11 +89,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) if (ipv4_is_multicast(iph->daddr)) { if (ipv4_is_zeronet(iph->saddr)) return ipv4_is_local_multicast(iph->daddr) ^ invert; - flow.flowi4_iif = 0; - } else { - flow.flowi4_iif = LOOPBACK_IFINDEX; } - + flow.flowi4_iif = LOOPBACK_IFINDEX; flow.daddr = iph->saddr; flow.saddr = rpfilter_get_saddr(iph->daddr); flow.flowi4_oif = 0; diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 8737400af0a0..8659067da28e 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -700,7 +700,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct mr6_table *mrt; struct flowi6 fl6 = { .flowi6_oif = dev->ifindex, - .flowi6_iif = skb->skb_iif, + .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, .flowi6_mark = skb->mark, }; int err; -- GitLab From 0d5edc68739f1c1e0519acbea1d3f0c1882a15d7 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Tue, 15 Apr 2014 16:25:35 -0700 Subject: [PATCH 356/797] ipv4, route: pass 0 instead of LOOPBACK_IFINDEX to fib_validate_source() In my special case, when a packet is redirected from veth0 to lo, its skb->dev->ifindex would be LOOPBACK_IFINDEX. Meanwhile we pass the hard-coded LOOPBACK_IFINDEX to fib_validate_source() in ip_route_input_slow(). This would cause the following check in fib_validate_source() fail: (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev)) when rp_filter is disabeld on loopback. As suggested by Julian, the caller should pass 0 here so that we will not end up by calling __fib_validate_source(). Cc: Eric Biederman Cc: Julian Anastasov Cc: David S. Miller Signed-off-by: Cong Wang Signed-off-by: Cong Wang Signed-off-by: David S. Miller --- net/ipv4/route.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 1485aafcad59..db1e0da871f4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1700,8 +1700,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr, if (res.type == RTN_LOCAL) { err = fib_validate_source(skb, saddr, daddr, tos, - LOOPBACK_IFINDEX, - dev, in_dev, &itag); + 0, dev, in_dev, &itag); if (err < 0) goto martian_source_keep_err; goto local_input; -- GitLab From 78cdb079685cd8365acaf9fce896137e7d60e1c1 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 15 Apr 2014 19:16:40 -0700 Subject: [PATCH 357/797] net: mdio-gpio: Use devm_ functions where possible This simplifies error path and deinit/removal functions. Signed-off-by: Guenter Roeck Tested-by: Chris Healy Signed-off-by: David S. Miller --- drivers/net/phy/mdio-gpio.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index e701433bf52f..e853066c805a 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -110,7 +110,7 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, struct mdio_gpio_info *bitbang; int i; - bitbang = kzalloc(sizeof(*bitbang), GFP_KERNEL); + bitbang = devm_kzalloc(dev, sizeof(*bitbang), GFP_KERNEL); if (!bitbang) goto out; @@ -121,7 +121,7 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, new_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!new_bus) - goto out_free_bitbang; + goto out; new_bus->name = "GPIO Bitbanged MDIO", @@ -138,11 +138,11 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); - if (gpio_request(bitbang->mdc, "mdc")) + if (devm_gpio_request(dev, bitbang->mdc, "mdc")) goto out_free_bus; - if (gpio_request(bitbang->mdio, "mdio")) - goto out_free_mdc; + if (devm_gpio_request(dev, bitbang->mdio, "mdio")) + goto out_free_bus; gpio_direction_output(bitbang->mdc, 0); @@ -150,12 +150,8 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, return new_bus; -out_free_mdc: - gpio_free(bitbang->mdc); out_free_bus: free_mdio_bitbang(new_bus); -out_free_bitbang: - kfree(bitbang); out: return NULL; } @@ -163,13 +159,8 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, static void mdio_gpio_bus_deinit(struct device *dev) { struct mii_bus *bus = dev_get_drvdata(dev); - struct mdio_gpio_info *bitbang = bus->priv; - dev_set_drvdata(dev, NULL); - gpio_free(bitbang->mdio); - gpio_free(bitbang->mdc); free_mdio_bitbang(bus); - kfree(bitbang); } static void mdio_gpio_bus_destroy(struct device *dev) -- GitLab From 1d2514818a2c3d94dd250e6027cb928a4e192548 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 15 Apr 2014 19:16:41 -0700 Subject: [PATCH 358/797] net: mdio-gpio: Add support for active low gpio pins Some systems using mdio-gpio may use active-low gpio pins (eg with inverters or FETs connected to all or some of the gpio pins). Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/phy/mdio-gpio.c | 19 +++++++++++++------ include/linux/mdio-gpio.h | 3 +++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index e853066c805a..fac211a5001e 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -33,28 +33,32 @@ struct mdio_gpio_info { struct mdiobb_ctrl ctrl; int mdc, mdio; + int mdc_active_low, mdio_active_low; }; static void *mdio_gpio_of_get_data(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mdio_gpio_platform_data *pdata; + enum of_gpio_flags flags; int ret; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; - ret = of_get_gpio(np, 0); + ret = of_get_gpio_flags(np, 0, &flags); if (ret < 0) return NULL; pdata->mdc = ret; + pdata->mdc_active_low = flags & OF_GPIO_ACTIVE_LOW; - ret = of_get_gpio(np, 1); + ret = of_get_gpio_flags(np, 1, &flags); if (ret < 0) return NULL; pdata->mdio = ret; + pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW; return pdata; } @@ -65,7 +69,8 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) container_of(ctrl, struct mdio_gpio_info, ctrl); if (dir) - gpio_direction_output(bitbang->mdio, 1); + gpio_direction_output(bitbang->mdio, + 1 ^ bitbang->mdio_active_low); else gpio_direction_input(bitbang->mdio); } @@ -75,7 +80,7 @@ static int mdio_get(struct mdiobb_ctrl *ctrl) struct mdio_gpio_info *bitbang = container_of(ctrl, struct mdio_gpio_info, ctrl); - return gpio_get_value(bitbang->mdio); + return gpio_get_value(bitbang->mdio) ^ bitbang->mdio_active_low; } static void mdio_set(struct mdiobb_ctrl *ctrl, int what) @@ -83,7 +88,7 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what) struct mdio_gpio_info *bitbang = container_of(ctrl, struct mdio_gpio_info, ctrl); - gpio_set_value(bitbang->mdio, what); + gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low); } static void mdc_set(struct mdiobb_ctrl *ctrl, int what) @@ -91,7 +96,7 @@ static void mdc_set(struct mdiobb_ctrl *ctrl, int what) struct mdio_gpio_info *bitbang = container_of(ctrl, struct mdio_gpio_info, ctrl); - gpio_set_value(bitbang->mdc, what); + gpio_set_value(bitbang->mdc, what ^ bitbang->mdc_active_low); } static struct mdiobb_ops mdio_gpio_ops = { @@ -117,7 +122,9 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, bitbang->ctrl.ops = &mdio_gpio_ops; bitbang->ctrl.reset = pdata->reset; bitbang->mdc = pdata->mdc; + bitbang->mdc_active_low = pdata->mdc_active_low; bitbang->mdio = pdata->mdio; + bitbang->mdio_active_low = pdata->mdio_active_low; new_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!new_bus) diff --git a/include/linux/mdio-gpio.h b/include/linux/mdio-gpio.h index 7c9fe3c2be73..57e57fe6055c 100644 --- a/include/linux/mdio-gpio.h +++ b/include/linux/mdio-gpio.h @@ -18,6 +18,9 @@ struct mdio_gpio_platform_data { unsigned int mdc; unsigned int mdio; + bool mdc_active_low; + bool mdio_active_low; + unsigned int phy_mask; int irqs[PHY_MAX_ADDR]; /* reset callback */ -- GitLab From f1d54c47502f42f5c4b89dacbe845ecd87ca002e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Tue, 15 Apr 2014 19:16:42 -0700 Subject: [PATCH 359/797] net: mdio-gpio: Add support for separate MDI and MDO gpio pins This is for a system with fixed assignments of input and output pins (various variants of Kontron COMe). Signed-off-by: Guenter Roeck Signed-off-by: David S. Miller --- drivers/net/phy/mdio-gpio.c | 34 +++++++++++++++++++++++++++++++--- include/linux/mdio-gpio.h | 2 ++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index fac211a5001e..9c4defdec67b 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c @@ -32,8 +32,8 @@ struct mdio_gpio_info { struct mdiobb_ctrl ctrl; - int mdc, mdio; - int mdc_active_low, mdio_active_low; + int mdc, mdio, mdo; + int mdc_active_low, mdio_active_low, mdo_active_low; }; static void *mdio_gpio_of_get_data(struct platform_device *pdev) @@ -60,6 +60,12 @@ static void *mdio_gpio_of_get_data(struct platform_device *pdev) pdata->mdio = ret; pdata->mdio_active_low = flags & OF_GPIO_ACTIVE_LOW; + ret = of_get_gpio_flags(np, 2, &flags); + if (ret > 0) { + pdata->mdo = ret; + pdata->mdo_active_low = flags & OF_GPIO_ACTIVE_LOW; + } + return pdata; } @@ -68,6 +74,16 @@ static void mdio_dir(struct mdiobb_ctrl *ctrl, int dir) struct mdio_gpio_info *bitbang = container_of(ctrl, struct mdio_gpio_info, ctrl); + if (bitbang->mdo) { + /* Separate output pin. Always set its value to high + * when changing direction. If direction is input, + * assume the pin serves as pull-up. If direction is + * output, the default value is high. + */ + gpio_set_value(bitbang->mdo, 1 ^ bitbang->mdo_active_low); + return; + } + if (dir) gpio_direction_output(bitbang->mdio, 1 ^ bitbang->mdio_active_low); @@ -88,7 +104,10 @@ static void mdio_set(struct mdiobb_ctrl *ctrl, int what) struct mdio_gpio_info *bitbang = container_of(ctrl, struct mdio_gpio_info, ctrl); - gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low); + if (bitbang->mdo) + gpio_set_value(bitbang->mdo, what ^ bitbang->mdo_active_low); + else + gpio_set_value(bitbang->mdio, what ^ bitbang->mdio_active_low); } static void mdc_set(struct mdiobb_ctrl *ctrl, int what) @@ -125,6 +144,8 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, bitbang->mdc_active_low = pdata->mdc_active_low; bitbang->mdio = pdata->mdio; bitbang->mdio_active_low = pdata->mdio_active_low; + bitbang->mdo = pdata->mdo; + bitbang->mdo_active_low = pdata->mdo_active_low; new_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!new_bus) @@ -151,6 +172,13 @@ static struct mii_bus *mdio_gpio_bus_init(struct device *dev, if (devm_gpio_request(dev, bitbang->mdio, "mdio")) goto out_free_bus; + if (bitbang->mdo) { + if (devm_gpio_request(dev, bitbang->mdo, "mdo")) + goto out_free_bus; + gpio_direction_output(bitbang->mdo, 1); + gpio_direction_input(bitbang->mdio); + } + gpio_direction_output(bitbang->mdc, 0); dev_set_drvdata(dev, new_bus); diff --git a/include/linux/mdio-gpio.h b/include/linux/mdio-gpio.h index 57e57fe6055c..66c30a763b10 100644 --- a/include/linux/mdio-gpio.h +++ b/include/linux/mdio-gpio.h @@ -17,9 +17,11 @@ struct mdio_gpio_platform_data { /* GPIO numbers for bus pins */ unsigned int mdc; unsigned int mdio; + unsigned int mdo; bool mdc_active_low; bool mdio_active_low; + bool mdo_active_low; unsigned int phy_mask; int irqs[PHY_MAX_ADDR]; -- GitLab From 5c5e0589038537848849fc827f5234a31a10f899 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Thu, 20 Mar 2014 15:11:02 +0100 Subject: [PATCH 360/797] GenWQE: Enable access to VPD flash area In addition to the two flash partitions we used so far, there is a 3rd one which is enabled for usage by this fix. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_dev.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 2c2c9cc75231..0d05ca77c458 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -531,7 +531,9 @@ static int do_flash_update(struct genwqe_file *cfile, case '1': cmdopts = 0x1C; break; /* download/erase_first/part_1 */ - case 'v': /* cmdopts = 0x0c (VPD) */ + case 'v': + cmdopts = 0x0C; + break; /* download/erase_first/vpd */ default: return -EINVAL; } @@ -665,6 +667,8 @@ static int do_flash_read(struct genwqe_file *cfile, cmdopts = 0x1A; break; /* upload/part_1 */ case 'v': + cmdopts = 0x0A; + break; /* upload/vpd */ default: return -EINVAL; } -- GitLab From 68fe8acc204c7fbefd4c01b8929fedb244ec283d Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Thu, 20 Mar 2014 15:11:03 +0100 Subject: [PATCH 361/797] GenWQE: Add wmb before DDCB is started Needed to add wmb() before we send the DDCB for execution. Without the syncronizing it failed on System p. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_ddcb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index 6f1acc0ccf88..29a1a28be02a 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -305,6 +305,8 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue, break; new = (old | DDCB_NEXT_BE32); + + wmb(); icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new); if (icrc_hsi_shi == old) @@ -314,6 +316,8 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue, /* Queue must be re-started by updating QUEUE_OFFSET */ ddcb_mark_tapped(pddcb); num = (u64)ddcb_no << 8; + + wmb(); __genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */ return RET_DDCB_TAPPED; -- GitLab From ebb2c96bb9214ba38c7fe35d5d725f6e7cb3bbc8 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Thu, 20 Mar 2014 15:11:04 +0100 Subject: [PATCH 362/797] GenWQE: Ensure rc is not returning an uninitialized value rc is not initialized, so genwqe_finish_queue() either returns -EIO or garbage. Fortunately the return is not being checked by any callers, so this has not yet caused any problems. Even so, it makes sense to fix this small bug in case is is checked in future. Signed-off-by: Colin Ian King Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_ddcb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index 29a1a28be02a..c8046db2d5a2 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -1310,7 +1310,7 @@ static int queue_wake_up_all(struct genwqe_dev *cd) */ int genwqe_finish_queue(struct genwqe_dev *cd) { - int i, rc, in_flight; + int i, rc = 0, in_flight; int waitmax = genwqe_ddcb_software_timeout; struct pci_dev *pci_dev = cd->pci_dev; struct ddcb_queue *queue = &cd->queue; -- GitLab From 718f762efc454796d02f172a929d051f2d6ec01a Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Thu, 20 Mar 2014 15:11:05 +0100 Subject: [PATCH 363/797] GenWQE: Fix multithreading problems When being used in a multithreaded application there were problems with memory pages/cachelines accessed by multiple threads/cpus at the same time, while doing DMA transfers to/from those. To avoid such situations this fix is creating a copy of the first and the last page if it is not fully used. The data is copied from user-space into those pages and results are copied back when the DDCB-request is successfully finished. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/card_base.h | 58 +++++++---- drivers/misc/genwqe/card_dev.c | 38 ++----- drivers/misc/genwqe/card_utils.c | 170 +++++++++++++++++++++++-------- 3 files changed, 180 insertions(+), 86 deletions(-) diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h index 5e4dbd21f89a..0e608a288603 100644 --- a/drivers/misc/genwqe/card_base.h +++ b/drivers/misc/genwqe/card_base.h @@ -336,6 +336,44 @@ enum genwqe_requ_state { GENWQE_REQU_STATE_MAX, }; +/** + * struct genwqe_sgl - Scatter gather list describing user-space memory + * @sgl: scatter gather list needs to be 128 byte aligned + * @sgl_dma_addr: dma address of sgl + * @sgl_size: size of area used for sgl + * @user_addr: user-space address of memory area + * @user_size: size of user-space memory area + * @page: buffer for partial pages if needed + * @page_dma_addr: dma address partial pages + */ +struct genwqe_sgl { + dma_addr_t sgl_dma_addr; + struct sg_entry *sgl; + size_t sgl_size; /* size of sgl */ + + void __user *user_addr; /* user-space base-address */ + size_t user_size; /* size of memory area */ + + unsigned long nr_pages; + unsigned long fpage_offs; + size_t fpage_size; + size_t lpage_size; + + void *fpage; + dma_addr_t fpage_dma_addr; + + void *lpage; + dma_addr_t lpage_dma_addr; +}; + +int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, + void __user *user_addr, size_t user_size); + +int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, + dma_addr_t *dma_list); + +int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl); + /** * struct ddcb_requ - Kernel internal representation of the DDCB request * @cmd: User space representation of the DDCB execution request @@ -347,9 +385,7 @@ struct ddcb_requ { struct ddcb_queue *queue; /* associated queue */ struct dma_mapping dma_mappings[DDCB_FIXUPS]; - struct sg_entry *sgl[DDCB_FIXUPS]; - dma_addr_t sgl_dma_addr[DDCB_FIXUPS]; - size_t sgl_size[DDCB_FIXUPS]; + struct genwqe_sgl sgls[DDCB_FIXUPS]; /* kernel/user shared content */ struct genwqe_ddcb_cmd cmd; /* ddcb_no for this request */ @@ -453,22 +489,6 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m, struct ddcb_requ *req); -struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages, - dma_addr_t *dma_addr, size_t *sgl_size); - -void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list, - dma_addr_t dma_addr, size_t size); - -int genwqe_setup_sgl(struct genwqe_dev *cd, - unsigned long offs, - unsigned long size, - struct sg_entry *sgl, /* genwqe sgl */ - dma_addr_t dma_addr, size_t sgl_size, - dma_addr_t *dma_list, int page_offs, int num_pages); - -int genwqe_check_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list, - int size); - static inline bool dma_mapping_used(struct dma_mapping *m) { if (!m) diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 0d05ca77c458..1d2f163a1906 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -840,15 +840,8 @@ static int ddcb_cmd_cleanup(struct genwqe_file *cfile, struct ddcb_requ *req) __genwqe_del_mapping(cfile, dma_map); genwqe_user_vunmap(cd, dma_map, req); } - if (req->sgl[i] != NULL) { - genwqe_free_sgl(cd, req->sgl[i], - req->sgl_dma_addr[i], - req->sgl_size[i]); - req->sgl[i] = NULL; - req->sgl_dma_addr[i] = 0x0; - req->sgl_size[i] = 0; - } - + if (req->sgls[i].sgl != NULL) + genwqe_free_sync_sgl(cd, &req->sgls[i]); } return 0; } @@ -917,7 +910,7 @@ static int ddcb_cmd_fixups(struct genwqe_file *cfile, struct ddcb_requ *req) case ATS_TYPE_SGL_RDWR: case ATS_TYPE_SGL_RD: { - int page_offs, nr_pages, offs; + int page_offs; u_addr = be64_to_cpu(*((__be64 *) &cmd->asiv[asiv_offs])); @@ -955,27 +948,18 @@ static int ddcb_cmd_fixups(struct genwqe_file *cfile, struct ddcb_requ *req) page_offs = 0; } - offs = offset_in_page(u_addr); - nr_pages = DIV_ROUND_UP(offs + u_size, PAGE_SIZE); - /* create genwqe style scatter gather list */ - req->sgl[i] = genwqe_alloc_sgl(cd, m->nr_pages, - &req->sgl_dma_addr[i], - &req->sgl_size[i]); - if (req->sgl[i] == NULL) { - rc = -ENOMEM; + rc = genwqe_alloc_sync_sgl(cd, &req->sgls[i], + (void __user *)u_addr, + u_size); + if (rc != 0) goto err_out; - } - genwqe_setup_sgl(cd, offs, u_size, - req->sgl[i], - req->sgl_dma_addr[i], - req->sgl_size[i], - m->dma_list, - page_offs, - nr_pages); + + genwqe_setup_sgl(cd, &req->sgls[i], + &m->dma_list[page_offs]); *((__be64 *)&cmd->asiv[asiv_offs]) = - cpu_to_be64(req->sgl_dma_addr[i]); + cpu_to_be64(req->sgls[i].sgl_dma_addr); break; } diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 6b1a6ef9f1a8..d049d271699c 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -275,67 +275,107 @@ static int genwqe_sgl_size(int num_pages) return roundup(len, PAGE_SIZE); } -struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages, - dma_addr_t *dma_addr, size_t *sgl_size) +/** + * genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages + * + * Allocates memory for sgl and overlapping pages. Pages which might + * overlap other user-space memory blocks are being cached for DMAs, + * such that we do not run into syncronization issues. Data is copied + * from user-space into the cached pages. + */ +int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, + void __user *user_addr, size_t user_size) { + int rc; struct pci_dev *pci_dev = cd->pci_dev; - struct sg_entry *sgl; - *sgl_size = genwqe_sgl_size(num_pages); - if (get_order(*sgl_size) > MAX_ORDER) { + sgl->fpage_offs = offset_in_page((unsigned long)user_addr); + sgl->fpage_size = min_t(size_t, PAGE_SIZE-sgl->fpage_offs, user_size); + sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE); + sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE; + + dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld " + "fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n", + __func__, user_addr, user_size, sgl->nr_pages, + sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size); + + sgl->user_addr = user_addr; + sgl->user_size = user_size; + sgl->sgl_size = genwqe_sgl_size(sgl->nr_pages); + + if (get_order(sgl->sgl_size) > MAX_ORDER) { dev_err(&pci_dev->dev, "[%s] err: too much memory requested!\n", __func__); - return NULL; + return -ENOMEM; } - sgl = __genwqe_alloc_consistent(cd, *sgl_size, dma_addr); - if (sgl == NULL) { + sgl->sgl = __genwqe_alloc_consistent(cd, sgl->sgl_size, + &sgl->sgl_dma_addr); + if (sgl->sgl == NULL) { dev_err(&pci_dev->dev, "[%s] err: no memory available!\n", __func__); - return NULL; + return -ENOMEM; } - return sgl; + /* Only use buffering on incomplete pages */ + if ((sgl->fpage_size != 0) && (sgl->fpage_size != PAGE_SIZE)) { + sgl->fpage = __genwqe_alloc_consistent(cd, PAGE_SIZE, + &sgl->fpage_dma_addr); + if (sgl->fpage == NULL) + goto err_out; + + /* Sync with user memory */ + if (copy_from_user(sgl->fpage + sgl->fpage_offs, + user_addr, sgl->fpage_size)) { + rc = -EFAULT; + goto err_out; + } + } + if (sgl->lpage_size != 0) { + sgl->lpage = __genwqe_alloc_consistent(cd, PAGE_SIZE, + &sgl->lpage_dma_addr); + if (sgl->lpage == NULL) + goto err_out1; + + /* Sync with user memory */ + if (copy_from_user(sgl->lpage, user_addr + user_size - + sgl->lpage_size, sgl->lpage_size)) { + rc = -EFAULT; + goto err_out1; + } + } + return 0; + + err_out1: + __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage, + sgl->fpage_dma_addr); + err_out: + __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl, + sgl->sgl_dma_addr); + return -ENOMEM; } -int genwqe_setup_sgl(struct genwqe_dev *cd, - unsigned long offs, - unsigned long size, - struct sg_entry *sgl, - dma_addr_t dma_addr, size_t sgl_size, - dma_addr_t *dma_list, int page_offs, int num_pages) +int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl, + dma_addr_t *dma_list) { int i = 0, j = 0, p; unsigned long dma_offs, map_offs; - struct pci_dev *pci_dev = cd->pci_dev; dma_addr_t prev_daddr = 0; struct sg_entry *s, *last_s = NULL; - - /* sanity checks */ - if (offs > PAGE_SIZE) { - dev_err(&pci_dev->dev, - "[%s] too large start offs %08lx\n", __func__, offs); - return -EFAULT; - } - if (sgl_size < genwqe_sgl_size(num_pages)) { - dev_err(&pci_dev->dev, - "[%s] sgl_size too small %08lx for %d pages\n", - __func__, sgl_size, num_pages); - return -EFAULT; - } + size_t size = sgl->user_size; dma_offs = 128; /* next block if needed/dma_offset */ - map_offs = offs; /* offset in first page */ + map_offs = sgl->fpage_offs; /* offset in first page */ - s = &sgl[0]; /* first set of 8 entries */ + s = &sgl->sgl[0]; /* first set of 8 entries */ p = 0; /* page */ - while (p < num_pages) { + while (p < sgl->nr_pages) { dma_addr_t daddr; unsigned int size_to_map; /* always write the chaining entry, cleanup is done later */ j = 0; - s[j].target_addr = cpu_to_be64(dma_addr + dma_offs); + s[j].target_addr = cpu_to_be64(sgl->sgl_dma_addr + dma_offs); s[j].len = cpu_to_be32(128); s[j].flags = cpu_to_be32(SG_CHAINED); j++; @@ -343,7 +383,17 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, while (j < 8) { /* DMA mapping for requested page, offs, size */ size_to_map = min(size, PAGE_SIZE - map_offs); - daddr = dma_list[page_offs + p] + map_offs; + + if ((p == 0) && (sgl->fpage != NULL)) { + daddr = sgl->fpage_dma_addr + map_offs; + + } else if ((p == sgl->nr_pages - 1) && + (sgl->lpage != NULL)) { + daddr = sgl->lpage_dma_addr; + } else { + daddr = dma_list[p] + map_offs; + } + size -= size_to_map; map_offs = 0; @@ -358,7 +408,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, size_to_map); p++; /* process next page */ - if (p == num_pages) + if (p == sgl->nr_pages) goto fixup; /* nothing to do */ prev_daddr = daddr + size_to_map; @@ -374,7 +424,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, j++; p++; /* process next page */ - if (p == num_pages) + if (p == sgl->nr_pages) goto fixup; /* nothing to do */ } dma_offs += 128; @@ -395,10 +445,50 @@ int genwqe_setup_sgl(struct genwqe_dev *cd, return 0; } -void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list, - dma_addr_t dma_addr, size_t size) +/** + * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages + * + * After the DMA transfer has been completed we free the memory for + * the sgl and the cached pages. Data is being transfered from cached + * pages into user-space buffers. + */ +int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl) { - __genwqe_free_consistent(cd, size, sg_list, dma_addr); + int rc; + struct pci_dev *pci_dev = cd->pci_dev; + + if (sgl->fpage) { + if (copy_to_user(sgl->user_addr, sgl->fpage + sgl->fpage_offs, + sgl->fpage_size)) { + dev_err(&pci_dev->dev, "[%s] err: copying fpage!\n", + __func__); + rc = -EFAULT; + } + __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage, + sgl->fpage_dma_addr); + sgl->fpage = NULL; + sgl->fpage_dma_addr = 0; + } + if (sgl->lpage) { + if (copy_to_user(sgl->user_addr + sgl->user_size - + sgl->lpage_size, sgl->lpage, + sgl->lpage_size)) { + dev_err(&pci_dev->dev, "[%s] err: copying lpage!\n", + __func__); + rc = -EFAULT; + } + __genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage, + sgl->lpage_dma_addr); + sgl->lpage = NULL; + sgl->lpage_dma_addr = 0; + } + __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl, + sgl->sgl_dma_addr); + + sgl->sgl = NULL; + sgl->sgl_dma_addr = 0x0; + sgl->sgl_size = 0; + return rc; } /** -- GitLab From 73590a25ba6f55eecde4ffbbbc53835d7ccf5402 Mon Sep 17 00:00:00 2001 From: Frank Haverkamp Date: Thu, 20 Mar 2014 15:11:06 +0100 Subject: [PATCH 364/797] GenWQE: Increase driver version number Increase genwqe driver version number. Signed-off-by: Frank Haverkamp Signed-off-by: Greg Kroah-Hartman --- drivers/misc/genwqe/genwqe_driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h index 46e916b36c70..cd5263163a6e 100644 --- a/drivers/misc/genwqe/genwqe_driver.h +++ b/drivers/misc/genwqe/genwqe_driver.h @@ -36,7 +36,7 @@ #include #include -#define DRV_VERS_STRING "2.0.0" +#define DRV_VERS_STRING "2.0.15" /* * Static minor number assignement, until we decide/implement -- GitLab From b7c0ddf5f270b2a3c0af326cb300eb17175d58e3 Mon Sep 17 00:00:00 2001 From: Jan Glauber Date: Wed, 16 Apr 2014 09:32:48 +0200 Subject: [PATCH 365/797] net: use SYSCALL_DEFINEx for sys_recv Make sys_recv a first class citizen by using the SYSCALL_DEFINEx macro. Besides being cleaner this will also generate meta data for the system call so tracing tools like ftrace or LTTng can resolve this system call. Signed-off-by: Jan Glauber Signed-off-by: David S. Miller --- net/socket.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/socket.c b/net/socket.c index 1b1e7e6a960f..abf56b2a14f9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1880,8 +1880,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, * Receive a datagram from a socket. */ -asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size, - unsigned int flags) +SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size, + unsigned int, flags) { return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); } -- GitLab From 8c923ce219b775cc659a31616590afee239a84e5 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Wed, 16 Apr 2014 11:19:32 +0200 Subject: [PATCH 366/797] ip_tunnel: use the right netns in ioctl handler Because the netdevice may be in another netns than the i/o netns, we should use the i/o netns instead of dev_net(dev). The variable 'tunnel' was used only to get 'itn', hence to simplify code I remove it and use 't' instead. Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/ipv4/ip_tunnel.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 484d0ce27ef7..fa5b7519765f 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -722,19 +722,18 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn, int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) { int err = 0; - struct ip_tunnel *t; - struct net *net = dev_net(dev); - struct ip_tunnel *tunnel = netdev_priv(dev); - struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id); + struct ip_tunnel *t = netdev_priv(dev); + struct net *net = t->net; + struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id); BUG_ON(!itn->fb_tunnel_dev); switch (cmd) { case SIOCGETTUNNEL: - t = NULL; - if (dev == itn->fb_tunnel_dev) + if (dev == itn->fb_tunnel_dev) { t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); - if (t == NULL) - t = netdev_priv(dev); + if (t == NULL) + t = netdev_priv(dev); + } memcpy(p, &t->parms, sizeof(*p)); break; -- GitLab From 9aad77c3b5cc9151d356b66ee8533e85ca7da192 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Wed, 16 Apr 2014 11:19:33 +0200 Subject: [PATCH 367/797] sit: use the right netns in ioctl handler Because the netdevice may be in another netns than the i/o netns, we should use the i/o netns instead of dev_net(dev). Note that netdev_priv(dev) cannot bu NULL, hence we can remove these useless checks. Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/ipv6/sit.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 8da8268d65f8..e5a453ca302e 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1127,8 +1127,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) int err = 0; struct ip_tunnel_parm p; struct ip_tunnel_prl prl; - struct ip_tunnel *t; - struct net *net = dev_net(dev); + struct ip_tunnel *t = netdev_priv(dev); + struct net *net = t->net; struct sit_net *sitn = net_generic(net, sit_net_id); #ifdef CONFIG_IPV6_SIT_6RD struct ip_tunnel_6rd ip6rd; @@ -1139,16 +1139,15 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) #ifdef CONFIG_IPV6_SIT_6RD case SIOCGET6RD: #endif - t = NULL; if (dev == sitn->fb_tunnel_dev) { if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { err = -EFAULT; break; } t = ipip6_tunnel_locate(net, &p, 0); + if (t == NULL) + t = netdev_priv(dev); } - if (t == NULL) - t = netdev_priv(dev); err = -EFAULT; if (cmd == SIOCGETTUNNEL) { @@ -1244,9 +1243,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = -EINVAL; if (dev == sitn->fb_tunnel_dev) goto done; - err = -ENOENT; - if (!(t = netdev_priv(dev))) - goto done; err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); break; @@ -1262,9 +1258,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = -EFAULT; if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) goto done; - err = -ENOENT; - if (!(t = netdev_priv(dev))) - goto done; switch (cmd) { case SIOCDELPRL: @@ -1292,8 +1285,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) sizeof(ip6rd))) goto done; - t = netdev_priv(dev); - if (cmd != SIOCDEL6RD) { err = ipip6_tunnel_update_6rd(t, &ip6rd); if (err < 0) -- GitLab From 74462f0d4a734274a04dbbe58099134cbe7a5522 Mon Sep 17 00:00:00 2001 From: Nicolas Dichtel Date: Wed, 16 Apr 2014 11:19:34 +0200 Subject: [PATCH 368/797] ip6_tunnel: use the right netns in ioctl handler Because the netdevice may be in another netns than the i/o netns, we should use the i/o netns instead of dev_net(dev). Signed-off-by: Nicolas Dichtel Signed-off-by: David S. Miller --- net/ipv6/ip6_tunnel.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index e1df691d78be..b05b609f69d1 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1340,8 +1340,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) int err = 0; struct ip6_tnl_parm p; struct __ip6_tnl_parm p1; - struct ip6_tnl *t = NULL; - struct net *net = dev_net(dev); + struct ip6_tnl *t = netdev_priv(dev); + struct net *net = t->net; struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); switch (cmd) { @@ -1353,11 +1353,11 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) } ip6_tnl_parm_from_user(&p1, &p); t = ip6_tnl_locate(net, &p1, 0); + if (t == NULL) + t = netdev_priv(dev); } else { memset(&p, 0, sizeof(p)); } - if (t == NULL) - t = netdev_priv(dev); ip6_tnl_parm_to_user(&p, &t->parms); if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { err = -EFAULT; -- GitLab From b7a314054eb55e3745a9409beaa5d8be5cd2d273 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 16 Apr 2014 14:25:16 +0300 Subject: [PATCH 369/797] isdn: icn: buffer overflow in icn_command() This buffer over was detected using static analysis: drivers/isdn/icn/icn.c:1325 icn_command() error: format string overflow. buf_size: 60 length: 98 The calculation for the length of the string is off because it assumes that the dial[] buffer holds a 50 character string, but actually it is at most 31 characters and NUL. I have removed the dial[] buffer because it isn't needed. The maximum length of the string is actually 79 characters and a NUL. I have made the cbuf[] array large enough to hold it and changed the sprintf() to an snprintf() as a further safety enhancement. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/icn/icn.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 53d487f0c79d..6a7447c304ac 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c @@ -1155,7 +1155,7 @@ icn_command(isdn_ctrl *c, icn_card *card) ulong a; ulong flags; int i; - char cbuf[60]; + char cbuf[80]; isdn_ctrl cmd; icn_cdef cdef; char __user *arg; @@ -1309,7 +1309,6 @@ icn_command(isdn_ctrl *c, icn_card *card) break; if ((c->arg & 255) < ICN_BCH) { char *p; - char dial[50]; char dcode[4]; a = c->arg; @@ -1321,10 +1320,10 @@ icn_command(isdn_ctrl *c, icn_card *card) } else /* Normal Dial */ strcpy(dcode, "CAL"); - strcpy(dial, p); - sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), - dcode, dial, c->parm.setup.si1, - c->parm.setup.si2, c->parm.setup.eazmsn); + snprintf(cbuf, sizeof(cbuf), + "%02d;D%s_R%s,%02d,%02d,%s\n", (int) (a + 1), + dcode, p, c->parm.setup.si1, + c->parm.setup.si2, c->parm.setup.eazmsn); i = icn_writecmd(cbuf, strlen(cbuf), 0, card); } break; -- GitLab From 5e6533a6f52f1a8283b2f818f5828be99a417dd6 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Tue, 25 Mar 2014 21:25:18 +0200 Subject: [PATCH 370/797] mei: me: do not load the driver if the FW doesn't support MEI interface NM and SPS FW types that may run on ME device on server platforms do not have valid MEI/HECI interface and driver should not be bound to it as this might lead to system hung. In practice not all BIOSes effectively hide such devices from the OS and in some cases it is not possible. We determine FW type by examining Host FW status registers in order to unbind the driver. In this patch we are adding check for ME on Cougar Point, Lynx Point Devices Cc: stable # 3.10+ Signed-off-by: Tomas Winkler Tested-by: Nikola Ciprich Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me-regs.h | 5 +++++ drivers/misc/mei/pci-me.c | 30 +++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index 66f411a6e8ea..cabc04383685 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -115,6 +115,11 @@ #define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */ #define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */ + +/* Host Firmware Status Registers in PCI Config Space */ +#define PCI_CFG_HFS_1 0x40 +#define PCI_CFG_HFS_2 0x48 + /* * MEI HW Section */ diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 1c8fd3a3e135..95889e2e31ff 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -97,15 +97,31 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { u32 reg; - if (ent->device == MEI_DEV_ID_PBG_1) { - pci_read_config_dword(pdev, 0x48, ®); - /* make sure that bit 9 is up and bit 10 is down */ - if ((reg & 0x600) == 0x200) { - dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); - return false; - } + /* Cougar Point || Patsburg */ + if (ent->device == MEI_DEV_ID_CPT_1 || + ent->device == MEI_DEV_ID_PBG_1) { + pci_read_config_dword(pdev, PCI_CFG_HFS_2, ®); + /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */ + if ((reg & 0x600) == 0x200) + goto no_mei; } + + /* Lynx Point */ + if (ent->device == MEI_DEV_ID_LPT_H || + ent->device == MEI_DEV_ID_LPT_W || + ent->device == MEI_DEV_ID_LPT_HR) { + /* Read ME FW Status check for SPS Firmware */ + pci_read_config_dword(pdev, PCI_CFG_HFS_1, ®); + /* if bits [19:16] = 15, running SPS Firmware */ + if ((reg & 0xf0000) == 0xf0000) + goto no_mei; + } + return true; + +no_mei: + dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); + return false; } /** * mei_probe - Device Initialization Routine -- GitLab From 34ec43661fe8f1977dd0f05353302ae2ed10aabb Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 1 Apr 2014 23:50:41 +0300 Subject: [PATCH 371/797] mei: ignore client writing state during cb completion Ignore client writing state during cb completion to fix a memory leak. When moving cbs to the completion list we should not look at writing_state as this state can be already overwritten by next write, the fact that a cb is on the write waiting list means that it was already written to the HW and we can safely complete it. Same pays for wait in poll handler, we do not have to check the state wake is done after completion list processing. Cc: stable@vger.kernel.org Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/interrupt.c | 3 +-- drivers/misc/mei/main.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 29b5af8efb71..4e3cba6da3f5 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -455,8 +455,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list) cl->status = 0; list_del(&cb->list); - if (MEI_WRITING == cl->writing_state && - cb->fop_type == MEI_FOP_WRITE && + if (cb->fop_type == MEI_FOP_WRITE && cl != &dev->iamthif_cl) { cl_dbg(dev, cl, "MEI WRITE COMPLETE\n"); cl->writing_state = MEI_WRITE_COMPLETE; diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index b35594dbf52f..147413145c97 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c @@ -644,8 +644,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait) goto out; } - if (MEI_WRITE_COMPLETE == cl->writing_state) - mask |= (POLLIN | POLLRDNORM); + mask |= (POLLIN | POLLRDNORM); out: mutex_unlock(&dev->device_lock); -- GitLab From 0acf07d240a84069c4a6651e6030cf35d30c7159 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 16 Apr 2014 10:54:34 -0700 Subject: [PATCH 372/797] seccomp: fix memory leak on filter attach This sets the correct error code when final filter memory is unavailable, and frees the raw filter no matter what. unreferenced object 0xffff8800d6ea4000 (size 512): comm "sshd", pid 278, jiffies 4294898315 (age 46.653s) hex dump (first 32 bytes): 21 00 00 00 04 00 00 00 15 00 01 00 3e 00 00 c0 !...........>... 06 00 00 00 00 00 00 00 21 00 00 00 00 00 00 00 ........!....... backtrace: [] kmemleak_alloc+0x4e/0xb0 [] __kmalloc+0x280/0x320 [] prctl_set_seccomp+0x11e/0x3b0 [] SyS_prctl+0x3bb/0x4a0 [] system_call_fastpath+0x1a/0x1f [] 0xffffffffffffffff Reported-by: Masami Ichikawa Signed-off-by: Kees Cook Tested-by: Masami Ichikawa Acked-by: Daniel Borkmann Signed-off-by: David S. Miller --- kernel/seccomp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 590c37925084..b35c21503a36 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -255,6 +255,7 @@ static long seccomp_attach_filter(struct sock_fprog *fprog) goto free_prog; /* Allocate a new seccomp_filter */ + ret = -ENOMEM; filter = kzalloc(sizeof(struct seccomp_filter) + sizeof(struct sock_filter_int) * new_len, GFP_KERNEL|__GFP_NOWARN); @@ -264,6 +265,7 @@ static long seccomp_attach_filter(struct sock_fprog *fprog) ret = sk_convert_filter(fp, fprog->len, filter->insnsi, &new_len); if (ret) goto free_filter; + kfree(fp); atomic_set(&filter->usage, 1); filter->len = new_len; -- GitLab From 7c7352827343b377446bb59b844d387df665e401 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Fri, 11 Apr 2014 18:40:05 +0200 Subject: [PATCH 373/797] drivers: mcb: fix memory leak in chameleon_parse_cells() error path chameleon_parse_cells() bails out if chameleon descriptor type is invalid but does not free the storage 'header' points to. Signed-off-by: Christoph Jaeger Signed-off-by: Johannes Thumshirn Signed-off-by: Greg Kroah-Hartman --- drivers/mcb/mcb-parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c index d1278b5f3028..004926955263 100644 --- a/drivers/mcb/mcb-parse.c +++ b/drivers/mcb/mcb-parse.c @@ -141,6 +141,7 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase, default: pr_err("Invalid chameleon descriptor type 0x%x\n", dtype); + kfree(header); return -EINVAL; } num_cells++; -- GitLab From a82cb8b91a37b6015f171a90dc4670e4c8e12e12 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 14 Apr 2014 18:55:49 +0200 Subject: [PATCH 374/797] misc: Grammar s/addition/additional/ Signed-off-by: Geert Uytterhoeven Cc: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1cb74085e410..8baff0effc7d 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -300,8 +300,8 @@ config SGI_GRU_DEBUG depends on SGI_GRU default n ---help--- - This option enables addition debugging code for the SGI GRU driver. If - you are unsure, say N. + This option enables additional debugging code for the SGI GRU driver. + If you are unsure, say N. config APDS9802ALS tristate "Medfield Avago APDS9802 ALS Sensor module" -- GitLab From f764cd68d9036498f08fe8834deb6a367b5c2542 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 16 Apr 2014 14:49:33 -0500 Subject: [PATCH 375/797] staging: r8712u: Fix case where ethtype was never obtained and always be checked against 0 Zero-initializing ether_type masked that the ether type would never be obtained for 8021x packets and the comparison against eapol_type would always fail. Reported-by: Jes Sorensen Signed-off-by: Larry Finger Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_recv.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c index 23ec684b60e1..274c359279ef 100644 --- a/drivers/staging/rtl8712/rtl871x_recv.c +++ b/drivers/staging/rtl8712/rtl871x_recv.c @@ -254,7 +254,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, struct sta_info *psta; struct sta_priv *pstapriv; union recv_frame *prtnframe; - u16 ether_type = 0; + u16 ether_type; pstapriv = &adapter->stapriv; ptr = get_recvframe_data(precv_frame); @@ -263,15 +263,14 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter, psta = r8712_get_stainfo(pstapriv, psta_addr); auth_alg = adapter->securitypriv.AuthAlgrthm; if (auth_alg == 2) { + /* get ether_type */ + ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; + memcpy(ðer_type, ptr, 2); + ether_type = ntohs((unsigned short)ether_type); + if ((psta != NULL) && (psta->ieee8021x_blocked)) { /* blocked * only accept EAPOL frame */ - prtnframe = precv_frame; - /*get ether_type */ - ptr = ptr + pfhdr->attrib.hdrlen + - pfhdr->attrib.iv_len + LLC_HEADER_SIZE; - memcpy(ðer_type, ptr, 2); - ether_type = ntohs((unsigned short)ether_type); if (ether_type == 0x888e) prtnframe = precv_frame; else { -- GitLab From 33c84bc14c25074ac14644cf7db75a57e9abaf1a Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 16 Apr 2014 14:49:34 -0500 Subject: [PATCH 376/797] staging: r8188eu: Fix case where ethtype was never obtained and always be checked against 0 Zero-initializing ether_type masked that the ether type would never be obtained for 8021x packets and the comparison against eapol_type would always fail. Reported-by: Jes Sorensen Signed-off-by: Larry Finger Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_recv.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c index 01fcabcc8e56..e305d43ebd06 100644 --- a/drivers/staging/rtl8188eu/core/rtw_recv.c +++ b/drivers/staging/rtl8188eu/core/rtw_recv.c @@ -551,10 +551,9 @@ static struct recv_frame *portctrl(struct adapter *adapter, struct sta_info *psta; struct sta_priv *pstapriv; struct recv_frame *prtnframe; - u16 ether_type = 0; + u16 ether_type; u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */ struct rx_pkt_attrib *pattrib; - __be16 be_tmp; pstapriv = &adapter->stapriv; @@ -572,18 +571,16 @@ static struct recv_frame *portctrl(struct adapter *adapter, RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm)); if (auth_alg == 2) { + /* get ether_type */ + ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; + memcpy(ðer_type, ptr, 2); + ether_type = ntohs((unsigned short)ether_type); + if ((psta != NULL) && (psta->ieee8021x_blocked)) { /* blocked */ /* only accept EAPOL frame */ RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n")); - prtnframe = precv_frame; - - /* get ether_type */ - ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE; - memcpy(&be_tmp, ptr, 2); - ether_type = ntohs(be_tmp); - if (ether_type == eapol_type) { prtnframe = precv_frame; } else { -- GitLab From efe26e16b1d93ac0085e69178cc18811629e8fc5 Mon Sep 17 00:00:00 2001 From: Michele Baldessari Date: Mon, 31 Mar 2014 10:51:00 +0200 Subject: [PATCH 377/797] USB: serial: ftdi_sio: add id for Brainboxes serial cards Custom VID/PIDs for Brainboxes cards as reported in https://bugzilla.redhat.com/show_bug.cgi?id=1071914 Signed-off-by: Michele Baldessari Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 33 +++++++++++++++++++++++++++ drivers/usb/serial/ftdi_sio_ids.h | 37 +++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 44ab12986805..7c6e1dedeb06 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -909,6 +909,39 @@ static const struct usb_device_id id_table_combined[] = { { USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) }, /* Cressi Devices */ { USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) }, + /* Brainboxes Devices */ + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) }, + { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) }, { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index e599fbfcde5f..993c93df6874 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -1326,3 +1326,40 @@ * Manufacturer: Cressi */ #define FTDI_CRESSI_PID 0x87d0 + +/* + * Brainboxes devices + */ +#define BRAINBOXES_VID 0x05d1 +#define BRAINBOXES_VX_001_PID 0x1001 /* VX-001 ExpressCard 1 Port RS232 */ +#define BRAINBOXES_VX_012_PID 0x1002 /* VX-012 ExpressCard 2 Port RS232 */ +#define BRAINBOXES_VX_023_PID 0x1003 /* VX-023 ExpressCard 1 Port RS422/485 */ +#define BRAINBOXES_VX_034_PID 0x1004 /* VX-034 ExpressCard 2 Port RS422/485 */ +#define BRAINBOXES_US_101_PID 0x1011 /* US-101 1xRS232 */ +#define BRAINBOXES_US_324_PID 0x1013 /* US-324 1xRS422/485 1Mbaud */ +#define BRAINBOXES_US_606_1_PID 0x2001 /* US-606 6 Port RS232 Serial Port 1 and 2 */ +#define BRAINBOXES_US_606_2_PID 0x2002 /* US-606 6 Port RS232 Serial Port 3 and 4 */ +#define BRAINBOXES_US_606_3_PID 0x2003 /* US-606 6 Port RS232 Serial Port 4 and 6 */ +#define BRAINBOXES_US_701_1_PID 0x2011 /* US-701 4xRS232 1Mbaud Port 1 and 2 */ +#define BRAINBOXES_US_701_2_PID 0x2012 /* US-701 4xRS422 1Mbaud Port 3 and 4 */ +#define BRAINBOXES_US_279_1_PID 0x2021 /* US-279 8xRS422 1Mbaud Port 1 and 2 */ +#define BRAINBOXES_US_279_2_PID 0x2022 /* US-279 8xRS422 1Mbaud Port 3 and 4 */ +#define BRAINBOXES_US_279_3_PID 0x2023 /* US-279 8xRS422 1Mbaud Port 5 and 6 */ +#define BRAINBOXES_US_279_4_PID 0x2024 /* US-279 8xRS422 1Mbaud Port 7 and 8 */ +#define BRAINBOXES_US_346_1_PID 0x3011 /* US-346 4xRS422/485 1Mbaud Port 1 and 2 */ +#define BRAINBOXES_US_346_2_PID 0x3012 /* US-346 4xRS422/485 1Mbaud Port 3 and 4 */ +#define BRAINBOXES_US_257_PID 0x5001 /* US-257 2xRS232 1Mbaud */ +#define BRAINBOXES_US_313_PID 0x6001 /* US-313 2xRS422/485 1Mbaud */ +#define BRAINBOXES_US_357_PID 0x7001 /* US_357 1xRS232/422/485 */ +#define BRAINBOXES_US_842_1_PID 0x8001 /* US-842 8xRS422/485 1Mbaud Port 1 and 2 */ +#define BRAINBOXES_US_842_2_PID 0x8002 /* US-842 8xRS422/485 1Mbaud Port 3 and 4 */ +#define BRAINBOXES_US_842_3_PID 0x8003 /* US-842 8xRS422/485 1Mbaud Port 5 and 6 */ +#define BRAINBOXES_US_842_4_PID 0x8004 /* US-842 8xRS422/485 1Mbaud Port 7 and 8 */ +#define BRAINBOXES_US_160_1_PID 0x9001 /* US-160 16xRS232 1Mbaud Port 1 and 2 */ +#define BRAINBOXES_US_160_2_PID 0x9002 /* US-160 16xRS232 1Mbaud Port 3 and 4 */ +#define BRAINBOXES_US_160_3_PID 0x9003 /* US-160 16xRS232 1Mbaud Port 5 and 6 */ +#define BRAINBOXES_US_160_4_PID 0x9004 /* US-160 16xRS232 1Mbaud Port 7 and 8 */ +#define BRAINBOXES_US_160_5_PID 0x9005 /* US-160 16xRS232 1Mbaud Port 9 and 10 */ +#define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */ +#define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */ +#define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */ -- GitLab From 2e01280d2801c72878cf3a7119eac30077b463d5 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 28 Mar 2014 18:05:10 +0100 Subject: [PATCH 378/797] Revert "USB: serial: add usbid for dell wwan card to sierra.c" This reverts commit 1ebca9dad5abe8b2ed4dbd186cd657fb47c1f321. This device was erroneously added to the sierra driver even though it's not a Sierra device and was already handled by the option driver. Cc: Richard Farina Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index a9eb6221a815..6b192e602ce0 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -291,7 +291,6 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */ .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist }, - { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */ { } }; -- GitLab From d6de486bc22255779bd54b0fceb4c240962bf146 Mon Sep 17 00:00:00 2001 From: Daniele Palmas Date: Wed, 2 Apr 2014 11:19:48 +0200 Subject: [PATCH 379/797] usb: option driver, add support for Telit UE910v2 option driver, added VID/PID for Telit UE910v2 modem Signed-off-by: Daniele Palmas Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 68fc9fe65936..367c7f08b27c 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -243,6 +243,7 @@ static void option_instat_callback(struct urb *urb); #define TELIT_PRODUCT_CC864_DUAL 0x1005 #define TELIT_PRODUCT_CC864_SINGLE 0x1006 #define TELIT_PRODUCT_DE910_DUAL 0x1010 +#define TELIT_PRODUCT_UE910_V2 0x1012 #define TELIT_PRODUCT_LE920 0x1200 /* ZTE PRODUCTS */ @@ -1041,6 +1042,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ -- GitLab From 72b3007951010ce1bbf950e23b19d9839fa905a5 Mon Sep 17 00:00:00 2001 From: Tristan Bruns Date: Sun, 13 Apr 2014 23:57:16 +0200 Subject: [PATCH 380/797] USB: cp210x: Add 8281 (Nanotec Plug & Drive) Signed-off-by: Tristan Bruns Cc: stable Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- 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 95fa1217afdd..762e4a5f5ae9 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -104,6 +104,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */ + { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */ { USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */ { USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ -- GitLab From b16c02fbfb963fa2941b7517ebf1f8a21946775e Mon Sep 17 00:00:00 2001 From: Aaron Sanders Date: Mon, 31 Mar 2014 15:54:21 +0200 Subject: [PATCH 381/797] USB: pl2303: add ids for Hewlett-Packard HP POS pole displays Add device ids to pl2303 for the Hewlett-Packard HP POS pole displays: LD960: 03f0:0B39 LCM220: 03f0:3139 LCM960: 03f0:3239 [ Johan: fix indentation and sort PIDs numerically ] Signed-off-by: Aaron Sanders Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/pl2303.c | 3 +++ drivers/usb/serial/pl2303.h | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 2e22fc22c382..b3d5a35c0d4b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -83,6 +83,9 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) }, { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) }, + { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) }, { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index c38b8c00c06f..42bc082896ac 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h @@ -121,8 +121,11 @@ #define SUPERIAL_VENDOR_ID 0x5372 #define SUPERIAL_PRODUCT_ID 0x2303 -/* Hewlett-Packard LD220-HP POS Pole Display */ +/* Hewlett-Packard POS Pole Displays */ #define HP_VENDOR_ID 0x03f0 +#define HP_LD960_PRODUCT_ID 0x0b39 +#define HP_LCM220_PRODUCT_ID 0x3139 +#define HP_LCM960_PRODUCT_ID 0x3239 #define HP_LD220_PRODUCT_ID 0x3524 /* Cressi Edy (diving computer) PC interface */ -- GitLab From bd73bd8831696f189a479a0712ae95208e513d7e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 3 Apr 2014 13:06:46 +0200 Subject: [PATCH 382/797] USB: usb_wwan: fix handling of missing bulk endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix regression introduced by commit 8e493ca1767d ("USB: usb_wwan: fix bulk-urb allocation") by making sure to require both bulk-in and out endpoints during port probe. The original option driver (which usb_wwan is based on) was written under the assumption that either endpoint could be missing, but evidently this cannot have been tested properly. Specifically, it would handle opening a device without bulk-in (but would blow up during resume which was implemented later), but not a missing bulk-out in write() (although it is handled in some places such as write_room()). Fortunately (?), the driver also got the test for missing endpoints wrong so the urbs were in fact always allocated, although they would be initialised using the wrong endpoint address (0) and any submission of such an urb would fail. The commit mentioned above fixed the test for missing endpoints but thereby exposed the other bugs which would now generate null-pointer exceptions rather than failed urb submissions. The regression was introduced in v3.7, but the offending commit was also marked for stable. Reported-by: Rafał Miłecki Cc: stable Signed-off-by: Johan Hovold Tested-by: Rafał Miłecki Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb_wwan.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 640fe0173236..b078440e822f 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -466,6 +466,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port) int err; int i; + if (!port->bulk_in_size || !port->bulk_out_size) + return -ENODEV; + portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); if (!portdata) return -ENOMEM; @@ -473,9 +476,6 @@ int usb_wwan_port_probe(struct usb_serial_port *port) init_usb_anchor(&portdata->delayed); for (i = 0; i < N_IN_URB; i++) { - if (!port->bulk_in_size) - break; - buffer = (u8 *)__get_free_page(GFP_KERNEL); if (!buffer) goto bail_out_error; @@ -489,9 +489,6 @@ int usb_wwan_port_probe(struct usb_serial_port *port) } for (i = 0; i < N_OUT_URB; i++) { - if (!port->bulk_out_size) - break; - buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); if (!buffer) goto bail_out_error2; -- GitLab From f9076e28013e448ba2a905ae905ac9b53f8a2e16 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Wed, 9 Apr 2014 14:48:58 +0800 Subject: [PATCH 383/797] usb: usb-common: fix typo for usb_state_string %s/addresssed/addressed Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/usb-common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c index d771870a819e..6dfd30a863c7 100644 --- a/drivers/usb/usb-common.c +++ b/drivers/usb/usb-common.c @@ -69,7 +69,7 @@ const char *usb_state_string(enum usb_device_state state) [USB_STATE_RECONNECTING] = "reconnecting", [USB_STATE_UNAUTHENTICATED] = "unauthenticated", [USB_STATE_DEFAULT] = "default", - [USB_STATE_ADDRESS] = "addresssed", + [USB_STATE_ADDRESS] = "addressed", [USB_STATE_CONFIGURED] = "configured", [USB_STATE_SUSPENDED] = "suspended", }; -- GitLab From 070c0b17f6a1ba39dff9be112218127e7e8fd456 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 12 Apr 2014 02:10:45 +0400 Subject: [PATCH 384/797] USB: cdc-acm: fix double usb_autopm_put_interface() in acm_port_activate() If acm_submit_read_urbs() fails in acm_port_activate(), error handling code calls usb_autopm_put_interface() while it is already called before acm_submit_read_urbs(). The patch reorganizes error handling code to avoid double decrement of USB interface's PM-usage counter. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 900f7ff805ee..d5d2c922186a 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -518,13 +518,16 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) { dev_err(&acm->control->dev, "%s - usb_submit_urb(ctrl irq) failed\n", __func__); + usb_autopm_put_interface(acm->control); goto error_submit_urb; } acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS; if (acm_set_control(acm, acm->ctrlout) < 0 && - (acm->ctrl_caps & USB_CDC_CAP_LINE)) + (acm->ctrl_caps & USB_CDC_CAP_LINE)) { + usb_autopm_put_interface(acm->control); goto error_set_control; + } usb_autopm_put_interface(acm->control); @@ -549,7 +552,6 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty) error_set_control: usb_kill_urb(acm->ctrlurb); error_submit_urb: - usb_autopm_put_interface(acm->control); error_get_interface: disconnected: mutex_unlock(&acm->mutex); -- GitLab From a2ff864b53eac9a0e9b05bfe9d1781ccd6c2af71 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 14 Apr 2014 13:48:47 -0400 Subject: [PATCH 385/797] USB: fix crash during hotplug of PCI USB controller card The code in hcd-pci.c that matches up EHCI controllers with their companion UHCI or OHCI controllers assumes that the private drvdata fields don't get set too early. However, it turns out that this field gets set by usb_create_hcd(), before hcd-pci expects it, and this can result in a crash when two controllers are probed in parallel (as can happen when a new controller card is hotplugged). The companions_rwsem lock was supposed to prevent this sort of thing, but usb_create_hcd() is called outside the scope of the rwsem. A simple solution is to check that the root-hub pointer has been initialized as well as the drvdata field. This doesn't happen until usb_add_hcd() is called; that call and the check are both protected by the rwsem. This patch should be applied to stable kernels from 3.10 onward. Signed-off-by: Alan Stern Reported-by: Stefani Seibold Tested-by: Stefani Seibold CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index d59d99347d54..1f02e65fe305 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -75,7 +75,7 @@ static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd, PCI_SLOT(companion->devfn) != slot) continue; companion_hcd = pci_get_drvdata(companion); - if (!companion_hcd) + if (!companion_hcd || !companion_hcd->self.root_hub) continue; fn(pdev, hcd, companion, companion_hcd); } -- GitLab From d72175103f25783b0504f864a4f381621a789ca2 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 10 Apr 2014 15:58:01 +0530 Subject: [PATCH 386/797] usb: ehci-exynos: Return immediately from suspend if ehci_suspend fails Patch 'b8efdaf USB: EHCI: add check for wakeup/suspend race' adds a check for possible race between suspend and wakeup interrupt, and thereby it returns -EBUSY as error code if there's a wakeup interrupt. So the platform host controller should not proceed further with its suspend callback, rather should return immediately to avoid powering down the essential things, like phy. Signed-off-by: Vivek Gautam Acked-by: Jingoo Han Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-exynos.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c index d1d8c47777c5..7f425acd9be5 100644 --- a/drivers/usb/host/ehci-exynos.c +++ b/drivers/usb/host/ehci-exynos.c @@ -212,6 +212,8 @@ static int exynos_ehci_suspend(struct device *dev) int rc; rc = ehci_suspend(hcd, do_wakeup); + if (rc) + return rc; if (exynos_ehci->otg) exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self); -- GitLab From e155b5b8d2d42455d3a94c2460c287e97184ec61 Mon Sep 17 00:00:00 2001 From: Vivek Gautam Date: Thu, 10 Apr 2014 15:58:02 +0530 Subject: [PATCH 387/797] usb: ehci-platform: Return immediately from suspend if ehci_suspend fails Patch 'b8efdaf USB: EHCI: add check for wakeup/suspend race' adds a check for possible race between suspend and wakeup interrupt, and thereby it returns -EBUSY as error code if there's a wakeup interrupt. So the platform host controller should not proceed further with its suspend callback, rather should return immediately to avoid powering down the essential things, like phy. Signed-off-by: Vivek Gautam Acked-by: Alan Stern Cc: Hauke Mehrtens Cc: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-platform.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c index b3a0e11073aa..c7dd93aad20c 100644 --- a/drivers/usb/host/ehci-platform.c +++ b/drivers/usb/host/ehci-platform.c @@ -303,6 +303,8 @@ static int ehci_platform_suspend(struct device *dev) int ret; ret = ehci_suspend(hcd, do_wakeup); + if (ret) + return ret; if (pdata->power_suspend) pdata->power_suspend(pdev); -- GitLab From 4f2fe2d27472f4a5dbd875888af4fc5175f3fdc5 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 14 Apr 2014 15:21:23 -0600 Subject: [PATCH 388/797] USB: EHCI: tegra: set txfill_tuning To avoid memory fetch underflows with larger USB transfers, Tegra SoCs need txfill_tuning's txfifothresh register field set to a non-default value. Add a custom reset override in order to set this up. These values are recommended practice for all Tegra chips. However, I've only noticed practical problems when not setting them this way on systems using Tegra124. Hence, CC: stable only for recent kernels which actually support Tegra124. Cc: # 3.14+ Signed-off-by: Stephen Warren Acked-by: Alan Stern Tested-by: Alexandre Courbot Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-tegra.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 27ac6ad53c3d..7ef00ecb0da1 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -509,8 +509,31 @@ static struct platform_driver tegra_ehci_driver = { } }; +static int tegra_ehci_reset(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + int txfifothresh; + + retval = ehci_setup(hcd); + if (retval) + return retval; + + /* + * We should really pull this value out of tegra_ehci_soc_config, but + * to avoid needing access to it, make use of the fact that Tegra20 is + * the only one so far that needs a value of 10, and Tegra20 is the + * only one which doesn't set has_hostpc. + */ + txfifothresh = ehci->has_hostpc ? 0x10 : 10; + ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning); + + return 0; +} + static const struct ehci_driver_overrides tegra_overrides __initconst = { .extra_priv_size = sizeof(struct tegra_ehci_hcd), + .reset = tegra_ehci_reset, }; static int __init ehci_tegra_init(void) -- GitLab From 4d6b5161dba1aa1964e505d2a09bfe4e3a1a7378 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 14 Apr 2014 12:08:13 +0200 Subject: [PATCH 389/797] USB: ohci-jz4740: Fix uninitialized variable warning The ret variable is not initialized in all code paths of the ohci_jz4740_hub_control function. Fix it. Signed-off-by: Laurent Pinchart Acked-by: Lars-Peter Clausen Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-jz4740.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index af8dc1b92d75..b34315ca6cff 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -82,7 +82,7 @@ static int ohci_jz4740_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex, char *buf, u16 wLength) { struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd); - int ret; + int ret = 0; switch (typeReq) { case SetHubFeature: -- GitLab From 166cf4aa354c0066cb1903336382772e9e1b7941 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Mon, 14 Apr 2014 12:08:14 +0200 Subject: [PATCH 390/797] USB: ohci-jz4740: FEAT_POWER is a port feature, not a hub feature Power control of hub ports target the CLEAR_FEATURE and SET_FEATURE requests to ports, not to the hub. Fix the hub control function to detect the request correctly. Signed-off-by: Laurent Pinchart Acked-by: Lars-Peter Clausen Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-jz4740.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c index b34315ca6cff..c2c221a332eb 100644 --- a/drivers/usb/host/ohci-jz4740.c +++ b/drivers/usb/host/ohci-jz4740.c @@ -85,11 +85,11 @@ static int ohci_jz4740_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, int ret = 0; switch (typeReq) { - case SetHubFeature: + case SetPortFeature: if (wValue == USB_PORT_FEAT_POWER) ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true); break; - case ClearHubFeature: + case ClearPortFeature: if (wValue == USB_PORT_FEAT_POWER) ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false); break; -- GitLab From 895d240d1db0b2736d779200788e4c4aea28a0c6 Mon Sep 17 00:00:00 2001 From: Michael Ulbricht Date: Tue, 25 Mar 2014 10:34:18 +0100 Subject: [PATCH 391/797] USB: cdc-acm: Remove Motorola/Telit H24 serial interfaces from ACM driver By specifying NO_UNION_NORMAL the ACM driver does only use the first two USB interfaces (modem data & control). The AT Port, Diagnostic and NMEA interfaces are left to the USB serial driver. Signed-off-by: Michael Ulbricht Signed-off-by: Alexander Stein Signed-off-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index d5d2c922186a..904efb6035b0 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1654,13 +1654,27 @@ static const struct usb_device_id acm_ids[] = { }, /* Motorola H24 HSPA module: */ { USB_DEVICE(0x22b8, 0x2d91) }, /* modem */ - { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */ - { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */ - { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */ - { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */ - { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */ - { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */ - { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */ + { USB_DEVICE(0x22b8, 0x2d92), /* modem + diagnostics */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, + { USB_DEVICE(0x22b8, 0x2d93), /* modem + AT port */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, + { USB_DEVICE(0x22b8, 0x2d95), /* modem + AT port + diagnostics */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, + { USB_DEVICE(0x22b8, 0x2d96), /* modem + NMEA */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, + { USB_DEVICE(0x22b8, 0x2d97), /* modem + diagnostics + NMEA */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, + { USB_DEVICE(0x22b8, 0x2d99), /* modem + AT port + NMEA */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, + { USB_DEVICE(0x22b8, 0x2d9a), /* modem + AT port + diagnostics + NMEA */ + .driver_info = NO_UNION_NORMAL, /* handle only modem interface */ + }, { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on -- GitLab From f7a87195603ae9db133ddd393169dd6c1d45b4a3 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Wed, 16 Apr 2014 18:48:02 +0900 Subject: [PATCH 392/797] uwb: adds missing error handling There is checking NULL before dereferncing but it need to add "return". Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/drp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c index 16ada8341c46..1a2fd9795367 100644 --- a/drivers/uwb/drp.c +++ b/drivers/uwb/drp.c @@ -599,8 +599,11 @@ static void uwb_drp_handle_alien_drp(struct uwb_rc *rc, struct uwb_ie_drp *drp_i /* alloc and initialize new uwb_cnflt_alien */ cnflt = kzalloc(sizeof(struct uwb_cnflt_alien), GFP_KERNEL); - if (!cnflt) + if (!cnflt) { dev_err(dev, "failed to alloc uwb_cnflt_alien struct\n"); + return; + } + INIT_LIST_HEAD(&cnflt->rc_node); init_timer(&cnflt->timer); cnflt->timer.function = uwb_cnflt_timer; -- GitLab From e7eda9329372f5e436e5a9291eb115eab0feae02 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 28 Mar 2014 11:10:30 +0100 Subject: [PATCH 393/797] uas: fix GFP_NOIO under spinlock Quote Dan: The patch e36e64930cff: "uas: Use GFP_NOIO rather then GFP_ATOMIC where possible" from Nov 7, 2013, leads to the following static checker warning: drivers/usb/storage/uas.c:806 uas_eh_task_mgmt() error: scheduling with locks held: 'spin_lock:lock' Some other allocations under spinlock are not caught. The fix essentially reverts e36e64930cffd94e1c37fdb82f35989384aa946b Signed-off-by: Oliver Neukum Reported-by: Dan Carpenter Reviewed-by: Hans de Goede Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index a7ac97cc5949..8f4222640bd6 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -137,7 +137,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_NOIO); + err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); if (!err) cmdinfo->state &= ~IS_IN_WORK_LIST; else @@ -803,7 +803,7 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, devinfo->running_task = 1; memset(&devinfo->response, 0, sizeof(devinfo->response)); - sense_urb = uas_submit_sense_urb(cmnd, GFP_NOIO, + sense_urb = uas_submit_sense_urb(cmnd, GFP_ATOMIC, devinfo->use_streams ? tag : 0); if (!sense_urb) { shost_printk(KERN_INFO, shost, @@ -813,7 +813,7 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd, spin_unlock_irqrestore(&devinfo->lock, flags); return FAILED; } - if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) { + if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) { shost_printk(KERN_INFO, shost, "%s: %s: submit task mgmt urb failed\n", __func__, fname); -- GitLab From c637f1fa7b0452b71eebd35d00906d371c04714e Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 28 Mar 2014 11:29:25 +0100 Subject: [PATCH 394/797] uas: fix error handling during scsi_scan() intfdata is set only after scsi_scan(). uas_pre_reset() however needs intfdata to be valid and will follow the NULL pointer killing khubd. intfdata must be preemptively set before the host is registered and undone in the error case. Signed-off-by: Oliver Neukum Reviewed-by: Hans de Goede Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 8f4222640bd6..fcab9b79d9fb 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -1096,16 +1096,17 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) if (result) goto free_streams; + usb_set_intfdata(intf, shost); result = scsi_add_host(shost, &intf->dev); if (result) goto free_streams; scsi_scan_host(shost); - usb_set_intfdata(intf, shost); return result; free_streams: uas_free_streams(devinfo); + usb_set_intfdata(intf, NULL); set_alt0: usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0); if (shost) -- GitLab From 94d72f008909610710bb1841d665eeeb010a0be1 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Fri, 28 Mar 2014 11:25:50 +0100 Subject: [PATCH 395/797] uas: fix deadlocky memory allocations There are also two allocations with GFP_KERNEL in the pre-/post_reset code paths. That is no good because that is a part of the SCSI error handler. Signed-off-by: Oliver Neukum Reviewed-by: Hans de Goede Acked-by: Hans de Goede Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index fcab9b79d9fb..511b22953167 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -1030,7 +1030,7 @@ static int uas_configure_endpoints(struct uas_dev_info *devinfo) devinfo->use_streams = 0; } else { devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1, - 3, 256, GFP_KERNEL); + 3, 256, GFP_NOIO); if (devinfo->qdepth < 0) return devinfo->qdepth; devinfo->use_streams = 1; @@ -1047,7 +1047,7 @@ static void uas_free_streams(struct uas_dev_info *devinfo) eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); - usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); + usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO); } static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) -- GitLab From 593ceb0c7046c640cf463022189428a45219f595 Mon Sep 17 00:00:00 2001 From: David Fries Date: Tue, 8 Apr 2014 22:37:07 -0500 Subject: [PATCH 396/797] w1: fix netlink refcnt leak on error path If the message type is W1_MASTER_CMD or W1_SLAVE_CMD, then a reference is taken when searching for the slave or master device. If there isn't any following data m->len (mlen is a copy) is 0 and packing up the message for later execution is skipped leaving nothing to decrement the reference counts. Way back when, m->len was checked before the search that increments the reference count, but W1_LIST_MASTERS has no additional data, the check was moved in 9be62e0b2fadaf5ff causing this bug. This change reorders to put the check before the reference count is incremented avoiding the problem. Signed-off-by: David Fries Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1_netlink.c | 44 ++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index 5234964fe001..a02704a59321 100644 --- a/drivers/w1/w1_netlink.c +++ b/drivers/w1/w1_netlink.c @@ -300,12 +300,6 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *w; u32 *id; - if (mcmd->type != W1_LIST_MASTERS) { - printk(KERN_NOTICE "%s: msg: %x.%x, wrong type: %u, len: %u.\n", - __func__, msg->id.idx, msg->id.val, mcmd->type, mcmd->len); - return -EPROTO; - } - cn = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!cn) return -ENOMEM; @@ -441,6 +435,9 @@ static void w1_process_cb(struct w1_master *dev, struct w1_async_cmd *async_cmd) w1_netlink_send_error(&node->block->msg, node->m, cmd, node->block->portid, err); + /* ref taken in w1_search_slave or w1_search_master_id when building + * the block + */ if (sl) w1_unref_slave(sl); else @@ -503,30 +500,42 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) msg_len = msg->len; while (msg_len && !err) { - struct w1_reg_num id; - u16 mlen = m->len; dev = NULL; sl = NULL; - memcpy(&id, m->id.id, sizeof(id)); -#if 0 - printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n", - __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len); -#endif if (m->len + sizeof(struct w1_netlink_msg) > msg_len) { err = -E2BIG; break; } + /* execute on this thread, no need to process later */ + if (m->type == W1_LIST_MASTERS) { + err = w1_process_command_root(msg, m, nsp->portid); + goto out_cont; + } + + /* All following message types require additional data, + * check here before references are taken. + */ + if (!m->len) { + err = -EPROTO; + goto out_cont; + } + + /* both search calls take reference counts */ if (m->type == W1_MASTER_CMD) { dev = w1_search_master_id(m->id.mst.id); } else if (m->type == W1_SLAVE_CMD) { - sl = w1_search_slave(&id); + sl = w1_search_slave((struct w1_reg_num *)m->id.id); if (sl) dev = sl->master; } else { - err = w1_process_command_root(msg, m, nsp->portid); + printk(KERN_NOTICE + "%s: msg: %x.%x, wrong type: %u, len: %u.\n", + __func__, msg->id.idx, msg->id.val, + m->type, m->len); + err = -EPROTO; goto out_cont; } @@ -536,8 +545,6 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) } err = 0; - if (!mlen) - goto out_cont; atomic_inc(&block->refcnt); node->async.cb = w1_process_cb; @@ -557,7 +564,8 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) if (err) w1_netlink_send_error(msg, m, NULL, nsp->portid, err); msg_len -= sizeof(struct w1_netlink_msg) + m->len; - m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len); + m = (struct w1_netlink_msg *)(((u8 *)m) + + sizeof(struct w1_netlink_msg) + m->len); /* * Let's allow requests for nonexisting devices. -- GitLab From 18d7f891bcc7e49f2900215f17a861ccec34b138 Mon Sep 17 00:00:00 2001 From: David Fries Date: Wed, 16 Apr 2014 01:21:21 -0500 Subject: [PATCH 397/797] w1: avoid recursive device_add __w1_attach_slave_device calls device_add which calls w1_bus_notify which calls the w1_bq27000 slave driver, which calls platform_device_add and device_add and deadlocks on getting &(&priv->bus_notifier)->rwsem as it is still held in the previous device_add. This avoids the problem by processing the family add/remove outside of the slave device_add call. Commit 47eba33a0997fc7362a introduced this deadlock and added a KOBJ_ADD, as the add was already reported in device_register two add events were being sent. This change suppresses the device_register add so that any slave device sysfs entries are setup before the add goes out. Belisko Marek reported this change fixed the deadlock he was seeing on ARM device tree, while testing on my x86-64 system never saw the deadlock. Reported-by: Belisko Marek Signed-off-by: David Fries Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index b96f61b15dc6..ff52618cafbe 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -614,27 +614,11 @@ static int w1_uevent(struct device *dev, struct kobj_uevent_env *env) return err; } -/* - * Handle sysfs file creation and removal here, before userspace is told that - * the device is added / removed from the system - */ -static int w1_bus_notify(struct notifier_block *nb, unsigned long action, - void *data) +static int w1_family_notify(unsigned long action, struct w1_slave *sl) { - struct device *dev = data; - struct w1_slave *sl; struct w1_family_ops *fops; int err; - /* - * Only care about slave devices at the moment. Yes, we should use a - * separate "type" for this, but for now, look at the release function - * to know which type it is... - */ - if (dev->release != w1_slave_release) - return 0; - - sl = dev_to_w1_slave(dev); fops = sl->family->fops; if (!fops) @@ -673,10 +657,6 @@ static int w1_bus_notify(struct notifier_block *nb, unsigned long action, return 0; } -static struct notifier_block w1_bus_nb = { - .notifier_call = w1_bus_notify, -}; - static int __w1_attach_slave_device(struct w1_slave *sl) { int err; @@ -698,6 +678,9 @@ static int __w1_attach_slave_device(struct w1_slave *sl) dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, dev_name(&sl->dev), sl); + /* suppress for w1_family_notify before sending KOBJ_ADD */ + dev_set_uevent_suppress(&sl->dev, true); + err = device_register(&sl->dev); if (err < 0) { dev_err(&sl->dev, @@ -705,7 +688,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl) dev_name(&sl->dev), err); return err; } - + w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl); dev_set_uevent_suppress(&sl->dev, false); kobject_uevent(&sl->dev.kobj, KOBJ_ADD); @@ -799,6 +782,7 @@ int w1_unref_slave(struct w1_slave *sl) msg.type = W1_SLAVE_REMOVE; w1_netlink_send(sl->master, &msg); + w1_family_notify(BUS_NOTIFY_DEL_DEVICE, sl); device_unregister(&sl->dev); #ifdef DEBUG memset(sl, 0, sizeof(*sl)); @@ -1186,10 +1170,6 @@ static int __init w1_init(void) goto err_out_exit_init; } - retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb); - if (retval) - goto err_out_bus_unregister; - retval = driver_register(&w1_master_driver); if (retval) { printk(KERN_ERR -- GitLab From 098ced8fefe4a4e4240fa47b1ed9b00d65b6cd21 Mon Sep 17 00:00:00 2001 From: Joe Schultz Date: Thu, 3 Apr 2014 14:47:55 -0500 Subject: [PATCH 398/797] vme_tsi148: Fix typo in tsi148_slave_get() This patch corrects a typo where "vme_base" was used instead of "*vme_base". The typo resulted in an incorrect value being returned to userspace (via vme_user). It also removes the following compile warning on some platforms: warning: cast from pointer to integer of different size [asierra: commit title/log rewording] Signed-off-by: Joe Schultz Signed-off-by: Aaron Sierra Signed-off-by: Greg Kroah-Hartman --- drivers/vme/bridges/vme_tsi148.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index 06990c6a1a69..6b03be715005 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -741,7 +741,7 @@ static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, reg_join(vme_bound_high, vme_bound_low, &vme_bound); reg_join(pci_offset_high, pci_offset_low, &pci_offset); - *pci_base = (dma_addr_t)vme_base + pci_offset; + *pci_base = (dma_addr_t)(*vme_base + pci_offset); *enabled = 0; *aspace = 0; -- GitLab From 226572b110ab6083cb8c1d6afb191166b4178179 Mon Sep 17 00:00:00 2001 From: Joe Schultz Date: Thu, 3 Apr 2014 14:48:16 -0500 Subject: [PATCH 399/797] vme_tsi148: Fix PCI address mapping assumption Previously, tsi148_master_set() assumed the address contained in its PCI bus resource represented the actual PCI bus address. This is a fine assumption on some platforms. However, on platforms that don't use a 1:1 (CPU:PCI) mapping this results in the tsi148 driver configuring an invalid master window translation. This patch updates the vme_tsi148 driver to first convert the address contained in the PCI bus resource into a PCI bus address before using it. [asierra: account for pcibios_resource_to_bus() prototype change] Signed-off-by: Joe Schultz Signed-off-by: Aaron Sierra Signed-off-by: Greg Kroah-Hartman --- drivers/vme/bridges/vme_tsi148.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index 6b03be715005..e64e4208de2b 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -910,11 +910,15 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled, unsigned long long pci_bound, vme_offset, pci_base; struct vme_bridge *tsi148_bridge; struct tsi148_driver *bridge; + struct pci_bus_region region; + struct pci_dev *pdev; tsi148_bridge = image->parent; bridge = tsi148_bridge->driver_priv; + pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + /* Verify input data */ if (vme_base & 0xFFFF) { dev_err(tsi148_bridge->parent, "Invalid VME Window " @@ -949,7 +953,9 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled, pci_bound = 0; vme_offset = 0; } else { - pci_base = (unsigned long long)image->bus_resource.start; + pcibios_resource_to_bus(pdev->bus, ®ion, + &image->bus_resource); + pci_base = region.start; /* * Bound address is a valid address for the window, adjust -- GitLab From 177581faf2a5aa71898d223bc47dbc882eeb1488 Mon Sep 17 00:00:00 2001 From: Aaron Sierra Date: Thu, 3 Apr 2014 14:48:27 -0500 Subject: [PATCH 400/797] vme_tsi148: Utilize to_pci_dev() macro Save some characters by using to_pci_dev() instead of container_of(). Signed-off-by: Aaron Sierra Signed-off-by: Greg Kroah-Hartman --- drivers/vme/bridges/vme_tsi148.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c index e64e4208de2b..61e706c0e00c 100644 --- a/drivers/vme/bridges/vme_tsi148.c +++ b/drivers/vme/bridges/vme_tsi148.c @@ -320,7 +320,7 @@ static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) struct pci_dev *pdev; struct tsi148_driver *bridge; - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + pdev = to_pci_dev(tsi148_bridge->parent); bridge = tsi148_bridge->driver_priv; @@ -433,9 +433,7 @@ static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO); if (sync != 0) { - pdev = container_of(tsi148_bridge->parent, - struct pci_dev, dev); - + pdev = to_pci_dev(tsi148_bridge->parent); synchronize_irq(pdev->irq); } } else { @@ -814,7 +812,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, tsi148_bridge = image->parent; - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + pdev = to_pci_dev(tsi148_bridge->parent); existing_size = (unsigned long long)(image->bus_resource.end - image->bus_resource.start); @@ -917,7 +915,7 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled, bridge = tsi148_bridge->driver_priv; - pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev); + pdev = to_pci_dev(tsi148_bridge->parent); /* Verify input data */ if (vme_base & 0xFFFF) { @@ -2238,7 +2236,7 @@ static void *tsi148_alloc_consistent(struct device *parent, size_t size, struct pci_dev *pdev; /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); + pdev = to_pci_dev(parent); return pci_alloc_consistent(pdev, size, dma); } @@ -2249,7 +2247,7 @@ static void tsi148_free_consistent(struct device *parent, size_t size, struct pci_dev *pdev; /* Find pci_dev container of dev */ - pdev = container_of(parent, struct pci_dev, dev); + pdev = to_pci_dev(parent); pci_free_consistent(pdev, size, vaddr, dma); } -- GitLab From 314672a2c2780212fb770bb02d2fffaa1019823f Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Wed, 9 Apr 2014 17:24:16 -0700 Subject: [PATCH 401/797] Tools: hv: Handle the case when the target file exists correctly Return the appropriate error code and handle the case when the target file exists correctly. This fixes a bug. Signed-off-by: K. Y. Srinivasan Cc: [3.14] Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/hyperv.h | 1 + tools/hv/hv_fcopy_daemon.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h index 9beb7c991638..78e4a86030dd 100644 --- a/include/uapi/linux/hyperv.h +++ b/include/uapi/linux/hyperv.h @@ -305,6 +305,7 @@ enum hv_kvp_exchg_pool { #define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F #define HV_INVALIDARG 0x80070057 #define HV_GUID_NOTFOUND 0x80041002 +#define HV_ERROR_ALREADY_EXISTS 0x80070050 #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 4ecc4fd0bc1b..fba1c75aa484 100644 --- a/tools/hv/hv_fcopy_daemon.c +++ b/tools/hv/hv_fcopy_daemon.c @@ -82,8 +82,10 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg) if (!access(target_fname, F_OK)) { syslog(LOG_INFO, "File: %s exists", target_fname); - if (!smsg->copy_flags & OVER_WRITE) + if (!(smsg->copy_flags & OVER_WRITE)) { + error = HV_ERROR_ALREADY_EXISTS; goto done; + } } target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744); -- GitLab From 408065998443831d3369c6bfdc8862c1d02a91dd Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 2 Apr 2014 09:37:08 -0700 Subject: [PATCH 402/797] stable_kernel_rules: spelling/word usage "than" should be "then" Signed-off-by: Brian Norris Signed-off-by: Greg Kroah-Hartman --- Documentation/stable_kernel_rules.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt index b0714d8f678a..cbc2f03056bd 100644 --- a/Documentation/stable_kernel_rules.txt +++ b/Documentation/stable_kernel_rules.txt @@ -39,7 +39,7 @@ Procedure for submitting patches to the -stable tree: the stable tree without anything else needing to be done by the author or subsystem maintainer. - If the patch requires other patches as prerequisites which can be - cherry-picked than this can be specified in the following format in + cherry-picked, then this can be specified in the following format in the sign-off area: Cc: # 3.3.x: a1f84a3: sched: Check for idle -- GitLab From 06d96c0ff77f20dbf5fc93c8cfa9a2a9690fd67e Mon Sep 17 00:00:00 2001 From: Lin Yongting Date: Wed, 16 Apr 2014 23:25:28 +0800 Subject: [PATCH 403/797] Chinese: add translation of io_ordering.txt This is a Chinese translated version of Documentation/io_ordering.txt Signed-off-by: Lin Yongting Signed-off-by: Greg Kroah-Hartman --- Documentation/zh_CN/io_ordering.txt | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/zh_CN/io_ordering.txt diff --git a/Documentation/zh_CN/io_ordering.txt b/Documentation/zh_CN/io_ordering.txt new file mode 100644 index 000000000000..e592daf4e014 --- /dev/null +++ b/Documentation/zh_CN/io_ordering.txt @@ -0,0 +1,67 @@ +Chinese translated version of Documentation/io_orderings.txt + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Chinese maintainer: Lin Yongting +--------------------------------------------------------------------- +Documentation/io_ordering.txt 的中文翻译 + +如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文 +交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻 +译存在问题,请联系中文版维护者。 + +中文版维护者: 林永听 Lin Yongting +中文版翻译者: 林永听 Lin Yongting +中文版校译者: 林永听 Lin Yongting + + +以下为正文 +--------------------------------------------------------------------- + +在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任 +保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全” +设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作, +而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。 +这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存 +屏障操作,mb(),不过仅适用于I/O)。 + +假设一个设备驱动程的具体例子: + + ... +CPU A: spin_lock_irqsave(&dev_lock, flags) +CPU A: val = readl(my_status); +CPU A: ... +CPU A: writel(newval, ring_ptr); +CPU A: spin_unlock_irqrestore(&dev_lock, flags) + ... +CPU B: spin_lock_irqsave(&dev_lock, flags) +CPU B: val = readl(my_status); +CPU B: ... +CPU B: writel(newval2, ring_ptr); +CPU B: spin_unlock_irqrestore(&dev_lock, flags) + ... + +上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就 +发生了。不过很容易通过下面方法来修复: + + ... +CPU A: spin_lock_irqsave(&dev_lock, flags) +CPU A: val = readl(my_status); +CPU A: ... +CPU A: writel(newval, ring_ptr); +CPU A: (void)readl(safe_register); /* 配置寄存器?*/ +CPU A: spin_unlock_irqrestore(&dev_lock, flags) + ... +CPU B: spin_lock_irqsave(&dev_lock, flags) +CPU B: val = readl(my_status); +CPU B: ... +CPU B: writel(newval2, ring_ptr); +CPU B: (void)readl(safe_register); /* 配置寄存器?*/ +CPU B: spin_unlock_irqrestore(&dev_lock, flags) + +在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作, +再处理后面的读操作,防止引发数据不一致问题。 -- GitLab From 53974e06603977f348ed978d75c426b0532daa67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Stehl=C3=A9?= Date: Fri, 4 Apr 2014 08:43:18 +0200 Subject: [PATCH 404/797] topology: Fix compilation warning when not in SMP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The topology_##name() macro does not use its argument when CONFIG_SMP is not set, as it ultimately calls the cpu_data() macro. So we avoid maintaining a possibly unused `cpu' variable, to avoid the following compilation warning: drivers/base/topology.c: In function ‘show_physical_package_id’: drivers/base/topology.c:103:118: warning: unused variable ‘cpu’ [-Wunused-variable] define_id_show_func(physical_package_id); drivers/base/topology.c: In function ‘show_core_id’: drivers/base/topology.c:106:106: warning: unused variable ‘cpu’ [-Wunused-variable] define_id_show_func(core_id); This can be seen with e.g. x86 defconfig and CONFIG_SMP not set. Signed-off-by: Vincent Stehlé Cc: Greg Kroah-Hartman Cc: # 3.10.x Cc: # 3.13.x Cc: # 3.14.x Signed-off-by: Greg Kroah-Hartman --- drivers/base/topology.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/base/topology.c b/drivers/base/topology.c index bbcbd3c43926..be7c1fb7c0c9 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -39,8 +39,7 @@ static ssize_t show_##name(struct device *dev, \ struct device_attribute *attr, char *buf) \ { \ - unsigned int cpu = dev->id; \ - return sprintf(buf, "%d\n", topology_##name(cpu)); \ + return sprintf(buf, "%d\n", topology_##name(dev->id)); \ } #if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \ -- GitLab From 98b0f811aade1b7c6e7806c86aa0befd5919d65f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 14 Apr 2014 18:52:14 +0200 Subject: [PATCH 405/797] Documentation: Update stable address in Chinese and Japanese translations The English and Korean translations were updated, the Chinese and Japanese weren't. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- Documentation/ja_JP/HOWTO | 2 +- Documentation/ja_JP/stable_kernel_rules.txt | 6 +++--- Documentation/zh_CN/HOWTO | 2 +- Documentation/zh_CN/stable_kernel_rules.txt | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO index 0091a8215ac1..b61885c35ce1 100644 --- a/Documentation/ja_JP/HOWTO +++ b/Documentation/ja_JP/HOWTO @@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が 最新の安定版カーネルです。 -3.x.y は "stable" チーム でメンテされており、必 +3.x.y は "stable" チーム でメンテされており、必 要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ た問題がなければもう少し長くなることもあります。セキュリティ関連の問題 の場合はこれに対してだいたいの場合、すぐにリリースがされます。 diff --git a/Documentation/ja_JP/stable_kernel_rules.txt b/Documentation/ja_JP/stable_kernel_rules.txt index 14265837c4ce..9dbda9b5d21e 100644 --- a/Documentation/ja_JP/stable_kernel_rules.txt +++ b/Documentation/ja_JP/stable_kernel_rules.txt @@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt -stable ツリーにパッチを送付する手続き- - - 上記の規則に従っているかを確認した後に、stable@kernel.org にパッチ + - 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ を送る。 - 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合 には NAK を受け取る。この反応は開発者たちのスケジュールによって、数 日かかる場合がある。 - もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの メンテナーによるレビューのために -stable キューに追加される。 - - パッチに stable@kernel.org のアドレスが付加されているときには、それ + - パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ が Linus のツリーに入る時に自動的に stable チームに email される。 - - セキュリティパッチはこのエイリアス (stable@kernel.org) に送られるべ + - セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ きではなく、代わりに security@kernel.org のアドレスに送られる。 レビューサイクル- diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO index 6c914aa87e71..54ea24ff63c7 100644 --- a/Documentation/zh_CN/HOWTO +++ b/Documentation/zh_CN/HOWTO @@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循 如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定 版内核。 -2.6.x.y版本由“稳定版”小组(邮件地址)维护,一般隔周发 +2.6.x.y版本由“稳定版”小组(邮件地址)维护,一般隔周发 布新版本。 内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定 diff --git a/Documentation/zh_CN/stable_kernel_rules.txt b/Documentation/zh_CN/stable_kernel_rules.txt index b5b9b0ab02fd..26ea5ed7cd9c 100644 --- a/Documentation/zh_CN/stable_kernel_rules.txt +++ b/Documentation/zh_CN/stable_kernel_rules.txt @@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译 向稳定版代码树提交补丁的过程: - - 在确认了补丁符合以上的规则后,将补丁发送到stable@kernel.org。 + - 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。 - 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收 到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。 - 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。 -- GitLab From 03367ef5ea811475187a0732aada068919e14d61 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Thu, 3 Apr 2014 18:02:45 -0700 Subject: [PATCH 406/797] Drivers: hv: vmbus: Negotiate version 3.0 when running on ws2012r2 hosts Only ws2012r2 hosts support the ability to reconnect to the host on VMBUS. This functionality is needed by kexec in Linux. To use this functionality we need to negotiate version 3.0 of the VMBUS protocol. Signed-off-by: K. Y. Srinivasan Cc: [3.9+] Signed-off-by: Greg Kroah-Hartman --- drivers/hv/connection.c | 5 ++++- include/linux/hyperv.h | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index f2d7bf90c9fe..2e7801af466e 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -55,6 +55,9 @@ static __u32 vmbus_get_next_version(__u32 current_version) case (VERSION_WIN8): return VERSION_WIN7; + case (VERSION_WIN8_1): + return VERSION_WIN8; + case (VERSION_WS2008): default: return VERSION_INVAL; @@ -77,7 +80,7 @@ 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) + if (version == VERSION_WIN8_1) msg->target_vcpu = hv_context.vp_index[smp_processor_id()]; /* diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index ab7359fde987..2d7b4f139c32 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -147,15 +147,17 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, * 0 . 13 (Windows Server 2008) * 1 . 1 (Windows 7) * 2 . 4 (Windows 8) + * 3 . 0 (Windows 8 R2) */ #define VERSION_WS2008 ((0 << 16) | (13)) #define VERSION_WIN7 ((1 << 16) | (1)) #define VERSION_WIN8 ((2 << 16) | (4)) +#define VERSION_WIN8_1 ((3 << 16) | (0)) #define VERSION_INVAL -1 -#define VERSION_CURRENT VERSION_WIN8 +#define VERSION_CURRENT VERSION_WIN8_1 /* Make maximum size of pipe payload of 16K */ #define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) -- GitLab From 93a2e470ef3b17495029a89a05e25830aeca1ffb Mon Sep 17 00:00:00 2001 From: Sanjay Singh Rawat Date: Fri, 21 Mar 2014 13:55:10 +0530 Subject: [PATCH 407/797] serial: omap: free the wakeup settings in remove Signed-off-by: Sanjay Singh Rawat Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index dd8b1a5458ff..ecfafbb30356 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1789,6 +1789,7 @@ static int serial_omap_remove(struct platform_device *dev) pm_runtime_disable(up->dev); uart_remove_one_port(&serial_omap_reg, &up->port); pm_qos_remove_request(&up->pm_qos_request); + device_init_wakeup(&dev->dev, false); return 0; } -- GitLab From 4ea8dafd2475e26b3cee3836bc6e6fddbdfb2721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Tue, 25 Mar 2014 15:53:12 +0100 Subject: [PATCH 408/797] serial: efm32: use $vendor,$device scheme for compatible string MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wolfram Sang pointed out that "efm32,$device" is non-standard. So use the common scheme and prefix device with "efm32-". The old compatible string is left in place until arch/arm/boot/dts/efm32* is fixed. Reported-by: Wolfram Sang Signed-off-by: Uwe Kleine-König Acked-by: Wolfram Sang Signed-off-by: Greg Kroah-Hartman --- Documentation/devicetree/bindings/serial/efm32-uart.txt | 4 ++-- drivers/tty/serial/efm32-uart.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/serial/efm32-uart.txt b/Documentation/devicetree/bindings/serial/efm32-uart.txt index 1984bdfbd545..3ca01336b837 100644 --- a/Documentation/devicetree/bindings/serial/efm32-uart.txt +++ b/Documentation/devicetree/bindings/serial/efm32-uart.txt @@ -1,7 +1,7 @@ * Energymicro efm32 UART Required properties: -- compatible : Should be "efm32,uart" +- compatible : Should be "energymicro,efm32-uart" - reg : Address and length of the register set - interrupts : Should contain uart interrupt @@ -13,7 +13,7 @@ Optional properties: Example: uart@0x4000c400 { - compatible = "efm32,uart"; + compatible = "energymicro,efm32-uart"; reg = <0x4000c400 0x400>; interrupts = <15>; efm32,location = <0>; diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index 028582e924a5..c167a710dc39 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c @@ -798,6 +798,9 @@ static int efm32_uart_remove(struct platform_device *pdev) static const struct of_device_id efm32_uart_dt_ids[] = { { + .compatible = "energymicro,efm32-uart", + }, { + /* doesn't follow the "vendor,device" scheme, don't use */ .compatible = "efm32,uart", }, { /* sentinel */ -- GitLab From 717f3bbab3c7628736ef738fdbf3d9a28578c26c Mon Sep 17 00:00:00 2001 From: Seth Bollinger Date: Tue, 25 Mar 2014 12:55:37 -0500 Subject: [PATCH 409/797] serial_core: Fix conditional start_tx on ring buffer not empty If the serial_core ring buffer empties just as the tty layer receives an XOFF, then start_tx will never be called when the tty layer receives an XON as the serial_core ring buffer is empty. This will possibly leave a few bytes trapped in the fifo for drivers that disable the transmitter when flow controlled. Signed-off-by: Seth Bollinger Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2cf5649a6dc0..dd1a7bef6647 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -89,8 +89,7 @@ static void __uart_start(struct tty_struct *tty) struct uart_state *state = tty->driver_data; struct uart_port *port = state->uart_port; - if (!uart_circ_empty(&state->xmit) && state->xmit.buf && - !tty->stopped && !tty->hw_stopped) + if (!tty->stopped && !tty->hw_stopped) port->ops->start_tx(port); } -- GitLab From 2f310b8e418ac5eb3833a9f36791c24a97f1f557 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Thu, 27 Mar 2014 13:38:19 +0400 Subject: [PATCH 410/797] Revert "serial: clps711x: Give a chance to perform useful tasks during wait loop" This reverts commit 63e3ad3252695a2b8c01b6f6c225e4537af08b85, since this not works as expected and produce runtime error: BUG: sleeping function called from invalid context at drivers/tty/serial/clps711x.c:379 in_atomic(): 0, irqs_disabled(): 128, pid: 287, name: mount Signed-off-by: Alexander Shiyan Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/clps711x.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 5e6fdb1ea73b..14aaea0d4131 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c @@ -368,16 +368,12 @@ static const struct uart_ops uart_clps711x_ops = { static void uart_clps711x_console_putchar(struct uart_port *port, int ch) { struct clps711x_port *s = dev_get_drvdata(port->dev); + u32 sysflg = 0; /* Wait for FIFO is not full */ - while (1) { - u32 sysflg = 0; - + do { regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); - if (!(sysflg & SYSFLG_UTXFF)) - break; - cond_resched(); - } + } while (sysflg & SYSFLG_UTXFF); writew(ch, port->membase + UARTDR_OFFSET); } @@ -387,18 +383,14 @@ static void uart_clps711x_console_write(struct console *co, const char *c, { struct uart_port *port = clps711x_uart.state[co->index].uart_port; struct clps711x_port *s = dev_get_drvdata(port->dev); + u32 sysflg = 0; uart_console_write(port, c, n, uart_clps711x_console_putchar); /* Wait for transmitter to become empty */ - while (1) { - u32 sysflg = 0; - + do { regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); - if (!(sysflg & SYSFLG_UBUSY)) - break; - cond_resched(); - } + } while (sysflg & SYSFLG_UBUSY); } static int uart_clps711x_console_setup(struct console *co, char *options) -- GitLab From c3c00b6f7f79be1dd1aa0969ee0ab7d1f79eda79 Mon Sep 17 00:00:00 2001 From: Daniel Thompson Date: Fri, 28 Mar 2014 10:53:10 +0000 Subject: [PATCH 411/797] serial: st-asc: Fix SysRq char handling This driver, like several others, uses the upper bits of the character to track both real and dummy state. Unfortunately it neglects to mask these bits properly when passing the character data around. This means neither break detection nor sysrq character handling work correctly. This patch adds the requires masking and has been tested to confirm that it correctly handles magic sysrq sequences on ST's B2020 board. Signed-off-by: Daniel Thompson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/st-asc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 21e6e84c0df8..dd3a96e07026 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c @@ -295,7 +295,7 @@ static void asc_receive_chars(struct uart_port *port) status & ASC_STA_OE) { if (c & ASC_RXBUF_FE) { - if (c == ASC_RXBUF_FE) { + if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) { port->icount.brk++; if (uart_handle_break(port)) continue; @@ -325,7 +325,7 @@ static void asc_receive_chars(struct uart_port *port) flag = TTY_FRAME; } - if (uart_handle_sysrq_char(port, c)) + if (uart_handle_sysrq_char(port, c & 0xff)) continue; uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag); -- GitLab From e55c2a07c4abf65d1915a7507a625c82c72fed5a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Thu, 3 Apr 2014 11:36:22 +0200 Subject: [PATCH 412/797] serial: timberdale: Depend on X86_32 As far as I know the Timberdale chip was only used as a companion for Intel Atom E600 series processors. As such, its drivers are only useful on X86_32. Signed-off-by: Jean Delvare Cc: Greg Kroah-Hartman Cc: Jiri Slaby 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 2e6d8ddc4425..5d9b01aa54f4 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1226,6 +1226,7 @@ config SERIAL_BFIN_SPORT3_UART_CTSRTS config SERIAL_TIMBERDALE tristate "Support for timberdale UART" select SERIAL_CORE + depends on X86_32 || COMPILE_TEST ---help--- Add support for UART controller on timberdale. -- GitLab From b2aeb775f814c9543784b15a5f2d87ea91005f3f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sat, 12 Apr 2014 19:47:17 +0200 Subject: [PATCH 413/797] serial: pl011: change Rx burst size to half of trigger level The amba-pl011.c driver sets DMA burst size equal to FIFO trigger level. If now exactly DMA burst size bytes are received, the DMAC will retrieve them all and no Rx timeout interrupt will be generated. To fix that set the burst size to half the FIFO trigger level. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d4eda24aa68b..ca0ec600fab6 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -318,7 +318,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * .src_addr = uap->port.mapbase + UART01x_DR, .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .direction = DMA_DEV_TO_MEM, - .src_maxburst = uap->fifosize >> 1, + .src_maxburst = uap->fifosize >> 2, .device_fc = false, }; -- GitLab From bf903c0c6ddfedec19ba92626ca30e98bfafbe08 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 27 Mar 2014 11:40:39 +0100 Subject: [PATCH 414/797] serial_core: Fix pm imbalance on unbind When a serial port is closed, uart_close() takes care of shutting down the hardware, and powering it down. When a serial port is unbound while in use, uart_close() bypasses all of this, as this is supposed to be done through uart_hangup() (invoked via tty_vhangup() in uart_remove_one_port()). However, uart_hangup() does not set the hardware's power state, leaving it powered up. This may also lead to unbounded nesting counts in clock and power management, depending on their internal implementation. Make sure to power down the port in uart_hangup(), except when the port is used as a serial console. For serial consoles, this operation must be postponed until after the port becomes completely unused. This case is not fixed yet, as it depends on a (future) fix for the tty->count vs. port->count imbalance on failed uart_open(). After this, the module clock used by the sh-sci driver is disabled on unbind while the serial port is in use. Signed-off-by: Geert Uytterhoeven Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index dd1a7bef6647..f26834d262b3 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1451,6 +1451,8 @@ static void uart_hangup(struct tty_struct *tty) clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); spin_unlock_irqrestore(&port->lock, flags); tty_port_tty_set(port, NULL); + if (!uart_console(state->uart_port)) + uart_change_pm(state, UART_PM_STATE_OFF); wake_up_interruptible(&port->open_wait); wake_up_interruptible(&port->delta_msr_wait); } -- GitLab From d758c9c1b36b4d9a141c2146c70398d756167ed1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 25 Mar 2014 11:48:47 -0700 Subject: [PATCH 415/797] serial: omap: Fix missing pm_runtime_resume handling by simplifying code The lack of pm_runtime_resume handling for the device state leads into device wake-up interrupts not working after a while for runtime PM. Also, serial-omap is confused about the use of device_may_wakeup. The checks for device_may_wakeup should only be done for suspend and resume, not for pm_runtime_suspend and pm_runtime_resume. The wake-up events for PM runtime should always be enabled. The lack of pm_runtime_resume handling leads into device wake-up interrupts not working after a while for runtime PM. Rather than try to patch over the issue of adding complex tests to the pm_runtime_resume, let's fix the issues properly: 1. Make serial_omap_enable_wakeup deal with all internal PM state handling so we don't need to test for up->wakeups_enabled elsewhere. Later on once omap3 boots in device tree only mode we can also remove the up->wakeups_enabled flag and rely on the wake-up interrupt enable/disable state alone. 2. Do the device_may_wakeup checks in suspend and resume only, for runtime PM the wake-up events need to be always enabled. 3. Finally just call serial_omap_enable_wakeup and make sure we call it also in pm_runtime_resume. 4. Note that we also have to use disable_irq_nosync as serial_omap_irq calls pm_runtime_get_sync. Fixes: 2a0b965cfb6e (serial: omap: Add support for optional wake-up) Cc: stable@vger.kernel.org # v3.13+ Signed-off-by: Tony Lindgren Acked-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index ecfafbb30356..08b6b9419f0d 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up, if (enable) enable_irq(up->wakeirq); else - disable_irq(up->wakeirq); + disable_irq_nosync(up->wakeirq); } static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) { struct omap_uart_port_info *pdata = dev_get_platdata(up->dev); + if (enable == up->wakeups_enabled) + return; + serial_omap_enable_wakeirq(up, enable); + up->wakeups_enabled = enable; + if (!pdata || !pdata->enable_wakeup) return; @@ -1495,6 +1500,11 @@ static int serial_omap_suspend(struct device *dev) uart_suspend_port(&serial_omap_reg, &up->port); flush_work(&up->qos_work); + if (device_may_wakeup(dev)) + serial_omap_enable_wakeup(up, true); + else + serial_omap_enable_wakeup(up, false); + return 0; } @@ -1502,6 +1512,9 @@ static int serial_omap_resume(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); + if (device_may_wakeup(dev)) + serial_omap_enable_wakeup(up, false); + uart_resume_port(&serial_omap_reg, &up->port); return 0; @@ -1878,17 +1891,7 @@ static int serial_omap_runtime_suspend(struct device *dev) up->context_loss_cnt = serial_omap_get_context_loss_count(up); - if (device_may_wakeup(dev)) { - if (!up->wakeups_enabled) { - serial_omap_enable_wakeup(up, true); - up->wakeups_enabled = true; - } - } else { - if (up->wakeups_enabled) { - serial_omap_enable_wakeup(up, false); - up->wakeups_enabled = false; - } - } + serial_omap_enable_wakeup(up, true); up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; schedule_work(&up->qos_work); @@ -1902,6 +1905,8 @@ static int serial_omap_runtime_resume(struct device *dev) int loss_cnt = serial_omap_get_context_loss_count(up); + serial_omap_enable_wakeup(up, false); + if (loss_cnt < 0) { dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n", loss_cnt); -- GitLab From 3053075cea4e1d385cf0b003ffeb860cc8b378fb Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 31 Mar 2014 14:54:25 +0200 Subject: [PATCH 416/797] Documentation/serial: Delete obsolete driver documentation These serial drivers were removed in kernel v3.1, so we can drop their documentation files and references to their magic numbers and parameters. There are still references to these old drivers in Documentation/devices.txt but I'm afraid they can't be removed. Signed-off-by: Jean Delvare Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: Rob Landley Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 13 - Documentation/magic-number.txt | 12 - Documentation/serial/00-INDEX | 8 - Documentation/serial/digiepca.txt | 98 ------- Documentation/serial/riscom8.txt | 36 --- Documentation/serial/specialix.txt | 383 --------------------------- Documentation/serial/sx.txt | 294 -------------------- Documentation/zh_CN/magic-number.txt | 12 - firmware/WHENCE | 10 - 9 files changed, 866 deletions(-) delete mode 100644 Documentation/serial/digiepca.txt delete mode 100644 Documentation/serial/riscom8.txt delete mode 100644 Documentation/serial/specialix.txt delete mode 100644 Documentation/serial/sx.txt diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 03e50b4883a8..43842177b771 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -804,13 +804,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. dhash_entries= [KNL] Set number of hash buckets for dentry cache. - digi= [HW,SERIAL] - IO parameters + enable/disable command. - - digiepca= [HW,SERIAL] - See drivers/char/README.epca and - Documentation/serial/digiepca.txt. - disable= [IPV6] See Documentation/networking/ipv6.txt. @@ -2939,9 +2932,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. rhash_entries= [KNL,NET] Set number of hash buckets for route cache - riscom8= [HW,SERIAL] - Format: [,[,...]] - ro [KNL] Mount root device read-only on boot root= [KNL] Root filesystem @@ -3083,9 +3073,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. sonypi.*= [HW] Sony Programmable I/O Control Device driver See Documentation/laptops/sonypi.txt - specialix= [HW,SERIAL] Specialix multi-serial port adapter - See Documentation/serial/specialix.txt. - spia_io_base= [HW,MTD] spia_fio_base= spia_pedr= diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt index 76d80a64bbe1..4c8e142db2ef 100644 --- a/Documentation/magic-number.txt +++ b/Documentation/magic-number.txt @@ -63,8 +63,6 @@ Magic Name Number Structure File PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h CMAGIC 0x0111 user include/linux/a.out.h MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h -RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h -SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h @@ -82,7 +80,6 @@ STRIP_MAGIC 0x5303 strip drivers/net/strip.c X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h -ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h TTY_MAGIC 0x5401 tty_struct include/linux/tty.h MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h @@ -94,13 +91,10 @@ USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h -A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h LSEMAGIC 0x05091998 lse drivers/fc4/fc.c GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c -RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c -SX_MAGIC 0x12345678 gs_port drivers/char/sx.h NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h RED_MAGIC2 0x170fc2a5 (any) mm/slab.c BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c @@ -116,7 +110,6 @@ ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c -STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c @@ -127,10 +120,8 @@ SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h RED_MAGIC1 0x5a2cf071 (any) mm/slab.c -STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h -EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c @@ -142,17 +133,14 @@ SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c -STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h -STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h CODA_MAGIC 0xC0DAC0DA coda_file_info fs/coda/coda_fs_i.h DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h -STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX index f9c6b5ed03e7..8021a9f29fc5 100644 --- a/Documentation/serial/00-INDEX +++ b/Documentation/serial/00-INDEX @@ -2,23 +2,15 @@ - this file. README.cycladesZ - info on Cyclades-Z firmware loading. -digiepca.txt - - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards. driver - intro to the low level serial driver. moxa-smartio - file with info on installing/using Moxa multiport serial driver. n_gsm.txt - GSM 0710 tty multiplexer howto. -riscom8.txt - - notes on using the RISCom/8 multi-port serial driver. rocket.txt - info on the Comtrol RocketPort multiport serial driver. serial-rs485.txt - info about RS485 structures and support in the kernel. -specialix.txt - - info on hardware/driver for specialix IO8+ multiport serial card. -sx.txt - - info on the Specialix SX/SI multiport serial driver. tty.txt - guide to the locking policies of the tty layer. diff --git a/Documentation/serial/digiepca.txt b/Documentation/serial/digiepca.txt deleted file mode 100644 index f2560e22f2c9..000000000000 --- a/Documentation/serial/digiepca.txt +++ /dev/null @@ -1,98 +0,0 @@ -NOTE: This driver is obsolete. Digi provides a 2.6 driver (dgdm) at -http://www.digi.com for PCI cards. They no longer maintain this driver, -and have no 2.6 driver for ISA cards. - -This driver requires a number of user-space tools. They can be acquired from -http://www.digi.com, but only works with 2.4 kernels. - - -The Digi Intl. epca driver. ----------------------------- -The Digi Intl. epca driver for Linux supports the following boards: - -Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve -Digi EISA/Xem, PCI/Xem, PCI/Xr - -Limitations: ------------- -Currently the driver only autoprobes for supported PCI boards. - -The Linux MAKEDEV command does not support generating the Digiboard -Devices. Users executing digiConfig to setup EISA and PC series cards -will have their device nodes automatically constructed (cud?? for ~CLOCAL, -and ttyD?? for CLOCAL). Users wishing to boot their board from the LILO -prompt, or those users booting PCI cards may use buildDIGI to construct -the necessary nodes. - -Notes: ------- -This driver may be configured via LILO. For users who have already configured -their driver using digiConfig, configuring from LILO will override previous -settings. Multiple boards may be configured by issuing multiple LILO command -lines. For examples see the bottom of this document. - -Device names start at 0 and continue up. Beware of this as previous Digi -drivers started device names with 1. - -PCI boards are auto-detected and configured by the driver. PCI boards will -be allocated device numbers (internally) beginning with the lowest PCI slot -first. In other words a PCI card in slot 3 will always have higher device -nodes than a PCI card in slot 1. - -LILO config examples: ---------------------- -Using LILO's APPEND command, a string of comma separated identifiers or -integers can be used to configure supported boards. The six values in order -are: - - Enable/Disable this card or Override, - Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2), - EISA/Xem (3), PC/64Xe (4), PC/Xi (5), - Enable/Disable alternate pin arrangement, - Number of ports on this card, - I/O Port where card is configured (in HEX if using string identifiers), - Base of memory window (in HEX if using string identifiers), - -NOTE : PCI boards are auto-detected and configured. Do not attempt to -configure PCI boards with the LILO append command. If you wish to override -previous configuration data (As set by digiConfig), but you do not wish to -configure any specific card (Example if there are PCI cards in the system) -the following override command will accomplish this: --> append="digi=2" - -Samples: - append="digiepca=E,PC/Xe,D,16,200,D0000" - or - append="digi=1,0,0,16,512,851968" - -Supporting Tools: ------------------ -Supporting tools include digiDload, digiConfig, buildPCI, and ditty. See -drivers/char/README.epca for more details. Note, -this driver REQUIRES that digiDload be executed prior to it being used. -Failure to do this will result in an ENODEV error. - -Documentation: --------------- -Complete documentation for this product may be found in the tool package. - -Sources of information and support: ------------------------------------ -Digi Intl. support site for this product: - --> http://www.digi.com - -Acknowledgments: ----------------- -Much of this work (And even text) was derived from a similar document -supporting the original public domain DigiBoard driver Copyright (C) -1994,1995 Troy De Jongh. Many thanks to Christoph Lameter -(christoph@lameter.com) and Mike McLagan (mike.mclagan@linux.org) who authored -and contributed to the original document. - -Changelog: ----------- -10-29-04: Update status of driver, remove dead links in document - James Nelson - -2000 (?) Original Document diff --git a/Documentation/serial/riscom8.txt b/Documentation/serial/riscom8.txt deleted file mode 100644 index 14f61fdad7ca..000000000000 --- a/Documentation/serial/riscom8.txt +++ /dev/null @@ -1,36 +0,0 @@ -* NOTE - this is an unmaintained driver. The original author cannot be located. - -SDL Communications is now SBS Technologies, and does not have any -information on these ancient ISA cards on their website. - -James Nelson - 12-12-2004 - - This is the README for RISCom/8 multi-port serial driver - (C) 1994-1996 D.Gorodchanin - See file LICENSE for terms and conditions. - -NOTE: English is not my native language. - I'm sorry for any mistakes in this text. - -Misc. notes for RISCom/8 serial driver, in no particular order :) - -1) This driver can support up to 4 boards at time. - Use string "riscom8=0xXXX,0xXXX,0xXXX,0xXXX" at LILO prompt, for - setting I/O base addresses for boards. If you compile driver - as module use modprobe options "iobase=0xXXX iobase1=0xXXX iobase2=..." - -2) The driver partially supports famous 'setserial' program, you can use almost - any of its options, excluding port & irq settings. - -3) There are some misc. defines at the beginning of riscom8.c, please read the - comments and try to change some of them in case of problems. - -4) I consider the current state of the driver as BETA. - -5) SDL Communications WWW page is http://www.sdlcomm.com. - -6) You can use the MAKEDEV program to create RISCom/8 /dev/ttyL* entries. - -7) Minor numbers for first board are 0-7, for second 8-15, etc. - -22 Apr 1996. diff --git a/Documentation/serial/specialix.txt b/Documentation/serial/specialix.txt deleted file mode 100644 index 6eb6f3a3331c..000000000000 --- a/Documentation/serial/specialix.txt +++ /dev/null @@ -1,383 +0,0 @@ - - specialix.txt -- specialix IO8+ multiport serial driver readme. - - - - Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - - Specialix pays for the development and support of this driver. - Please DO contact io8-linux@specialix.co.uk if you require - support. - - This driver was developed in the BitWizard linux device - driver service. If you require a linux device driver for your - product, please contact devices@BitWizard.nl for a quote. - - This code is firmly based on the riscom/8 serial driver, - written by Dmitry Gorodchanin. The specialix IO8+ card - programming information was obtained from the CL-CD1865 Data - Book, and Specialix document number 6200059: IO8+ Hardware - Functional Specification, augmented by document number 6200088: - Merak Hardware Functional Specification. (IO8+/PCI is also - called Merak) - - - 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. - - 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., 675 Mass Ave, Cambridge, MA 02139, - USA. - - -Intro -===== - - -This file contains some random information, that I like to have online -instead of in a manual that can get lost. Ever misplace your Linux -kernel sources? And the manual of one of the boards in your computer? - - -Addresses and interrupts -======================== - -Address dip switch settings: -The dip switch sets bits 2-9 of the IO address. - - 9 8 7 6 5 4 3 2 - +-----------------+ - 0 | X X X X X X X | - | | = IoBase = 0x100 - 1 | X | - +-----------------+ ------ RS232 connectors ----> - - | | | - edge connector - | | | - V V V - -Base address 0x100 caused a conflict in one of my computers once. I -haven't the foggiest why. My Specialix card is now at 0x180. My -other computer runs just fine with the Specialix card at 0x100.... -The card occupies 4 addresses, but actually only two are really used. - -The PCI version doesn't have any dip switches. The BIOS assigns -an IO address. - -The driver now still autoprobes at 0x100, 0x180, 0x250 and 0x260. If -that causes trouble for you, please report that. I'll remove -autoprobing then. - -The driver will tell the card what IRQ to use, so you don't have to -change any jumpers to change the IRQ. Just use a command line -argument (irq=xx) to the insmod program to set the interrupt. - -The BIOS assigns the IRQ on the PCI version. You have no say in what -IRQ to use in that case. - -If your specialix cards are not at the default locations, you can use -the kernel command line argument "specialix=io0,irq0,io1,irq1...". -Here "io0" is the io address for the first card, and "irq0" is the -irq line that the first card should use. And so on. - -Examples. - -You use the driver as a module and have three cards at 0x100, 0x250 -and 0x180. And some way or another you want them detected in that -order. Moreover irq 12 is taken (e.g. by your PS/2 mouse). - - insmod specialix.o iobase=0x100,0x250,0x180 irq=9,11,15 - -The same three cards, but now in the kernel would require you to -add - - specialix=0x100,9,0x250,11,0x180,15 - -to the command line. This would become - - append="specialix=0x100,9,0x250,11,0x180,15" - -in your /etc/lilo.conf file if you use lilo. - -The Specialix driver is slightly odd: It allows you to have the second -or third card detected without having a first card. This has -advantages and disadvantages. A slot that isn't filled by an ISA card, -might be filled if a PCI card is detected. Thus if you have an ISA -card at 0x250 and a PCI card, you would get: - -sx0: specialix IO8+ Board at 0x100 not found. -sx1: specialix IO8+ Board at 0x180 not found. -sx2: specialix IO8+ board detected at 0x250, IRQ 12, CD1865 Rev. B. -sx3: specialix IO8+ Board at 0x260 not found. -sx0: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B. - -This would happen if you don't give any probe hints to the driver. -If you would specify: - - specialix=0x250,11 - -you'd get the following messages: - -sx0: specialix IO8+ board detected at 0x250, IRQ 11, CD1865 Rev. B. -sx1: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B. - -ISA probing is aborted after the IO address you gave is exhausted, and -the PCI card is now detected as the second card. The ISA card is now -also forced to IRQ11.... - - -Baud rates -========== - -The rev 1.2 and below boards use a CL-CD1864. These chips can only -do 64kbit. The rev 1.3 and newer boards use a CL-CD1865. These chips -are officially capable of 115k2. - -The Specialix card uses a 25MHz crystal (in times two mode, which in -fact is a divided by two mode). This is not enough to reach the rated -115k2 on all ports at the same time. With this clock rate you can only -do 37% of this rate. This means that at 115k2 on all ports you are -going to lose characters (The chip cannot handle that many incoming -bits at this clock rate.) (Yes, you read that correctly: there is a -limit to the number of -=bits=- per second that the chip can handle.) - -If you near the "limit" you will first start to see a graceful -degradation in that the chip cannot keep the transmitter busy at all -times. However with a central clock this slow, you can also get it to -miss incoming characters. The driver will print a warning message when -you are outside the official specs. The messages usually show up in -the file /var/log/messages . - -The specialix card cannot reliably do 115k2. If you use it, you have -to do "extensive testing" (*) to verify if it actually works. - -When "mgetty" communicates with my modem at 115k2 it reports: -got: +++[0d]ATQ0V1H0[0d][0d][8a]O[cb][0d][8a] - ^^^^ ^^^^ ^^^^ - -The three characters that have the "^^^" under them have suffered a -bit error in the highest bit. In conclusion: I've tested it, and found -that it simply DOESN'T work for me. I also suspect that this is also -caused by the baud rate being just a little bit out of tune. - -I upgraded the crystal to 66Mhz on one of my Specialix cards. Works -great! Contact me for details. (Voids warranty, requires a steady hand -and more such restrictions....) - - -(*) Cirrus logic CD1864 databook, page 40. - - -Cables for the Specialix IO8+ -============================= - -The pinout of the connectors on the IO8+ is: - - pin short direction long name - name - Pin 1 DCD input Data Carrier Detect - Pin 2 RXD input Receive - Pin 3 DTR/RTS output Data Terminal Ready/Ready To Send - Pin 4 GND - Ground - Pin 5 TXD output Transmit - Pin 6 CTS input Clear To Send - - - -- 6 5 4 3 2 1 -- - | | - | | - | | - | | - +----- -----+ - |__________| - clip - - Front view of an RJ12 connector. Cable moves "into" the paper. - (the plug is ready to plug into your mouth this way...) - - - NULL cable. I don't know who is going to use these except for - testing purposes, but I tested the cards with this cable. (It - took quite a while to figure out, so I'm not going to delete - it. So there! :-) - - - This end goes This end needs - straight into the some twists in - RJ12 plug. the wiring. - IO8+ RJ12 IO8+ RJ12 - 1 DCD white - - - - 1 DCD - 2 RXD black 5 TXD - 3 DTR/RTS red 6 CTS - 4 GND green 4 GND - 5 TXD yellow 2 RXD - 6 CTS blue 3 DTR/RTS - - - Same NULL cable, but now sorted on the second column. - - 1 DCD white - - - - 1 DCD - 5 TXD yellow 2 RXD - 6 CTS blue 3 DTR/RTS - 4 GND green 4 GND - 2 RXD black 5 TXD - 3 DTR/RTS red 6 CTS - - - - This is a modem cable usable for hardware handshaking: - RJ12 DB25 DB9 - 1 DCD white 8 DCD 1 DCD - 2 RXD black 3 RXD 2 RXD - 3 DTR/RTS red 4 RTS 7 RTS - 4 GND green 7 GND 5 GND - 5 TXD yellow 2 TXD 3 TXD - 6 CTS blue 5 CTS 8 CTS - +---- 6 DSR 6 DSR - +---- 20 DTR 4 DTR - - This is a modem cable usable for software handshaking: - It allows you to reset the modem using the DTR ioctls. - I (REW) have never tested this, "but xxxxxxxxxxxxx - says that it works." If you test this, please - tell me and I'll fill in your name on the xxx's. - - RJ12 DB25 DB9 - 1 DCD white 8 DCD 1 DCD - 2 RXD black 3 RXD 2 RXD - 3 DTR/RTS red 20 DTR 4 DTR - 4 GND green 7 GND 5 GND - 5 TXD yellow 2 TXD 3 TXD - 6 CTS blue 5 CTS 8 CTS - +---- 6 DSR 6 DSR - +---- 4 RTS 7 RTS - - I bought a 6 wire flat cable. It was colored as indicated. - Check that yours is the same before you trust me on this. - - -Hardware handshaking issues. -============================ - -The driver can be told to operate in two different ways. The default -behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when -hardware handshaking is off. It behaves as the RTS hardware -handshaking signal when hardware handshaking is selected. - -When you use this, you have to use the appropriate cable. The -cable will either be compatible with hardware handshaking or with -software handshaking. So switching on the fly is not really an -option. - -I actually prefer to use the "specialix.sx_rtscts=1" option. -This makes the DTR/RTS pin always an RTS pin, and ioctls to -change DTR are always ignored. I have a cable that is configured -for this. - - -Ports and devices -================= - -Port 0 is the one furthest from the card-edge connector. - -Devices: - -You should make the devices as follows: - -bash -cd /dev -for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \ - 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -do - echo -n "$i " - mknod /dev/ttyW$i c 75 $i - mknod /dev/cuw$i c 76 $i -done -echo "" - -If your system doesn't come with these devices preinstalled, bug your -linux-vendor about this. They have had ample time to get this -implemented by now. - -You cannot have more than 4 boards in one computer. The card only -supports 4 different interrupts. If you really want this, contact me -about this and I'll give you a few tips (requires soldering iron).... - -If you have enough PCI slots, you can probably use more than 4 PCI -versions of the card though.... - -The PCI version of the card cannot adhere to the mechanical part of -the PCI spec because the 8 serial connectors are simply too large. If -it doesn't fit in your computer, bring back the card. - - ------------------------------------------------------------------------- - - - Fixed bugs and restrictions: - - During initialization, interrupts are blindly turned on. - Having a shadow variable would cause an extra memory - access on every IO instruction. - - The interrupt (on the card) should be disabled when we - don't allocate the Linux end of the interrupt. This allows - a different driver/card to use it while all ports are not in - use..... (a la standard serial port) - == An extra _off variant of the sx_in and sx_out macros are - now available. They don't set the interrupt enable bit. - These are used during initialization. Normal operation uses - the old variant which enables the interrupt line. - - RTS/DTR issue needs to be implemented according to - specialix' spec. - I kind of like the "determinism" of the current - implementation. Compile time flag? - == Ok. Compile time flag! Default is how Specialix likes it. - == Now a config time flag! Gets saved in your config file. Neat! - - Can you set the IO address from the lilo command line? - If you need this, bug me about it, I'll make it. - == Hah! No bugging needed. Fixed! :-) - - Cirrus logic hasn't gotten back to me yet why the CD1865 can - and the CD1864 can't do 115k2. I suspect that this is - because the CD1864 is not rated for 33MHz operation. - Therefore the CD1864 versions of the card can't do 115k2 on - all ports just like the CD1865 versions. The driver does - not block 115k2 on CD1864 cards. - == I called the Cirrus Logic representative here in Holland. - The CD1864 databook is identical to the CD1865 databook, - except for an extra warning at the end. Similar Bit errors - have been observed in testing at 115k2 on both an 1865 and - a 1864 chip. I see no reason why I would prohibit 115k2 on - 1864 chips and not do it on 1865 chips. Actually there is - reason to prohibit it on BOTH chips. I print a warning. - If you use 115k2, you're on your own. - - A spiky CD may send spurious HUPs. Also in CLOCAL??? - -- A fix for this turned out to be counter productive. - Different fix? Current behaviour is acceptable? - -- Maybe the current implementation is correct. If anybody - gets bitten by this, please report, and it will get fixed. - - -- Testing revealed that when in CLOCAL, the problem doesn't - occur. As warned for in the CD1865 manual, the chip may - send modem intr's on a spike. We could filter those out, - but that would be a cludge anyway (You'd still risk getting - a spurious HUP when two spikes occur.)..... - - - - Bugs & restrictions: - - This is a difficult card to autoprobe. - You have to WRITE to the address register to even - read-probe a CD186x register. Disable autodetection? - -- Specialix: any suggestions? - - diff --git a/Documentation/serial/sx.txt b/Documentation/serial/sx.txt deleted file mode 100644 index cb4efa0fb5cc..000000000000 --- a/Documentation/serial/sx.txt +++ /dev/null @@ -1,294 +0,0 @@ - - sx.txt -- specialix SX/SI multiport serial driver readme. - - - - Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl) - - Specialix pays for the development and support of this driver. - Please DO contact support@specialix.co.uk if you require - support. - - This driver was developed in the BitWizard linux device - driver service. If you require a linux device driver for your - product, please contact devices@BitWizard.nl for a quote. - - (History) - There used to be an SI driver by Simon Allan. This is a complete - rewrite from scratch. Just a few lines-of-code have been snatched. - - (Sources) - Specialix document number 6210028: SX Host Card and Download Code - Software Functional Specification. - - (Copying) - 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. - - 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., 675 Mass Ave, Cambridge, MA 02139, - USA. - - (Addendum) - I'd appreciate it that if you have fixes, that you send them - to me first. - - -Introduction -============ - -This file contains some random information, that I like to have online -instead of in a manual that can get lost. Ever misplace your Linux -kernel sources? And the manual of one of the boards in your computer? - - -Theory of operation -=================== - -An important thing to know is that the driver itself doesn't have the -firmware for the card. This means that you need the separate package -"sx_firmware". For now you can get the source at - - ftp://ftp.bitwizard.nl/specialix/sx_firmware_.tgz - -The firmware load needs a "misc" device, so you'll need to enable the -"Support for user misc device modules" in your kernel configuration. -The misc device needs to be called "/dev/specialix_sxctl". It needs -misc major 10, and minor number 167 (assigned by HPA). The section -on creating device files below also creates this device. - -After loading the sx.o module into your kernel, the driver will report -the number of cards detected, but because it doesn't have any -firmware, it will not be able to determine the number of ports. Only -when you then run "sx_firmware" will the firmware be downloaded and -the rest of the driver initialized. At that time the sx_firmware -program will report the number of ports installed. - -In contrast with many other multi port serial cards, some of the data -structures are only allocated when the card knows the number of ports -that are connected. This means we won't waste memory for 120 port -descriptor structures when you only have 8 ports. If you experience -problems due to this, please report them: I haven't seen any. - - -Interrupts -========== - -A multi port serial card, would generate a horrendous amount of -interrupts if it would interrupt the CPU for every received -character. Even more than 10 years ago, the trick not to use -interrupts but to poll the serial cards was invented. - -The SX card allow us to do this two ways. First the card limits its -own interrupt rate to a rate that won't overwhelm the CPU. Secondly, -we could forget about the cards interrupt completely and use the -internal timer for this purpose. - -Polling the card can take up to a few percent of your CPU. Using the -interrupts would be better if you have most of the ports idle. Using -timer-based polling is better if your card almost always has work to -do. You save the separate interrupt in that case. - -In any case, it doesn't really matter all that much. - -The most common problem with interrupts is that for ISA cards in a PCI -system the BIOS has to be told to configure that interrupt as "legacy -ISA". Otherwise the card can pull on the interrupt line all it wants -but the CPU won't see this. - -If you can't get the interrupt to work, remember that polling mode is -more efficient (provided you actually use the card intensively). - - -Allowed Configurations -====================== - -Some configurations are disallowed. Even though at a glance they might -seem to work, they are known to lockup the bus between the host card -and the device concentrators. You should respect the drivers decision -not to support certain configurations. It's there for a reason. - -Warning: Seriously technical stuff ahead. Executive summary: Don't use -SX cards except configured at a 64k boundary. Skip the next paragraph. - -The SX cards can theoretically be placed at a 32k boundary. So for -instance you can put an SX card at 0xc8000-0xd7fff. This is not a -"recommended configuration". ISA cards have to tell the bus controller -how they like their timing. Due to timing issues they have to do this -based on which 64k window the address falls into. This means that the -32k window below and above the SX card have to use exactly the same -timing as the SX card. That reportedly works for other SX cards. But -you're still left with two useless 32k windows that should not be used -by anybody else. - - -Configuring the driver -====================== - -PCI cards are always detected. The driver auto-probes for ISA cards at -some sensible addresses. Please report if the auto-probe causes trouble -in your system, or when a card isn't detected. - -I'm afraid I haven't implemented "kernel command line parameters" yet. -This means that if the default doesn't work for you, you shouldn't use -the compiled-into-the-kernel version of the driver. Use a module -instead. If you convince me that you need this, I'll make it for -you. Deal? - -I'm afraid that the module parameters are a bit clumsy. If you have a -better idea, please tell me. - -You can specify several parameters: - - sx_poll: number of jiffies between timer-based polls. - - Set this to "0" to disable timer based polls. - Initialization of cards without a working interrupt - will fail. - - Set this to "1" if you want a polling driver. - (on Intel: 100 polls per second). If you don't use - fast baud rates, you might consider a value like "5". - (If you don't know how to do the math, use 1). - - sx_slowpoll: Number of jiffies between timer-based polls. - Set this to "100" to poll once a second. - This should get the card out of a stall if the driver - ever misses an interrupt. I've never seen this happen, - and if it does, that's a bug. Tell me. - - sx_maxints: Number of interrupts to request from the card. - The card normally limits interrupts to about 100 per - second to offload the host CPU. You can increase this - number to reduce latency on the card a little. - Note that if you give a very high number you can overload - your CPU as well as the CPU on the host card. This setting - is inaccurate and not recommended for SI cards (But it - works). - - sx_irqmask: The mask of allowable IRQs to use. I suggest you set - this to 0 (disable IRQs all together) and use polling if - the assignment of IRQs becomes problematic. This is defined - as the sum of (1 << irq) 's that you want to allow. So - sx_irqmask of 8 (1 << 3) specifies that only irq 3 may - be used by the SX driver. If you want to specify to the - driver: "Either irq 11 or 12 is ok for you to use", then - specify (1 << 11) | (1 << 12) = 0x1800 . - - sx_debug: You can enable different sorts of debug traces with this. - At "-1" all debugging traces are active. You'll get several - times more debugging output than you'll get characters - transmitted. - - -Baud rates -========== - -Theoretically new SXDCs should be capable of more than 460k -baud. However the line drivers usually give up before that. Also the -CPU on the card may not be able to handle 8 channels going at full -blast at that speed. Moreover, the buffers are not large enough to -allow operation with 100 interrupts per second. You'll have to realize -that the card has a 256 byte buffer, so you'll have to increase the -number of interrupts per second if you have more than 256*100 bytes -per second to transmit. If you do any performance testing in this -area, I'd be glad to hear from you... - -(Psst Linux users..... I think the Linux driver is more efficient than -the driver for other OSes. If you can and want to benchmark them -against each other, be my guest, and report your findings...... :-) - - -Ports and devices -================= - -Port 0 is the top connector on the module closest to the host -card. Oh, the ports on the SXDCs and TAs are labelled from 1 to 8 -instead of from 0 to 7, as they are numbered by linux. I'm stubborn in -this: I know for sure that I wouldn't be able to calculate which port -is which anymore if I would change that.... - - -Devices: - -You should make the device files as follows: - -#!/bin/sh -# (I recommend that you cut-and-paste this into a file and run that) -cd /dev -t=0 -mknod specialix_sxctl c 10 167 -while [ $t -lt 64 ] - do - echo -n "$t " - mknod ttyX$t c 32 $t - mknod cux$t c 33 $t - t=`expr $t + 1` -done -echo "" -rm /etc/psdevtab -ps > /dev/null - - -This creates 64 devices. If you have more, increase the constant on -the line with "while". The devices start at 0, as is customary on -Linux. Specialix seems to like starting the numbering at 1. - -If your system doesn't come with these devices pre-installed, bug your -linux-vendor about this. They should have these devices -"pre-installed" before the new millennium. The "ps" stuff at the end -is to "tell" ps that the new devices exist. - -Officially the maximum number of cards per computer is 4. This driver -however supports as many cards in one machine as you want. You'll run -out of interrupts after a few, but you can switch to polled operation -then. At about 256 ports (More than 8 cards), we run out of minor -device numbers. Sorry. I suggest you buy a second computer.... (Or -switch to RIO). - ------------------------------------------------------------------------- - - - Fixed bugs and restrictions: - - Hangup processing. - -- Done. - - - the write path in generic_serial (lockup / oops). - -- Done (Ugly: not the way I want it. Copied from serial.c). - - - write buffer isn't flushed at close. - -- Done. I still seem to lose a few chars at close. - Sorry. I think that this is a firmware issue. (-> Specialix) - - - drain hardware before changing termios - - Change debug on the fly. - - ISA free irq -1. (no firmware loaded). - - adding c8000 as a probe address. Added warning. - - Add a RAMtest for the RAM on the card.c - - Crash when opening a port "way" of the number of allowed ports. - (for example opening port 60 when there are only 24 ports attached) - - Sometimes the use-count strays a bit. After a few hours of - testing the use count is sometimes "3". If you are not like - me and can remember what you did to get it that way, I'd - appreciate an Email. Possibly fixed. Tell me if anyone still - sees this. - - TAs don't work right if you don't connect all the modem control - signals. SXDCs do. T225 firmware problem -> Specialix. - (Mostly fixed now, I think. Tell me if you encounter this!) - - Bugs & restrictions: - - - Arbitrary baud rates. Requires firmware update. (-> Specialix) - - - Low latency (mostly firmware, -> Specialix) - - - diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt index 2ebe539f5450..dfb72a5c63e9 100644 --- a/Documentation/zh_CN/magic-number.txt +++ b/Documentation/zh_CN/magic-number.txt @@ -63,8 +63,6 @@ struct tty_ldisc { PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h CMAGIC 0x0111 user include/linux/a.out.h MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h -RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h -SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h @@ -82,7 +80,6 @@ STRIP_MAGIC 0x5303 strip drivers/net/strip.c X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h -ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h TTY_MAGIC 0x5401 tty_struct include/linux/tty.h MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h @@ -94,13 +91,10 @@ USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h -A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h LSEMAGIC 0x05091998 lse drivers/fc4/fc.c GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c -RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c -SX_MAGIC 0x12345678 gs_port drivers/char/sx.h NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h RED_MAGIC2 0x170fc2a5 (any) mm/slab.c BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c @@ -116,7 +110,6 @@ ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c -STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c @@ -127,10 +120,8 @@ SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h RED_MAGIC1 0x5a2cf071 (any) mm/slab.c -STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h -EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c @@ -142,17 +133,14 @@ SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c -STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h -STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h -STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c diff --git a/firmware/WHENCE b/firmware/WHENCE index 8388f02de2bd..0c4d96dee9b6 100644 --- a/firmware/WHENCE +++ b/firmware/WHENCE @@ -273,16 +273,6 @@ Converted from Intel HEX files, used in our binary representation of ihex. -------------------------------------------------------------------------- -Driver: ip2 -- Computone IntelliPort Plus serial device - -File: intelliport2.bin - -Licence: Unknown - -Found in hex form in kernel source. - --------------------------------------------------------------------------- - Driver: CPiA2 -- cameras based on Vision's CPiA2 File: cpia2/stv0672_vp4.bin -- GitLab From f4f653e9875e573860e783fecbebde284a8626f5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 1 Apr 2014 13:37:00 +0200 Subject: [PATCH 417/797] serial: 8250, disable "too much work" messages The 8250 driver now reports many of these: serial8250: too much work for irq4 These messages turned out to be common these days with a use of virtualization. I tried to increase the limit of processed characters in commit e7328ae1848966181a7ac47e8ae6cddbd2cf55f3 (serial: 8250, increase PASS_LIMIT) in 2011. It was raised from 256 to 512, but it is still not enough, apparently. So disable the warning unless somebody turns on DEBUG (or DYNAMIC_DEBUG _and_ the message). Signed-off-by: Jiri Slaby Reported-by: Martin Pluskal Reported-by: Takashi Iwai Tested-by: Takashi Iwai References: https://bugzilla.novell.com/show_bug.cgi?id=868394 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 81f909c2101f..139ab1997e06 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1601,8 +1601,7 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) l = l->next; if (l == i->head && pass_counter++ > PASS_LIMIT) { - /* If we hit this, we're dead. */ - printk_ratelimited(KERN_ERR + pr_debug_ratelimited( "serial8250: too much work for irq%d\n", irq); break; } -- GitLab From 7d1c2858c49095ab748f55354b89dbd6b18d28b9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Apr 2014 14:45:21 +0200 Subject: [PATCH 418/797] ttyprintk: Fix wrong tty_unregister_driver() call in the error path ttyprintk driver calls tty_unregister_driver() wrongly in the error path of tty_register_driver(). Also, setting ttyprintk_driver to NULL is utterly superfluous, so let's get rid of it, too. Reported-by: Jean Delvare Reviewed-by: Jean Delvare Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/char/ttyprintk.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index daea84c41743..2a39c5790364 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -210,10 +210,8 @@ static int __init ttyprintk_init(void) return 0; error: - tty_unregister_driver(ttyprintk_driver); put_tty_driver(ttyprintk_driver); tty_port_destroy(&tpk_port.port); - ttyprintk_driver = NULL; return ret; } device_initcall(ttyprintk_init); -- GitLab From b24313a82cf24e90170671ea74360b3e6ef3a91f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 2 Apr 2014 14:45:22 +0200 Subject: [PATCH 419/797] ttyprintk: Allow built as a module The driver is well written to be used as a module, just the exit call is missing. Reviewed-by: Jean Delvare Signed-off-by: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/char/Kconfig | 2 +- drivers/char/ttyprintk.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index fbae63e3d304..6e9f74a5c095 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -40,7 +40,7 @@ config SGI_MBCS source "drivers/tty/serial/Kconfig" config TTY_PRINTK - bool "TTY driver to output user messages via printk" + tristate "TTY driver to output user messages via printk" depends on EXPERT && TTY default n ---help--- diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 2a39c5790364..a15ce4ef39cd 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include struct ttyprintk_port { struct tty_port port; @@ -214,4 +214,15 @@ static int __init ttyprintk_init(void) tty_port_destroy(&tpk_port.port); return ret; } + +static void __exit ttyprintk_exit(void) +{ + tty_unregister_driver(ttyprintk_driver); + put_tty_driver(ttyprintk_driver); + tty_port_destroy(&tpk_port.port); +} + device_initcall(ttyprintk_init); +module_exit(ttyprintk_exit); + +MODULE_LICENSE("GPL"); -- GitLab From c70dbb1e79a1ac2802b4b7b6de7456b230fbbbeb Mon Sep 17 00:00:00 2001 From: Chen Tingjie Date: Tue, 15 Apr 2014 11:52:51 +0800 Subject: [PATCH 420/797] tty: fix memleak in alloc_pid There is memleak in alloc_pid: ------------------------------ unreferenced object 0xd3453a80 (size 64): comm "adbd", pid 1730, jiffies 66363 (age 6586.950s) hex dump (first 32 bytes): 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 40 c2 f6 d5 00 d3 25 c1 59 28 00 00 ....@.....%.Y(.. backtrace: [] kmemleak_alloc+0x3c/0xa0 [] kmem_cache_alloc+0xc6/0x190 [] alloc_pid+0x1e/0x400 [] copy_process.part.39+0xad4/0x1120 [] do_fork+0x99/0x330 [] sys_fork+0x28/0x30 [] syscall_call+0x7/0xb [] 0xffffffff the leak is due to unreleased pid->count, which execute in function: get_pid()(pid->count++) and put_pid()(pid->count--). The race condition as following: task[dumpsys] task[adbd] in disassociate_ctty() in tty_signal_session_leader() ----------------------- ------------------------- tty = get_current_tty(); // tty is not NULL ... spin_lock_irq(¤t->sighand->siglock); put_pid(current->signal->tty_old_pgrp); current->signal->tty_old_pgrp = NULL; spin_unlock_irq(¤t->sighand->siglock); spin_lock_irq(&p->sighand->siglock); ... p->signal->tty = NULL; ... spin_unlock_irq(&p->sighand->siglock); tty = get_current_tty(); // tty NULL, goto else branch by accident. if (tty) { ... put_pid(tty_session); put_pid(tty_pgrp); ... } else { print msg } in task[dumpsys], in disassociate_ctty(), tty is set NULL by task[adbd], tty_signal_session_leader(), then it goto else branch and lack of put_pid(), cause memleak. move spin_unlock(sighand->siglock) after get_current_tty() can avoid the race and fix the memleak. Signed-off-by: Zhang Jun Signed-off-by: Chen Tingjie 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 d3448a90f0f9..34110719fe03 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -878,9 +878,8 @@ void disassociate_ctty(int on_exit) spin_lock_irq(¤t->sighand->siglock); put_pid(current->signal->tty_old_pgrp); current->signal->tty_old_pgrp = NULL; - spin_unlock_irq(¤t->sighand->siglock); - tty = get_current_tty(); + tty = tty_kref_get(current->signal->tty); if (tty) { unsigned long flags; spin_lock_irqsave(&tty->ctrl_lock, flags); @@ -897,6 +896,7 @@ void disassociate_ctty(int on_exit) #endif } + spin_unlock_irq(¤t->sighand->siglock); /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); session_clear_tty(task_session(current)); -- GitLab From 9ca83fd2d5805a5e4608a901ffa802697adc638b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 14 Apr 2014 18:32:13 +0200 Subject: [PATCH 421/797] tty: Fix help text of SYNCLINK_CS Enabling SYNCLINK_CS as a module builds synclink_cs, not synclinkmp. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/char/pcmcia/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig index b27f5342fe76..8d3dfb0c8a26 100644 --- a/drivers/char/pcmcia/Kconfig +++ b/drivers/char/pcmcia/Kconfig @@ -15,7 +15,7 @@ config SYNCLINK_CS This driver may be built as a module ( = code which can be inserted in and removed from the running kernel whenever you want). - The module will be called synclinkmp. If you want to do that, say M + The module will be called synclink_cs. If you want to do that, say M here. config CARDMAN_4000 -- GitLab From 1e7da0530423a232747d64c2113ace55b01e5754 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sat, 5 Apr 2014 16:31:08 +0200 Subject: [PATCH 422/797] serial: amba-pl011: fix regression, causing an Oops on rmmod A recent commit ef2889f7ffee67f0aed49e854c72be63f1466759 "serial: pl011: Move uart_register_driver call to device probe" introduced a regression, causing the pl011 driver to Oops if more than 1 port have been probed. Fix the Oops by only calling uart_unregister_driver() once after the last port has been removed. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index ca0ec600fab6..dacf0a09ab24 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -2176,6 +2176,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) static int pl011_remove(struct amba_device *dev) { struct uart_amba_port *uap = amba_get_drvdata(dev); + bool busy = false; int i; uart_remove_one_port(&amba_reg, &uap->port); @@ -2183,9 +2184,12 @@ static int pl011_remove(struct amba_device *dev) for (i = 0; i < ARRAY_SIZE(amba_ports); i++) if (amba_ports[i] == uap) amba_ports[i] = NULL; + else if (amba_ports[i]) + busy = true; pl011_dma_remove(uap); - uart_unregister_driver(&amba_reg); + if (!busy) + uart_unregister_driver(&amba_reg); return 0; } -- GitLab From 0e1f789d0dc38db79dfc4ddfd9cf541a8c198b7a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 17 Apr 2014 08:15:19 +1000 Subject: [PATCH 423/797] xfs: don't map ranges that span EOF for direct IO Al Viro tracked down the problem that has caused generic/263 to fail on XFS since the test was introduced. If is caused by xfs_get_blocks() mapping a single extent that spans EOF without marking it as buffer-new() so that the direct IO code does not zero the tail of the block at the new EOF. This is a long standing bug that has been around for many, many years. Because xfs_get_blocks() starts the map before EOF, it can't set buffer_new(), because that causes he direct IO code to also zero unaligned sectors at the head of the IO. This would overwrite valid data with zeros, and hence we cannot validly return a single extent that spans EOF to direct IO. Fix this by detecting a mapping that spans EOF and truncate it down to EOF. This results in the the direct IO code doing the right thing for unaligned data blocks before EOF, and then returning to get another mapping for the region beyond EOF which XFS treats correctly by setting buffer_new() on it. This makes direct Io behave correctly w.r.t. tail block zeroing beyond EOF, and fsx is happy about that. Again, thanks to Al Viro for finding what I couldn't. [ dchinner: Fix for __divdi3 build error: Reported-by: Paul Gortmaker Tested-by: Paul Gortmaker Signed-off-by: Mark Tinguely Reviewed-by: Eric Sandeen ] Signed-off-by: Dave Chinner Tested-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e0a793113ea9..0479c32c5eb1 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1344,6 +1344,14 @@ __xfs_get_blocks( /* * If this is O_DIRECT or the mpage code calling tell them how large * the mapping is, so that we can avoid repeated get_blocks calls. + * + * If the mapping spans EOF, then we have to break the mapping up as the + * mapping for blocks beyond EOF must be marked new so that sub block + * regions can be correctly zeroed. We can't do this for mappings within + * EOF unless the mapping was just allocated or is unwritten, otherwise + * the callers would overwrite existing data with zeros. Hence we have + * to split the mapping into a range up to and including EOF, and a + * second mapping for beyond EOF. */ if (direct || size > (1 << inode->i_blkbits)) { xfs_off_t mapping_size; @@ -1354,6 +1362,12 @@ __xfs_get_blocks( ASSERT(mapping_size > 0); if (mapping_size > size) mapping_size = size; + if (offset < i_size_read(inode) && + offset + mapping_size >= i_size_read(inode)) { + /* limit mapping to block that spans EOF */ + mapping_size = roundup_64(i_size_read(inode) - offset, + 1 << inode->i_blkbits); + } if (mapping_size > LONG_MAX) mapping_size = LONG_MAX; -- GitLab From d39a2ced0fa0172faa46df0866fc22419b876e2a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 17 Apr 2014 08:15:25 +1000 Subject: [PATCH 424/797] xfs: collapse range is delalloc challenged FSX has been detecting data corruption after to collapse range calls. The key observation is that the offset of the last extent in the file was not being shifted, and hence when the file size was adjusted it was truncating away data because the extents handled been correctly shifted. Tracing indicated that before the collapse, the extent list looked like: .... ino 0x5788 state idx 6 offset 26 block 195904 count 10 flag 0 ino 0x5788 state idx 7 offset 39 block 195917 count 35 flag 0 ino 0x5788 state idx 8 offset 86 block 195964 count 32 flag 0 and after the shift of 2 blocks: ino 0x5788 state idx 6 offset 24 block 195904 count 10 flag 0 ino 0x5788 state idx 7 offset 37 block 195917 count 35 flag 0 ino 0x5788 state idx 8 offset 86 block 195964 count 32 flag 0 Note that the last extent did not change offset. After the changing of the file size: ino 0x5788 state idx 6 offset 24 block 195904 count 10 flag 0 ino 0x5788 state idx 7 offset 37 block 195917 count 35 flag 0 ino 0x5788 state idx 8 offset 86 block 195964 count 30 flag 0 You can see that the last extent had it's length truncated, indicating that we've lost data. The reason for this is that the xfs_bmap_shift_extents() loop uses XFS_IFORK_NEXTENTS() to determine how many extents are in the inode. This, unfortunately, doesn't take into account delayed allocation extents - it's a count of physically allocated extents - and hence when the file being collapsed has a delalloc extent like this one does prior to the range being collapsed: .... ino 0x5788 state idx 4 offset 11 block 4503599627239429 count 1 flag 0 .... it gets the count wrong and terminates the shift loop early. Fix it by using the in-memory extent array size that includes delayed allocation extents to determine the number of extents on the inode. Signed-off-by: Dave Chinner Tested-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_bmap.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 5b6092ef51ef..f0efc7e970ef 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -5413,6 +5413,7 @@ xfs_bmap_shift_extents( int whichfork = XFS_DATA_FORK; int logflags; xfs_filblks_t blockcount = 0; + int total_extents; if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -5429,7 +5430,6 @@ xfs_bmap_shift_extents( ASSERT(current_ext != NULL); ifp = XFS_IFORK_PTR(ip, whichfork); - if (!(ifp->if_flags & XFS_IFEXTENTS)) { /* Read in all the extents */ error = xfs_iread_extents(tp, ip, whichfork); @@ -5456,7 +5456,6 @@ xfs_bmap_shift_extents( /* We are going to change core inode */ logflags = XFS_ILOG_CORE; - if (ifp->if_flags & XFS_IFBROOT) { cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork); cur->bc_private.b.firstblock = *firstblock; @@ -5467,8 +5466,14 @@ xfs_bmap_shift_extents( logflags |= XFS_ILOG_DEXT; } - while (nexts++ < num_exts && - *current_ext < XFS_IFORK_NEXTENTS(ip, whichfork)) { + /* + * There may be delalloc extents in the data fork before the range we + * are collapsing out, so we cannot + * use the count of real extents here. Instead we have to calculate it + * from the incore fork. + */ + total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); + while (nexts++ < num_exts && *current_ext < total_extents) { gotp = xfs_iext_get_ext(ifp, *current_ext); xfs_bmbt_get_all(gotp, &got); @@ -5556,10 +5561,11 @@ xfs_bmap_shift_extents( } (*current_ext)++; + total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t); } /* Check if we are done */ - if (*current_ext == XFS_IFORK_NEXTENTS(ip, whichfork)) + if (*current_ext == total_extents) *done = 1; del_cursor: @@ -5568,6 +5574,5 @@ xfs_bmap_shift_extents( error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); xfs_trans_log_inode(tp, ip, logflags); - return error; } -- GitLab From 9c23eccc1e746f64b18fab070a37189b4422e44a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 17 Apr 2014 08:15:26 +1000 Subject: [PATCH 425/797] xfs: unmount does not wait for shutdown during unmount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit And interesting situation can occur if a log IO error occurs during the unmount of a filesystem. The cases reported have the same signature - the update of the superblock counters fails due to a log write IO error: XFS (dm-16): xfs_do_force_shutdown(0x2) called from line 1170 of file fs/xfs/xfs_log.c. Return address = 0xffffffffa08a44a1 XFS (dm-16): Log I/O Error Detected. Shutting down filesystem XFS (dm-16): Unable to update superblock counters. Freespace may not be correct on next mount. XFS (dm-16): xfs_log_force: error 5 returned. XFS (¿-¿¿¿): Please umount the filesystem and rectify the problem(s) It can be seen that the last line of output contains a corrupt device name - this is because the log and xfs_mount structures have already been freed by the time this message is printed. A kernel oops closely follows. The issue is that the shutdown is occurring in a separate IO completion thread to the unmount. Once the shutdown processing has started and all the iclogs are marked with XLOG_STATE_IOERROR, the log shutdown code wakes anyone waiting on a log force so they can process the shutdown error. This wakes up the unmount code that is doing a synchronous transaction to update the superblock counters. The unmount path now sees all the iclogs are marked with XLOG_STATE_IOERROR and so never waits on them again, knowing that if it does, there will not be a wakeup trigger for it and we will hang the unmount if we do. Hence the unmount runs through all the remaining code and frees all the filesystem structures while the xlog_iodone() is still processing the shutdown. When the log shutdown processing completes, xfs_do_force_shutdown() emits the "Please umount the filesystem and rectify the problem(s)" message, and xlog_iodone() then aborts all the objects attached to the iclog. An iclog that has already been freed.... The real issue here is that there is no serialisation point between the log IO and the unmount. We have serialisations points for log writes, log forces, reservations, etc, but we don't actually have any code that wakes for log IO to fully complete. We do that for all other types of object, so why not iclogbufs? Well, it turns out that we can easily do this. We've got xfs_buf handles, and that's what everyone else uses for IO serialisation. i.e. bp->b_sema. So, lets hold iclogbufs locked over IO, and only release the lock in xlog_iodone() when we are finished with the buffer. That way before we tear down the iclog, we can lock and unlock the buffer to ensure IO completion has finished completely before we tear it down. Signed-off-by: Dave Chinner Tested-by: Mike Snitzer Tested-by: Bob Mastors Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_log.c | 53 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 8497a00e399d..08624dc67317 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1181,11 +1181,14 @@ xlog_iodone(xfs_buf_t *bp) /* log I/O is always issued ASYNC */ ASSERT(XFS_BUF_ISASYNC(bp)); xlog_state_done_syncing(iclog, aborted); + /* - * do not reference the buffer (bp) here as we could race - * with it being freed after writing the unmount record to the - * log. + * drop the buffer lock now that we are done. Nothing references + * the buffer after this, so an unmount waiting on this lock can now + * tear it down safely. As such, it is unsafe to reference the buffer + * (bp) after the unlock as we could race with it being freed. */ + xfs_buf_unlock(bp); } /* @@ -1368,8 +1371,16 @@ xlog_alloc_log( bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0); if (!bp) goto out_free_log; - bp->b_iodone = xlog_iodone; + + /* + * The iclogbuf buffer locks are held over IO but we are not going to do + * IO yet. Hence unlock the buffer so that the log IO path can grab it + * when appropriately. + */ ASSERT(xfs_buf_islocked(bp)); + xfs_buf_unlock(bp); + + bp->b_iodone = xlog_iodone; log->l_xbuf = bp; spin_lock_init(&log->l_icloglock); @@ -1398,6 +1409,9 @@ xlog_alloc_log( if (!bp) goto out_free_iclog; + ASSERT(xfs_buf_islocked(bp)); + xfs_buf_unlock(bp); + bp->b_iodone = xlog_iodone; iclog->ic_bp = bp; iclog->ic_data = bp->b_addr; @@ -1422,7 +1436,6 @@ xlog_alloc_log( iclog->ic_callback_tail = &(iclog->ic_callback); iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize; - ASSERT(xfs_buf_islocked(iclog->ic_bp)); init_waitqueue_head(&iclog->ic_force_wait); init_waitqueue_head(&iclog->ic_write_wait); @@ -1631,6 +1644,12 @@ xlog_cksum( * we transition the iclogs to IOERROR state *after* flushing all existing * iclogs to disk. This is because we don't want anymore new transactions to be * started or completed afterwards. + * + * We lock the iclogbufs here so that we can serialise against IO completion + * during unmount. We might be processing a shutdown triggered during unmount, + * and that can occur asynchronously to the unmount thread, and hence we need to + * ensure that completes before tearing down the iclogbufs. Hence we need to + * hold the buffer lock across the log IO to acheive that. */ STATIC int xlog_bdstrat( @@ -1638,6 +1657,7 @@ xlog_bdstrat( { struct xlog_in_core *iclog = bp->b_fspriv; + xfs_buf_lock(bp); if (iclog->ic_state & XLOG_STATE_IOERROR) { xfs_buf_ioerror(bp, EIO); xfs_buf_stale(bp); @@ -1645,7 +1665,8 @@ xlog_bdstrat( /* * It would seem logical to return EIO here, but we rely on * the log state machine to propagate I/O errors instead of - * doing it here. + * doing it here. Similarly, IO completion will unlock the + * buffer, so we don't do it here. */ return 0; } @@ -1847,14 +1868,28 @@ xlog_dealloc_log( xlog_cil_destroy(log); /* - * always need to ensure that the extra buffer does not point to memory - * owned by another log buffer before we free it. + * Cycle all the iclogbuf locks to make sure all log IO completion + * is done before we tear down these buffers. */ + iclog = log->l_iclog; + for (i = 0; i < log->l_iclog_bufs; i++) { + xfs_buf_lock(iclog->ic_bp); + xfs_buf_unlock(iclog->ic_bp); + iclog = iclog->ic_next; + } + + /* + * Always need to ensure that the extra buffer does not point to memory + * owned by another log buffer before we free it. Also, cycle the lock + * first to ensure we've completed IO on it. + */ + xfs_buf_lock(log->l_xbuf); + xfs_buf_unlock(log->l_xbuf); xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size)); xfs_buf_free(log->l_xbuf); iclog = log->l_iclog; - for (i=0; il_iclog_bufs; i++) { + for (i = 0; i < log->l_iclog_bufs; i++) { xfs_buf_free(iclog->ic_bp); next_iclog = iclog->ic_next; kmem_free(iclog); -- GitLab From 07d5035a289f8bebe0ea86c293b2d5412478c481 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 17 Apr 2014 08:15:27 +1000 Subject: [PATCH 426/797] xfs: wrong error sign conversion during failed DIO writes We negate the error value being returned from a generic function incorrectly. The code path that it is running in returned negative errors, so there is no need to negate it to get the correct error signs here. This was uncovered by generic/019. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 79e96ce98733..82afdcb33183 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -679,7 +679,7 @@ xfs_file_dio_aio_write( goto out; if (mapping->nrpages) { - ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping, + ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping, pos, -1); if (ret) goto out; -- GitLab From 8d6c121018bf60d631c05a4a2efc468a392b97bb Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Thu, 17 Apr 2014 08:15:28 +1000 Subject: [PATCH 427/797] xfs: fix buffer use after free on IO error When testing exhaustion of dm snapshots, the following appeared with CONFIG_DEBUG_OBJECTS_FREE enabled: ODEBUG: free active (active state 0) object type: work_struct hint: xfs_buf_iodone_work+0x0/0x1d0 [xfs] indicating that we'd freed a buffer which still had a pending reference, down this path: [ 190.867975] [] debug_check_no_obj_freed+0x22b/0x270 [ 190.880820] [] kmem_cache_free+0xd0/0x370 [ 190.892615] [] xfs_buf_free+0xe4/0x210 [xfs] [ 190.905629] [] xfs_buf_rele+0xe7/0x270 [xfs] [ 190.911770] [] xfs_trans_read_buf_map+0x7b6/0xac0 [xfs] At issue is the fact that if IO fails in xfs_buf_iorequest, we'll queue completion unconditionally, and then call xfs_buf_rele; but if IO failed, there are no IOs remaining, and xfs_buf_rele will free the bp while work is still queued. Fix this by not scheduling completion if the buffer has an error on it; run it immediately. The rest is only comment changes. Thanks to dchinner for spotting the root cause. Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster Signed-off-by: Dave Chinner --- fs/xfs/xfs_buf.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 107f2fdfe41f..cb10a0aaab3a 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -1372,21 +1372,29 @@ xfs_buf_iorequest( xfs_buf_wait_unpin(bp); xfs_buf_hold(bp); - /* Set the count to 1 initially, this will stop an I/O + /* + * Set the count to 1 initially, this will stop an I/O * completion callout which happens before we have started * all the I/O from calling xfs_buf_ioend too early. */ atomic_set(&bp->b_io_remaining, 1); _xfs_buf_ioapply(bp); - _xfs_buf_ioend(bp, 1); + /* + * If _xfs_buf_ioapply failed, we'll get back here with + * only the reference we took above. _xfs_buf_ioend will + * drop it to zero, so we'd better not queue it for later, + * or we'll free it before it's done. + */ + _xfs_buf_ioend(bp, bp->b_error ? 0 : 1); xfs_buf_rele(bp); } /* * Waits for I/O to complete on the buffer supplied. It returns immediately if - * no I/O is pending or there is already a pending error on the buffer. It - * returns the I/O error code, if any, or 0 if there was no error. + * no I/O is pending or there is already a pending error on the buffer, in which + * case nothing will ever complete. It returns the I/O error code, if any, or + * 0 if there was no error. */ int xfs_buf_iowait( -- GitLab From 330033d697ed8d296fa52b5303db9d802ad901cc Mon Sep 17 00:00:00 2001 From: Brian Foster Date: Thu, 17 Apr 2014 08:15:30 +1000 Subject: [PATCH 428/797] xfs: fix tmpfile/selinux deadlock and initialize security xfstests generic/004 reproduces an ilock deadlock using the tmpfile interface when selinux is enabled. This occurs because xfs_create_tmpfile() takes the ilock and then calls d_tmpfile(). The latter eventually calls into xfs_xattr_get() which attempts to get the lock again. E.g.: xfs_io D ffffffff81c134c0 4096 3561 3560 0x00000080 ffff8801176a1a68 0000000000000046 ffff8800b401b540 ffff8801176a1fd8 00000000001d5800 00000000001d5800 ffff8800b401b540 ffff8800b401b540 ffff8800b73a6bd0 fffffffeffffffff ffff8800b73a6bd8 ffff8800b5ddb480 Call Trace: [] schedule+0x29/0x70 [] rwsem_down_read_failed+0xc5/0x120 [] ? xfs_ilock_attr_map_shared+0x1f/0x50 [xfs] [] call_rwsem_down_read_failed+0x14/0x30 [] ? down_read_nested+0x89/0xa0 [] ? xfs_ilock+0x122/0x250 [xfs] [] xfs_ilock+0x122/0x250 [xfs] [] xfs_ilock_attr_map_shared+0x1f/0x50 [xfs] [] xfs_attr_get+0x90/0xe0 [xfs] [] xfs_xattr_get+0x37/0x50 [xfs] [] generic_getxattr+0x4f/0x70 [] inode_doinit_with_dentry+0x1ae/0x650 [] selinux_d_instantiate+0x1c/0x20 [] security_d_instantiate+0x1b/0x30 [] d_instantiate+0x50/0x70 [] d_tmpfile+0xb5/0xc0 [] xfs_create_tmpfile+0x362/0x410 [xfs] [] xfs_vn_tmpfile+0x18/0x20 [xfs] [] path_openat+0x228/0x6a0 [] ? sched_clock+0x9/0x10 [] ? kvm_clock_read+0x27/0x40 [] ? __alloc_fd+0xaf/0x1f0 [] do_filp_open+0x3a/0x90 [] ? _raw_spin_unlock+0x27/0x40 [] ? __alloc_fd+0xaf/0x1f0 [] do_sys_open+0x12e/0x210 [] SyS_open+0x1e/0x20 [] system_call_fastpath+0x16/0x1b xfs_vn_tmpfile() also fails to initialize security on the newly created inode. Pull the d_tmpfile() call up into xfs_vn_tmpfile() after the transaction has been committed and the inode unlocked. Also, initialize security on the inode based on the parent directory provided via the tmpfile call. Signed-off-by: Brian Foster Reviewed-by: Christoph Hellwig Signed-off-by: Dave Chinner --- fs/xfs/xfs_inode.c | 5 +++-- fs/xfs/xfs_inode.h | 2 +- fs/xfs/xfs_iops.c | 20 +++++++++++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 5e7a38fa6ee6..768087bedbac 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1334,7 +1334,8 @@ int xfs_create_tmpfile( struct xfs_inode *dp, struct dentry *dentry, - umode_t mode) + umode_t mode, + struct xfs_inode **ipp) { struct xfs_mount *mp = dp->i_mount; struct xfs_inode *ip = NULL; @@ -1402,7 +1403,6 @@ xfs_create_tmpfile( xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); ip->i_d.di_nlink--; - d_tmpfile(dentry, VFS_I(ip)); error = xfs_iunlink(tp, ip); if (error) goto out_trans_abort; @@ -1415,6 +1415,7 @@ xfs_create_tmpfile( xfs_qm_dqrele(gdqp); xfs_qm_dqrele(pdqp); + *ipp = ip; return 0; out_trans_abort: diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 396cc1fafd0d..f2fcde52b66d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -334,7 +334,7 @@ int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, int xfs_create(struct xfs_inode *dp, struct xfs_name *name, umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp); int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry, - umode_t mode); + umode_t mode, struct xfs_inode **ipp); int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, struct xfs_inode *ip); int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 89b07e43ca28..ef1ca010f417 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1053,11 +1053,25 @@ xfs_vn_tmpfile( struct dentry *dentry, umode_t mode) { - int error; + int error; + struct xfs_inode *ip; + struct inode *inode; - error = xfs_create_tmpfile(XFS_I(dir), dentry, mode); + error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); + if (unlikely(error)) + return -error; - return -error; + inode = VFS_I(ip); + + error = xfs_init_security(inode, dir, &dentry->d_name); + if (unlikely(error)) { + iput(inode); + return -error; + } + + d_tmpfile(dentry, inode); + + return 0; } static const struct inode_operations xfs_inode_operations = { -- GitLab From 5d6c97c55984b3b991400692f9e8568a702b93c0 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Wed, 16 Apr 2014 19:21:53 -0400 Subject: [PATCH 429/797] tracing: Do not try to recreated toplevel set_ftrace_* files With the restructing of the function tracer working with instances, the "top level" buffer is a bit special, as the function tracing is mapped to the same set of filters. This is done by using a "global_ops" descriptor and having the "set_ftrace_filter" and "set_ftrace_notrace" map to it. When an instance is created, it creates the same files but its for the local instance and not the global_ops. The issues is that the local instance creation shares some code with the global instance one and we end up trying to create th top level "set_ftrace_*" files twice, and on boot up, we get an error like this: Could not create debugfs 'set_ftrace_filter' entry Could not create debugfs 'set_ftrace_notrace' entry The reason they failed to be created was because they were created twice, and the second time gives this error as you can not create the same file twice. Reported-by: Borislav Petkov Signed-off-by: Steven Rostedt --- kernel/trace/trace_functions.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 5b781d2be383..ffd56351b521 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -58,12 +58,16 @@ int ftrace_create_function_files(struct trace_array *tr, { int ret; - /* The top level array uses the "global_ops". */ - if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) { - ret = allocate_ftrace_ops(tr); - if (ret) - return ret; - } + /* + * The top level array uses the "global_ops", and the files are + * created on boot up. + */ + if (tr->flags & TRACE_ARRAY_FL_GLOBAL) + return 0; + + ret = allocate_ftrace_ops(tr); + if (ret) + return ret; ftrace_create_filter_files(tr->ops, parent); -- GitLab From 94f8cc0eea03648e5cc5de1a4e7dc464de92cc74 Mon Sep 17 00:00:00 2001 From: Frank Rowand Date: Wed, 16 Apr 2014 17:12:30 -0700 Subject: [PATCH 430/797] drivers/base/dd.c incorrect pr_debug() parameters pr_debug() parameters are reverse order of format string Signed-off-by: Frank Rowand Signed-off-by: Greg Kroah-Hartman --- drivers/base/dd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 06051767393f..8986b9f22781 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -187,8 +187,8 @@ static void driver_bound(struct device *dev) return; } - pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev), - __func__, dev->driver->name); + pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name, + __func__, dev_name(dev)); klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices); -- GitLab From bae9f746a18ee31bbeeb25ae6615805ed6eca173 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 12:48:49 -0400 Subject: [PATCH 431/797] cifs: fix error handling cifs_user_readv Coverity says: *** CID 1202537: Dereference after null check (FORWARD_NULL) /fs/cifs/file.c: 2873 in cifs_user_readv() 2867 cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize); 2868 npages = DIV_ROUND_UP(cur_len, PAGE_SIZE); 2869 2870 /* allocate a readdata struct */ 2871 rdata = cifs_readdata_alloc(npages, 2872 cifs_uncached_readv_complete); >>> CID 1202537: Dereference after null check (FORWARD_NULL) >>> Comparing "rdata" to null implies that "rdata" might be null. 2873 if (!rdata) { 2874 rc = -ENOMEM; 2875 goto error; 2876 } 2877 2878 rc = cifs_read_allocate_pages(rdata, npages); ...when we "goto error", rc will be non-zero, and then we end up trying to do a kref_put on the rdata (which is NULL). Fix this by replacing the "goto error" with a "break". Reported-by: Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index d8ee76241b64..a875eedfd928 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2882,7 +2882,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov, cifs_uncached_readv_complete); if (!rdata) { rc = -ENOMEM; - goto error; + break; } rc = cifs_read_allocate_pages(rdata, npages); -- GitLab From 1f80c0cc39e587edd06a36b43ba3a3b09d4ac428 Mon Sep 17 00:00:00 2001 From: Michael Opdenacker Date: Tue, 15 Apr 2014 10:06:50 +0200 Subject: [PATCH 432/797] cif: fix dead code This issue was found by Coverity (CID 1202536) This proposes a fix for a statement that creates dead code. The "rc < 0" statement is within code that is run with "rc > 0". It seems like "err < 0" was meant to be used here. This way, the error code is returned by the function. Signed-off-by: Michael Opdenacker Acked-by: Al Viro Signed-off-by: Steve French --- fs/cifs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a875eedfd928..5ed03e0b8b40 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2599,7 +2599,7 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov, ssize_t err; err = generic_write_sync(file, iocb->ki_pos - rc, rc); - if (rc < 0) + if (err < 0) rc = err; } } else { -- GitLab From f7018c21350204c4cf628462f229d44d03545254 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Feb 2014 15:31:38 +0200 Subject: [PATCH 433/797] video: move fbdev to drivers/video/fbdev The drivers/video directory is a mess. It contains generic video related files, directories for backlight, console, linux logo, lots of fbdev device drivers, fbdev framework files. Make some order into the chaos by creating drivers/video/fbdev directory, and move all fbdev related files there. No functionality is changed, although I guess it is possible that some subtle Makefile build order related issue could be created by this patch. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart Acked-by: Geert Uytterhoeven Acked-by: Rob Clark Acked-by: Jingoo Han Acked-by: Daniel Vetter --- Documentation/DocBook/device-drivers.tmpl | 10 +- drivers/Makefile | 4 +- drivers/staging/xgifb/vb_def.h | 2 +- drivers/staging/xgifb/vb_struct.h | 2 +- drivers/staging/xgifb/vgatypes.h | 4 +- drivers/video/Kconfig | 2476 +---------------- drivers/video/Makefile | 166 +- drivers/video/console/sticon.c | 2 +- drivers/video/console/sticore.c | 2 +- drivers/video/{ => fbdev}/68328fb.c | 0 drivers/video/fbdev/Kconfig | 2474 ++++++++++++++++ drivers/video/fbdev/Makefile | 166 ++ drivers/video/{ => fbdev}/acornfb.c | 0 drivers/video/{ => fbdev}/acornfb.h | 0 drivers/video/{ => fbdev}/amba-clcd.c | 0 drivers/video/{ => fbdev}/amifb.c | 0 drivers/video/{ => fbdev}/arcfb.c | 0 drivers/video/{ => fbdev}/arkfb.c | 0 drivers/video/{ => fbdev}/asiliantfb.c | 0 drivers/video/{ => fbdev}/atafb.c | 0 drivers/video/{ => fbdev}/atafb.h | 0 drivers/video/{ => fbdev}/atafb_iplan2p2.c | 0 drivers/video/{ => fbdev}/atafb_iplan2p4.c | 0 drivers/video/{ => fbdev}/atafb_iplan2p8.c | 0 drivers/video/{ => fbdev}/atafb_mfb.c | 0 drivers/video/{ => fbdev}/atafb_utils.h | 0 drivers/video/{ => fbdev}/atmel_lcdfb.c | 0 drivers/video/{ => fbdev}/aty/Makefile | 0 drivers/video/{ => fbdev}/aty/ati_ids.h | 0 drivers/video/{ => fbdev}/aty/aty128fb.c | 0 drivers/video/{ => fbdev}/aty/atyfb.h | 0 drivers/video/{ => fbdev}/aty/atyfb_base.c | 0 drivers/video/{ => fbdev}/aty/mach64_accel.c | 0 drivers/video/{ => fbdev}/aty/mach64_ct.c | 0 drivers/video/{ => fbdev}/aty/mach64_cursor.c | 0 drivers/video/{ => fbdev}/aty/mach64_gx.c | 0 drivers/video/{ => fbdev}/aty/radeon_accel.c | 0 .../video/{ => fbdev}/aty/radeon_backlight.c | 0 drivers/video/{ => fbdev}/aty/radeon_base.c | 0 drivers/video/{ => fbdev}/aty/radeon_i2c.c | 0 .../video/{ => fbdev}/aty/radeon_monitor.c | 0 drivers/video/{ => fbdev}/aty/radeon_pm.c | 0 drivers/video/{ => fbdev}/aty/radeonfb.h | 0 drivers/video/{ => fbdev}/au1100fb.c | 0 drivers/video/{ => fbdev}/au1100fb.h | 0 drivers/video/{ => fbdev}/au1200fb.c | 0 drivers/video/{ => fbdev}/au1200fb.h | 0 drivers/video/{ => fbdev}/auo_k1900fb.c | 0 drivers/video/{ => fbdev}/auo_k1901fb.c | 0 drivers/video/{ => fbdev}/auo_k190x.c | 0 drivers/video/{ => fbdev}/auo_k190x.h | 0 drivers/video/{ => fbdev}/bf537-lq035.c | 0 drivers/video/{ => fbdev}/bf54x-lq043fb.c | 0 drivers/video/{ => fbdev}/bfin-lq035q1-fb.c | 0 drivers/video/{ => fbdev}/bfin-t350mcqb-fb.c | 0 drivers/video/{ => fbdev}/bfin_adv7393fb.c | 0 drivers/video/{ => fbdev}/bfin_adv7393fb.h | 0 drivers/video/{ => fbdev}/broadsheetfb.c | 0 drivers/video/{ => fbdev}/bt431.h | 0 drivers/video/{ => fbdev}/bt455.h | 0 drivers/video/{ => fbdev}/bw2.c | 0 drivers/video/{ => fbdev}/c2p.h | 0 drivers/video/{ => fbdev}/c2p_core.h | 0 drivers/video/{ => fbdev}/c2p_iplan2.c | 0 drivers/video/{ => fbdev}/c2p_planar.c | 0 drivers/video/{ => fbdev}/carminefb.c | 0 drivers/video/{ => fbdev}/carminefb.h | 0 drivers/video/{ => fbdev}/carminefb_regs.h | 0 drivers/video/{ => fbdev}/cfbcopyarea.c | 0 drivers/video/{ => fbdev}/cfbfillrect.c | 0 drivers/video/{ => fbdev}/cfbimgblt.c | 0 drivers/video/{ => fbdev}/cg14.c | 0 drivers/video/{ => fbdev}/cg3.c | 0 drivers/video/{ => fbdev}/cg6.c | 0 drivers/video/{ => fbdev}/chipsfb.c | 0 drivers/video/{ => fbdev}/cirrusfb.c | 0 drivers/video/{ => fbdev}/clps711xfb.c | 0 drivers/video/{ => fbdev}/cobalt_lcdfb.c | 0 drivers/video/{ => fbdev}/controlfb.c | 0 drivers/video/{ => fbdev}/controlfb.h | 0 drivers/video/{ => fbdev}/cyber2000fb.c | 0 drivers/video/{ => fbdev}/cyber2000fb.h | 0 drivers/video/{ => fbdev}/da8xx-fb.c | 0 drivers/video/{ => fbdev}/dnfb.c | 0 drivers/video/{ => fbdev}/edid.h | 0 drivers/video/{ => fbdev}/efifb.c | 0 drivers/video/{ => fbdev}/ep93xx-fb.c | 0 drivers/video/{ => fbdev}/exynos/Kconfig | 0 drivers/video/{ => fbdev}/exynos/Makefile | 0 .../{ => fbdev}/exynos/exynos_mipi_dsi.c | 0 .../exynos/exynos_mipi_dsi_common.c | 0 .../exynos/exynos_mipi_dsi_common.h | 0 .../exynos/exynos_mipi_dsi_lowlevel.c | 0 .../exynos/exynos_mipi_dsi_lowlevel.h | 0 .../{ => fbdev}/exynos/exynos_mipi_dsi_regs.h | 0 drivers/video/{ => fbdev}/exynos/s6e8ax0.c | 0 drivers/video/{ => fbdev}/fb-puv3.c | 0 drivers/video/{ => fbdev}/fb_ddc.c | 0 drivers/video/{ => fbdev}/fb_defio.c | 0 drivers/video/{ => fbdev}/fb_draw.h | 0 drivers/video/{ => fbdev}/fb_notify.c | 0 drivers/video/{ => fbdev}/fb_sys_fops.c | 0 drivers/video/{ => fbdev}/fbcmap.c | 0 drivers/video/{ => fbdev}/fbcvt.c | 0 drivers/video/{ => fbdev}/fbmem.c | 0 drivers/video/{ => fbdev}/fbmon.c | 0 drivers/video/{ => fbdev}/fbsysfs.c | 0 drivers/video/{ => fbdev}/ffb.c | 0 drivers/video/{ => fbdev}/fm2fb.c | 0 drivers/video/{ => fbdev}/fsl-diu-fb.c | 0 drivers/video/{ => fbdev}/g364fb.c | 0 drivers/video/{ => fbdev}/gbefb.c | 0 drivers/video/{ => fbdev}/geode/Kconfig | 0 drivers/video/{ => fbdev}/geode/Makefile | 0 drivers/video/{ => fbdev}/geode/display_gx.c | 0 drivers/video/{ => fbdev}/geode/display_gx1.c | 0 drivers/video/{ => fbdev}/geode/display_gx1.h | 0 drivers/video/{ => fbdev}/geode/geodefb.h | 0 drivers/video/{ => fbdev}/geode/gx1fb_core.c | 0 drivers/video/{ => fbdev}/geode/gxfb.h | 0 drivers/video/{ => fbdev}/geode/gxfb_core.c | 0 drivers/video/{ => fbdev}/geode/lxfb.h | 0 drivers/video/{ => fbdev}/geode/lxfb_core.c | 0 drivers/video/{ => fbdev}/geode/lxfb_ops.c | 0 drivers/video/{ => fbdev}/geode/suspend_gx.c | 0 .../video/{ => fbdev}/geode/video_cs5530.c | 0 .../video/{ => fbdev}/geode/video_cs5530.h | 0 drivers/video/{ => fbdev}/geode/video_gx.c | 0 drivers/video/{ => fbdev}/goldfishfb.c | 0 drivers/video/{ => fbdev}/grvga.c | 0 drivers/video/{ => fbdev}/gxt4500.c | 0 drivers/video/{ => fbdev}/hecubafb.c | 0 drivers/video/{ => fbdev}/hgafb.c | 0 drivers/video/{ => fbdev}/hitfb.c | 0 drivers/video/{ => fbdev}/hpfb.c | 0 drivers/video/{ => fbdev}/hyperv_fb.c | 0 drivers/video/{ => fbdev}/i740_reg.h | 0 drivers/video/{ => fbdev}/i740fb.c | 0 drivers/video/{ => fbdev}/i810/Makefile | 0 drivers/video/{ => fbdev}/i810/i810-i2c.c | 0 drivers/video/{ => fbdev}/i810/i810.h | 0 drivers/video/{ => fbdev}/i810/i810_accel.c | 0 drivers/video/{ => fbdev}/i810/i810_dvt.c | 0 drivers/video/{ => fbdev}/i810/i810_gtf.c | 0 drivers/video/{ => fbdev}/i810/i810_main.c | 0 drivers/video/{ => fbdev}/i810/i810_main.h | 0 drivers/video/{ => fbdev}/i810/i810_regs.h | 0 drivers/video/{ => fbdev}/igafb.c | 0 drivers/video/{ => fbdev}/imsttfb.c | 0 drivers/video/{ => fbdev}/imxfb.c | 0 drivers/video/{ => fbdev}/intelfb/Makefile | 0 drivers/video/{ => fbdev}/intelfb/intelfb.h | 0 .../video/{ => fbdev}/intelfb/intelfb_i2c.c | 0 .../video/{ => fbdev}/intelfb/intelfbdrv.c | 0 drivers/video/{ => fbdev}/intelfb/intelfbhw.c | 0 drivers/video/{ => fbdev}/intelfb/intelfbhw.h | 0 drivers/video/{ => fbdev}/jz4740_fb.c | 0 drivers/video/{ => fbdev}/kyro/Makefile | 0 .../{ => fbdev}/kyro/STG4000InitDevice.c | 0 .../video/{ => fbdev}/kyro/STG4000Interface.h | 0 .../{ => fbdev}/kyro/STG4000OverlayDevice.c | 0 .../video/{ => fbdev}/kyro/STG4000Ramdac.c | 0 drivers/video/{ => fbdev}/kyro/STG4000Reg.h | 0 drivers/video/{ => fbdev}/kyro/STG4000VTG.c | 0 drivers/video/{ => fbdev}/kyro/fbdev.c | 0 drivers/video/{ => fbdev}/leo.c | 0 drivers/video/{ => fbdev}/macfb.c | 0 drivers/video/{ => fbdev}/macmodes.c | 0 drivers/video/{ => fbdev}/macmodes.h | 0 drivers/video/{ => fbdev}/matrox/Makefile | 0 drivers/video/{ => fbdev}/matrox/g450_pll.c | 0 drivers/video/{ => fbdev}/matrox/g450_pll.h | 0 .../video/{ => fbdev}/matrox/i2c-matroxfb.c | 0 .../{ => fbdev}/matrox/matroxfb_DAC1064.c | 0 .../{ => fbdev}/matrox/matroxfb_DAC1064.h | 0 .../{ => fbdev}/matrox/matroxfb_Ti3026.c | 0 .../{ => fbdev}/matrox/matroxfb_Ti3026.h | 0 .../video/{ => fbdev}/matrox/matroxfb_accel.c | 0 .../video/{ => fbdev}/matrox/matroxfb_accel.h | 0 .../video/{ => fbdev}/matrox/matroxfb_base.c | 0 .../video/{ => fbdev}/matrox/matroxfb_base.h | 0 .../video/{ => fbdev}/matrox/matroxfb_crtc2.c | 0 .../video/{ => fbdev}/matrox/matroxfb_crtc2.h | 0 .../video/{ => fbdev}/matrox/matroxfb_g450.c | 0 .../video/{ => fbdev}/matrox/matroxfb_g450.h | 0 .../video/{ => fbdev}/matrox/matroxfb_maven.c | 0 .../video/{ => fbdev}/matrox/matroxfb_maven.h | 0 .../video/{ => fbdev}/matrox/matroxfb_misc.c | 0 .../video/{ => fbdev}/matrox/matroxfb_misc.h | 0 drivers/video/{ => fbdev}/maxinefb.c | 0 drivers/video/{ => fbdev}/mb862xx/Makefile | 0 .../video/{ => fbdev}/mb862xx/mb862xx-i2c.c | 0 .../video/{ => fbdev}/mb862xx/mb862xx_reg.h | 0 drivers/video/{ => fbdev}/mb862xx/mb862xxfb.h | 0 .../{ => fbdev}/mb862xx/mb862xxfb_accel.c | 0 .../{ => fbdev}/mb862xx/mb862xxfb_accel.h | 0 .../video/{ => fbdev}/mb862xx/mb862xxfbdrv.c | 0 drivers/video/{ => fbdev}/mbx/Makefile | 0 drivers/video/{ => fbdev}/mbx/mbxdebugfs.c | 0 drivers/video/{ => fbdev}/mbx/mbxfb.c | 0 drivers/video/{ => fbdev}/mbx/reg_bits.h | 0 drivers/video/{ => fbdev}/mbx/regs.h | 0 drivers/video/{ => fbdev}/metronomefb.c | 0 drivers/video/{ => fbdev}/mmp/Kconfig | 6 +- drivers/video/{ => fbdev}/mmp/Makefile | 0 drivers/video/{ => fbdev}/mmp/core.c | 0 drivers/video/{ => fbdev}/mmp/fb/Kconfig | 0 drivers/video/{ => fbdev}/mmp/fb/Makefile | 0 drivers/video/{ => fbdev}/mmp/fb/mmpfb.c | 0 drivers/video/{ => fbdev}/mmp/fb/mmpfb.h | 0 drivers/video/{ => fbdev}/mmp/hw/Kconfig | 0 drivers/video/{ => fbdev}/mmp/hw/Makefile | 0 drivers/video/{ => fbdev}/mmp/hw/mmp_ctrl.c | 0 drivers/video/{ => fbdev}/mmp/hw/mmp_ctrl.h | 0 drivers/video/{ => fbdev}/mmp/hw/mmp_spi.c | 0 drivers/video/{ => fbdev}/mmp/panel/Kconfig | 0 drivers/video/{ => fbdev}/mmp/panel/Makefile | 0 .../{ => fbdev}/mmp/panel/tpo_tj032md01bw.c | 0 drivers/video/{ => fbdev}/modedb.c | 0 drivers/video/{ => fbdev}/msm/Makefile | 0 drivers/video/{ => fbdev}/msm/mddi.c | 0 .../video/{ => fbdev}/msm/mddi_client_dummy.c | 0 .../{ => fbdev}/msm/mddi_client_nt35399.c | 0 .../{ => fbdev}/msm/mddi_client_toshiba.c | 0 drivers/video/{ => fbdev}/msm/mddi_hw.h | 0 drivers/video/{ => fbdev}/msm/mdp.c | 0 drivers/video/{ => fbdev}/msm/mdp_csc_table.h | 0 drivers/video/{ => fbdev}/msm/mdp_hw.h | 0 drivers/video/{ => fbdev}/msm/mdp_ppp.c | 0 .../video/{ => fbdev}/msm/mdp_scale_tables.c | 0 .../video/{ => fbdev}/msm/mdp_scale_tables.h | 0 drivers/video/{ => fbdev}/msm/msm_fb.c | 0 drivers/video/{ => fbdev}/mx3fb.c | 0 drivers/video/{ => fbdev}/mxsfb.c | 0 drivers/video/{ => fbdev}/n411.c | 0 drivers/video/{ => fbdev}/neofb.c | 0 drivers/video/{ => fbdev}/nuc900fb.c | 0 drivers/video/{ => fbdev}/nuc900fb.h | 0 drivers/video/{ => fbdev}/nvidia/Makefile | 0 drivers/video/{ => fbdev}/nvidia/nv_accel.c | 0 .../video/{ => fbdev}/nvidia/nv_backlight.c | 0 drivers/video/{ => fbdev}/nvidia/nv_dma.h | 0 drivers/video/{ => fbdev}/nvidia/nv_hw.c | 0 drivers/video/{ => fbdev}/nvidia/nv_i2c.c | 0 drivers/video/{ => fbdev}/nvidia/nv_local.h | 0 drivers/video/{ => fbdev}/nvidia/nv_of.c | 0 drivers/video/{ => fbdev}/nvidia/nv_proto.h | 0 drivers/video/{ => fbdev}/nvidia/nv_setup.c | 0 drivers/video/{ => fbdev}/nvidia/nv_type.h | 0 drivers/video/{ => fbdev}/nvidia/nvidia.c | 0 drivers/video/{ => fbdev}/ocfb.c | 0 drivers/video/{ => fbdev}/offb.c | 0 drivers/video/{ => fbdev}/omap/Kconfig | 0 drivers/video/{ => fbdev}/omap/Makefile | 0 drivers/video/{ => fbdev}/omap/hwa742.c | 0 .../video/{ => fbdev}/omap/lcd_ams_delta.c | 0 drivers/video/{ => fbdev}/omap/lcd_h3.c | 0 .../video/{ => fbdev}/omap/lcd_htcherald.c | 0 drivers/video/{ => fbdev}/omap/lcd_inn1510.c | 0 drivers/video/{ => fbdev}/omap/lcd_inn1610.c | 0 drivers/video/{ => fbdev}/omap/lcd_mipid.c | 0 drivers/video/{ => fbdev}/omap/lcd_osk.c | 0 drivers/video/{ => fbdev}/omap/lcd_palmte.c | 0 drivers/video/{ => fbdev}/omap/lcd_palmtt.c | 0 drivers/video/{ => fbdev}/omap/lcd_palmz71.c | 0 drivers/video/{ => fbdev}/omap/lcdc.c | 0 drivers/video/{ => fbdev}/omap/lcdc.h | 0 drivers/video/{ => fbdev}/omap/omapfb.h | 0 drivers/video/{ => fbdev}/omap/omapfb_main.c | 0 drivers/video/{ => fbdev}/omap/sossi.c | 0 drivers/video/fbdev/omap2/Kconfig | 10 + drivers/video/{ => fbdev}/omap2/Makefile | 0 .../{ => fbdev}/omap2/displays-new/Kconfig | 0 .../{ => fbdev}/omap2/displays-new/Makefile | 0 .../omap2/displays-new/connector-analog-tv.c | 0 .../omap2/displays-new/connector-dvi.c | 0 .../omap2/displays-new/connector-hdmi.c | 0 .../omap2/displays-new/encoder-tfp410.c | 0 .../omap2/displays-new/encoder-tpd12s015.c | 0 .../omap2/displays-new/panel-dpi.c | 0 .../omap2/displays-new/panel-dsi-cm.c | 0 .../displays-new/panel-lgphilips-lb035q02.c | 0 .../omap2/displays-new/panel-nec-nl8048hl11.c | 0 .../displays-new/panel-sharp-ls037v7dw01.c | 0 .../omap2/displays-new/panel-sony-acx565akm.c | 0 .../omap2/displays-new/panel-tpo-td028ttec1.c | 0 .../omap2/displays-new/panel-tpo-td043mtea1.c | 0 drivers/video/{ => fbdev}/omap2/dss/Kconfig | 0 drivers/video/{ => fbdev}/omap2/dss/Makefile | 0 drivers/video/{ => fbdev}/omap2/dss/apply.c | 0 drivers/video/{ => fbdev}/omap2/dss/core.c | 0 .../{ => fbdev}/omap2/dss/dispc-compat.c | 0 .../{ => fbdev}/omap2/dss/dispc-compat.h | 0 drivers/video/{ => fbdev}/omap2/dss/dispc.c | 0 drivers/video/{ => fbdev}/omap2/dss/dispc.h | 0 .../video/{ => fbdev}/omap2/dss/dispc_coefs.c | 0 .../{ => fbdev}/omap2/dss/display-sysfs.c | 0 drivers/video/{ => fbdev}/omap2/dss/display.c | 0 drivers/video/{ => fbdev}/omap2/dss/dpi.c | 0 drivers/video/{ => fbdev}/omap2/dss/dsi.c | 0 drivers/video/{ => fbdev}/omap2/dss/dss-of.c | 0 drivers/video/{ => fbdev}/omap2/dss/dss.c | 0 drivers/video/{ => fbdev}/omap2/dss/dss.h | 0 .../{ => fbdev}/omap2/dss/dss_features.c | 0 .../{ => fbdev}/omap2/dss/dss_features.h | 0 drivers/video/{ => fbdev}/omap2/dss/hdmi.h | 0 drivers/video/{ => fbdev}/omap2/dss/hdmi4.c | 0 .../video/{ => fbdev}/omap2/dss/hdmi4_core.c | 0 .../video/{ => fbdev}/omap2/dss/hdmi4_core.h | 0 .../video/{ => fbdev}/omap2/dss/hdmi_common.c | 0 .../video/{ => fbdev}/omap2/dss/hdmi_phy.c | 0 .../video/{ => fbdev}/omap2/dss/hdmi_pll.c | 0 drivers/video/{ => fbdev}/omap2/dss/hdmi_wp.c | 0 .../{ => fbdev}/omap2/dss/manager-sysfs.c | 0 drivers/video/{ => fbdev}/omap2/dss/manager.c | 0 drivers/video/{ => fbdev}/omap2/dss/output.c | 0 .../{ => fbdev}/omap2/dss/overlay-sysfs.c | 0 drivers/video/{ => fbdev}/omap2/dss/overlay.c | 0 drivers/video/{ => fbdev}/omap2/dss/rfbi.c | 0 drivers/video/{ => fbdev}/omap2/dss/sdi.c | 0 drivers/video/{ => fbdev}/omap2/dss/venc.c | 0 .../video/{ => fbdev}/omap2/dss/venc_panel.c | 0 .../video/{ => fbdev}/omap2/omapfb/Kconfig | 0 .../video/{ => fbdev}/omap2/omapfb/Makefile | 0 .../{ => fbdev}/omap2/omapfb/omapfb-ioctl.c | 0 .../{ => fbdev}/omap2/omapfb/omapfb-main.c | 0 .../{ => fbdev}/omap2/omapfb/omapfb-sysfs.c | 0 .../video/{ => fbdev}/omap2/omapfb/omapfb.h | 0 drivers/video/{ => fbdev}/omap2/vrfb.c | 0 drivers/video/{ => fbdev}/p9100.c | 0 drivers/video/{ => fbdev}/platinumfb.c | 0 drivers/video/{ => fbdev}/platinumfb.h | 0 drivers/video/{ => fbdev}/pm2fb.c | 0 drivers/video/{ => fbdev}/pm3fb.c | 0 drivers/video/{ => fbdev}/pmag-aa-fb.c | 0 drivers/video/{ => fbdev}/pmag-ba-fb.c | 0 drivers/video/{ => fbdev}/pmagb-b-fb.c | 0 drivers/video/{ => fbdev}/ps3fb.c | 0 drivers/video/{ => fbdev}/pvr2fb.c | 0 drivers/video/{ => fbdev}/pxa168fb.c | 0 drivers/video/{ => fbdev}/pxa168fb.h | 0 drivers/video/{ => fbdev}/pxa3xx-gcu.c | 0 drivers/video/{ => fbdev}/pxa3xx-gcu.h | 0 drivers/video/{ => fbdev}/pxafb.c | 0 drivers/video/{ => fbdev}/pxafb.h | 0 drivers/video/{ => fbdev}/q40fb.c | 0 drivers/video/{ => fbdev}/riva/Makefile | 0 drivers/video/{ => fbdev}/riva/fbdev.c | 0 drivers/video/{ => fbdev}/riva/nv_driver.c | 0 drivers/video/{ => fbdev}/riva/nv_type.h | 0 drivers/video/{ => fbdev}/riva/nvreg.h | 0 drivers/video/{ => fbdev}/riva/riva_hw.c | 0 drivers/video/{ => fbdev}/riva/riva_hw.h | 0 drivers/video/{ => fbdev}/riva/riva_tbl.h | 0 drivers/video/{ => fbdev}/riva/rivafb-i2c.c | 0 drivers/video/{ => fbdev}/riva/rivafb.h | 0 drivers/video/{ => fbdev}/s1d13xxxfb.c | 0 drivers/video/{ => fbdev}/s3c-fb.c | 0 drivers/video/{ => fbdev}/s3c2410fb.c | 0 drivers/video/{ => fbdev}/s3c2410fb.h | 0 drivers/video/{ => fbdev}/s3fb.c | 0 drivers/video/{ => fbdev}/sa1100fb.c | 0 drivers/video/{ => fbdev}/sa1100fb.h | 0 drivers/video/{ => fbdev}/savage/Makefile | 0 .../video/{ => fbdev}/savage/savagefb-i2c.c | 0 drivers/video/{ => fbdev}/savage/savagefb.h | 0 .../video/{ => fbdev}/savage/savagefb_accel.c | 0 .../{ => fbdev}/savage/savagefb_driver.c | 0 drivers/video/{ => fbdev}/sbuslib.c | 0 drivers/video/{ => fbdev}/sbuslib.h | 0 drivers/video/{ => fbdev}/sh7760fb.c | 0 drivers/video/{ => fbdev}/sh_mipi_dsi.c | 0 drivers/video/{ => fbdev}/sh_mobile_hdmi.c | 0 drivers/video/{ => fbdev}/sh_mobile_lcdcfb.c | 0 drivers/video/{ => fbdev}/sh_mobile_lcdcfb.h | 0 drivers/video/{ => fbdev}/sh_mobile_meram.c | 0 drivers/video/{ => fbdev}/simplefb.c | 0 drivers/video/{ => fbdev}/sis/300vtbl.h | 0 drivers/video/{ => fbdev}/sis/310vtbl.h | 0 drivers/video/{ => fbdev}/sis/Makefile | 0 drivers/video/{ => fbdev}/sis/init.c | 0 drivers/video/{ => fbdev}/sis/init.h | 0 drivers/video/{ => fbdev}/sis/init301.c | 0 drivers/video/{ => fbdev}/sis/init301.h | 0 drivers/video/{ => fbdev}/sis/initdef.h | 0 drivers/video/{ => fbdev}/sis/initextlfb.c | 0 drivers/video/{ => fbdev}/sis/oem300.h | 0 drivers/video/{ => fbdev}/sis/oem310.h | 0 drivers/video/{ => fbdev}/sis/sis.h | 0 drivers/video/{ => fbdev}/sis/sis_accel.c | 0 drivers/video/{ => fbdev}/sis/sis_accel.h | 0 drivers/video/{ => fbdev}/sis/sis_main.c | 0 drivers/video/{ => fbdev}/sis/sis_main.h | 0 drivers/video/{ => fbdev}/sis/vgatypes.h | 0 drivers/video/{ => fbdev}/sis/vstruct.h | 0 drivers/video/{ => fbdev}/skeletonfb.c | 0 drivers/video/{ => fbdev}/sm501fb.c | 0 drivers/video/{ => fbdev}/smscufx.c | 0 drivers/video/{ => fbdev}/ssd1307fb.c | 0 drivers/video/{ => fbdev}/sstfb.c | 0 drivers/video/{ => fbdev}/sticore.h | 0 drivers/video/{ => fbdev}/stifb.c | 0 drivers/video/{ => fbdev}/sunxvr1000.c | 0 drivers/video/{ => fbdev}/sunxvr2500.c | 0 drivers/video/{ => fbdev}/sunxvr500.c | 0 drivers/video/{ => fbdev}/svgalib.c | 0 drivers/video/{ => fbdev}/syscopyarea.c | 0 drivers/video/{ => fbdev}/sysfillrect.c | 0 drivers/video/{ => fbdev}/sysimgblt.c | 0 drivers/video/{ => fbdev}/tcx.c | 0 drivers/video/{ => fbdev}/tdfxfb.c | 0 drivers/video/{ => fbdev}/tgafb.c | 0 drivers/video/{ => fbdev}/tmiofb.c | 0 drivers/video/{ => fbdev}/tridentfb.c | 0 drivers/video/{ => fbdev}/udlfb.c | 0 drivers/video/{ => fbdev}/uvesafb.c | 0 drivers/video/{ => fbdev}/valkyriefb.c | 0 drivers/video/{ => fbdev}/valkyriefb.h | 0 drivers/video/{ => fbdev}/vermilion/Makefile | 0 drivers/video/{ => fbdev}/vermilion/cr_pll.c | 0 .../video/{ => fbdev}/vermilion/vermilion.c | 0 .../video/{ => fbdev}/vermilion/vermilion.h | 0 drivers/video/{ => fbdev}/vesafb.c | 0 drivers/video/{ => fbdev}/vfb.c | 0 drivers/video/{ => fbdev}/vga16fb.c | 0 drivers/video/{ => fbdev}/via/Makefile | 0 drivers/video/{ => fbdev}/via/accel.c | 0 drivers/video/{ => fbdev}/via/accel.h | 0 drivers/video/{ => fbdev}/via/chip.h | 0 drivers/video/{ => fbdev}/via/debug.h | 0 drivers/video/{ => fbdev}/via/dvi.c | 0 drivers/video/{ => fbdev}/via/dvi.h | 0 drivers/video/{ => fbdev}/via/global.c | 0 drivers/video/{ => fbdev}/via/global.h | 0 drivers/video/{ => fbdev}/via/hw.c | 0 drivers/video/{ => fbdev}/via/hw.h | 0 drivers/video/{ => fbdev}/via/ioctl.c | 0 drivers/video/{ => fbdev}/via/ioctl.h | 0 drivers/video/{ => fbdev}/via/lcd.c | 0 drivers/video/{ => fbdev}/via/lcd.h | 0 drivers/video/{ => fbdev}/via/share.h | 0 drivers/video/{ => fbdev}/via/tblDPASetting.c | 0 drivers/video/{ => fbdev}/via/tblDPASetting.h | 0 drivers/video/{ => fbdev}/via/via-core.c | 0 drivers/video/{ => fbdev}/via/via-gpio.c | 0 drivers/video/{ => fbdev}/via/via_aux.c | 0 drivers/video/{ => fbdev}/via/via_aux.h | 0 .../video/{ => fbdev}/via/via_aux_ch7301.c | 0 drivers/video/{ => fbdev}/via/via_aux_edid.c | 0 .../video/{ => fbdev}/via/via_aux_sii164.c | 0 .../video/{ => fbdev}/via/via_aux_vt1621.c | 0 .../video/{ => fbdev}/via/via_aux_vt1622.c | 0 .../video/{ => fbdev}/via/via_aux_vt1625.c | 0 .../video/{ => fbdev}/via/via_aux_vt1631.c | 0 .../video/{ => fbdev}/via/via_aux_vt1632.c | 0 .../video/{ => fbdev}/via/via_aux_vt1636.c | 0 drivers/video/{ => fbdev}/via/via_clock.c | 0 drivers/video/{ => fbdev}/via/via_clock.h | 0 drivers/video/{ => fbdev}/via/via_i2c.c | 0 .../video/{ => fbdev}/via/via_modesetting.c | 0 .../video/{ => fbdev}/via/via_modesetting.h | 0 drivers/video/{ => fbdev}/via/via_utility.c | 0 drivers/video/{ => fbdev}/via/via_utility.h | 0 drivers/video/{ => fbdev}/via/viafbdev.c | 0 drivers/video/{ => fbdev}/via/viafbdev.h | 0 drivers/video/{ => fbdev}/via/viamode.c | 0 drivers/video/{ => fbdev}/via/viamode.h | 0 drivers/video/{ => fbdev}/via/vt1636.c | 0 drivers/video/{ => fbdev}/via/vt1636.h | 0 drivers/video/{ => fbdev}/vt8500lcdfb.c | 0 drivers/video/{ => fbdev}/vt8500lcdfb.h | 0 drivers/video/{ => fbdev}/vt8623fb.c | 0 drivers/video/{ => fbdev}/w100fb.c | 0 drivers/video/{ => fbdev}/w100fb.h | 0 drivers/video/{ => fbdev}/wm8505fb.c | 0 drivers/video/{ => fbdev}/wm8505fb_regs.h | 0 drivers/video/{ => fbdev}/wmt_ge_rops.c | 0 drivers/video/{ => fbdev}/wmt_ge_rops.h | 0 drivers/video/{ => fbdev}/xen-fbfront.c | 0 drivers/video/{ => fbdev}/xilinxfb.c | 0 drivers/video/omap2/Kconfig | 10 - 481 files changed, 2672 insertions(+), 2662 deletions(-) rename drivers/video/{ => fbdev}/68328fb.c (100%) create mode 100644 drivers/video/fbdev/Kconfig create mode 100644 drivers/video/fbdev/Makefile rename drivers/video/{ => fbdev}/acornfb.c (100%) rename drivers/video/{ => fbdev}/acornfb.h (100%) rename drivers/video/{ => fbdev}/amba-clcd.c (100%) rename drivers/video/{ => fbdev}/amifb.c (100%) rename drivers/video/{ => fbdev}/arcfb.c (100%) rename drivers/video/{ => fbdev}/arkfb.c (100%) rename drivers/video/{ => fbdev}/asiliantfb.c (100%) rename drivers/video/{ => fbdev}/atafb.c (100%) rename drivers/video/{ => fbdev}/atafb.h (100%) rename drivers/video/{ => fbdev}/atafb_iplan2p2.c (100%) rename drivers/video/{ => fbdev}/atafb_iplan2p4.c (100%) rename drivers/video/{ => fbdev}/atafb_iplan2p8.c (100%) rename drivers/video/{ => fbdev}/atafb_mfb.c (100%) rename drivers/video/{ => fbdev}/atafb_utils.h (100%) rename drivers/video/{ => fbdev}/atmel_lcdfb.c (100%) rename drivers/video/{ => fbdev}/aty/Makefile (100%) rename drivers/video/{ => fbdev}/aty/ati_ids.h (100%) rename drivers/video/{ => fbdev}/aty/aty128fb.c (100%) rename drivers/video/{ => fbdev}/aty/atyfb.h (100%) rename drivers/video/{ => fbdev}/aty/atyfb_base.c (100%) rename drivers/video/{ => fbdev}/aty/mach64_accel.c (100%) rename drivers/video/{ => fbdev}/aty/mach64_ct.c (100%) rename drivers/video/{ => fbdev}/aty/mach64_cursor.c (100%) rename drivers/video/{ => fbdev}/aty/mach64_gx.c (100%) rename drivers/video/{ => fbdev}/aty/radeon_accel.c (100%) rename drivers/video/{ => fbdev}/aty/radeon_backlight.c (100%) rename drivers/video/{ => fbdev}/aty/radeon_base.c (100%) rename drivers/video/{ => fbdev}/aty/radeon_i2c.c (100%) rename drivers/video/{ => fbdev}/aty/radeon_monitor.c (100%) rename drivers/video/{ => fbdev}/aty/radeon_pm.c (100%) rename drivers/video/{ => fbdev}/aty/radeonfb.h (100%) rename drivers/video/{ => fbdev}/au1100fb.c (100%) rename drivers/video/{ => fbdev}/au1100fb.h (100%) rename drivers/video/{ => fbdev}/au1200fb.c (100%) rename drivers/video/{ => fbdev}/au1200fb.h (100%) rename drivers/video/{ => fbdev}/auo_k1900fb.c (100%) rename drivers/video/{ => fbdev}/auo_k1901fb.c (100%) rename drivers/video/{ => fbdev}/auo_k190x.c (100%) rename drivers/video/{ => fbdev}/auo_k190x.h (100%) rename drivers/video/{ => fbdev}/bf537-lq035.c (100%) rename drivers/video/{ => fbdev}/bf54x-lq043fb.c (100%) rename drivers/video/{ => fbdev}/bfin-lq035q1-fb.c (100%) rename drivers/video/{ => fbdev}/bfin-t350mcqb-fb.c (100%) rename drivers/video/{ => fbdev}/bfin_adv7393fb.c (100%) rename drivers/video/{ => fbdev}/bfin_adv7393fb.h (100%) rename drivers/video/{ => fbdev}/broadsheetfb.c (100%) rename drivers/video/{ => fbdev}/bt431.h (100%) rename drivers/video/{ => fbdev}/bt455.h (100%) rename drivers/video/{ => fbdev}/bw2.c (100%) rename drivers/video/{ => fbdev}/c2p.h (100%) rename drivers/video/{ => fbdev}/c2p_core.h (100%) rename drivers/video/{ => fbdev}/c2p_iplan2.c (100%) rename drivers/video/{ => fbdev}/c2p_planar.c (100%) rename drivers/video/{ => fbdev}/carminefb.c (100%) rename drivers/video/{ => fbdev}/carminefb.h (100%) rename drivers/video/{ => fbdev}/carminefb_regs.h (100%) rename drivers/video/{ => fbdev}/cfbcopyarea.c (100%) rename drivers/video/{ => fbdev}/cfbfillrect.c (100%) rename drivers/video/{ => fbdev}/cfbimgblt.c (100%) rename drivers/video/{ => fbdev}/cg14.c (100%) rename drivers/video/{ => fbdev}/cg3.c (100%) rename drivers/video/{ => fbdev}/cg6.c (100%) rename drivers/video/{ => fbdev}/chipsfb.c (100%) rename drivers/video/{ => fbdev}/cirrusfb.c (100%) rename drivers/video/{ => fbdev}/clps711xfb.c (100%) rename drivers/video/{ => fbdev}/cobalt_lcdfb.c (100%) rename drivers/video/{ => fbdev}/controlfb.c (100%) rename drivers/video/{ => fbdev}/controlfb.h (100%) rename drivers/video/{ => fbdev}/cyber2000fb.c (100%) rename drivers/video/{ => fbdev}/cyber2000fb.h (100%) rename drivers/video/{ => fbdev}/da8xx-fb.c (100%) rename drivers/video/{ => fbdev}/dnfb.c (100%) rename drivers/video/{ => fbdev}/edid.h (100%) rename drivers/video/{ => fbdev}/efifb.c (100%) rename drivers/video/{ => fbdev}/ep93xx-fb.c (100%) rename drivers/video/{ => fbdev}/exynos/Kconfig (100%) rename drivers/video/{ => fbdev}/exynos/Makefile (100%) rename drivers/video/{ => fbdev}/exynos/exynos_mipi_dsi.c (100%) rename drivers/video/{ => fbdev}/exynos/exynos_mipi_dsi_common.c (100%) rename drivers/video/{ => fbdev}/exynos/exynos_mipi_dsi_common.h (100%) rename drivers/video/{ => fbdev}/exynos/exynos_mipi_dsi_lowlevel.c (100%) rename drivers/video/{ => fbdev}/exynos/exynos_mipi_dsi_lowlevel.h (100%) rename drivers/video/{ => fbdev}/exynos/exynos_mipi_dsi_regs.h (100%) rename drivers/video/{ => fbdev}/exynos/s6e8ax0.c (100%) rename drivers/video/{ => fbdev}/fb-puv3.c (100%) rename drivers/video/{ => fbdev}/fb_ddc.c (100%) rename drivers/video/{ => fbdev}/fb_defio.c (100%) rename drivers/video/{ => fbdev}/fb_draw.h (100%) rename drivers/video/{ => fbdev}/fb_notify.c (100%) rename drivers/video/{ => fbdev}/fb_sys_fops.c (100%) rename drivers/video/{ => fbdev}/fbcmap.c (100%) rename drivers/video/{ => fbdev}/fbcvt.c (100%) rename drivers/video/{ => fbdev}/fbmem.c (100%) rename drivers/video/{ => fbdev}/fbmon.c (100%) rename drivers/video/{ => fbdev}/fbsysfs.c (100%) rename drivers/video/{ => fbdev}/ffb.c (100%) rename drivers/video/{ => fbdev}/fm2fb.c (100%) rename drivers/video/{ => fbdev}/fsl-diu-fb.c (100%) rename drivers/video/{ => fbdev}/g364fb.c (100%) rename drivers/video/{ => fbdev}/gbefb.c (100%) rename drivers/video/{ => fbdev}/geode/Kconfig (100%) rename drivers/video/{ => fbdev}/geode/Makefile (100%) rename drivers/video/{ => fbdev}/geode/display_gx.c (100%) rename drivers/video/{ => fbdev}/geode/display_gx1.c (100%) rename drivers/video/{ => fbdev}/geode/display_gx1.h (100%) rename drivers/video/{ => fbdev}/geode/geodefb.h (100%) rename drivers/video/{ => fbdev}/geode/gx1fb_core.c (100%) rename drivers/video/{ => fbdev}/geode/gxfb.h (100%) rename drivers/video/{ => fbdev}/geode/gxfb_core.c (100%) rename drivers/video/{ => fbdev}/geode/lxfb.h (100%) rename drivers/video/{ => fbdev}/geode/lxfb_core.c (100%) rename drivers/video/{ => fbdev}/geode/lxfb_ops.c (100%) rename drivers/video/{ => fbdev}/geode/suspend_gx.c (100%) rename drivers/video/{ => fbdev}/geode/video_cs5530.c (100%) rename drivers/video/{ => fbdev}/geode/video_cs5530.h (100%) rename drivers/video/{ => fbdev}/geode/video_gx.c (100%) rename drivers/video/{ => fbdev}/goldfishfb.c (100%) rename drivers/video/{ => fbdev}/grvga.c (100%) rename drivers/video/{ => fbdev}/gxt4500.c (100%) rename drivers/video/{ => fbdev}/hecubafb.c (100%) rename drivers/video/{ => fbdev}/hgafb.c (100%) rename drivers/video/{ => fbdev}/hitfb.c (100%) rename drivers/video/{ => fbdev}/hpfb.c (100%) rename drivers/video/{ => fbdev}/hyperv_fb.c (100%) rename drivers/video/{ => fbdev}/i740_reg.h (100%) rename drivers/video/{ => fbdev}/i740fb.c (100%) rename drivers/video/{ => fbdev}/i810/Makefile (100%) rename drivers/video/{ => fbdev}/i810/i810-i2c.c (100%) rename drivers/video/{ => fbdev}/i810/i810.h (100%) rename drivers/video/{ => fbdev}/i810/i810_accel.c (100%) rename drivers/video/{ => fbdev}/i810/i810_dvt.c (100%) rename drivers/video/{ => fbdev}/i810/i810_gtf.c (100%) rename drivers/video/{ => fbdev}/i810/i810_main.c (100%) rename drivers/video/{ => fbdev}/i810/i810_main.h (100%) rename drivers/video/{ => fbdev}/i810/i810_regs.h (100%) rename drivers/video/{ => fbdev}/igafb.c (100%) rename drivers/video/{ => fbdev}/imsttfb.c (100%) rename drivers/video/{ => fbdev}/imxfb.c (100%) rename drivers/video/{ => fbdev}/intelfb/Makefile (100%) rename drivers/video/{ => fbdev}/intelfb/intelfb.h (100%) rename drivers/video/{ => fbdev}/intelfb/intelfb_i2c.c (100%) rename drivers/video/{ => fbdev}/intelfb/intelfbdrv.c (100%) rename drivers/video/{ => fbdev}/intelfb/intelfbhw.c (100%) rename drivers/video/{ => fbdev}/intelfb/intelfbhw.h (100%) rename drivers/video/{ => fbdev}/jz4740_fb.c (100%) rename drivers/video/{ => fbdev}/kyro/Makefile (100%) rename drivers/video/{ => fbdev}/kyro/STG4000InitDevice.c (100%) rename drivers/video/{ => fbdev}/kyro/STG4000Interface.h (100%) rename drivers/video/{ => fbdev}/kyro/STG4000OverlayDevice.c (100%) rename drivers/video/{ => fbdev}/kyro/STG4000Ramdac.c (100%) rename drivers/video/{ => fbdev}/kyro/STG4000Reg.h (100%) rename drivers/video/{ => fbdev}/kyro/STG4000VTG.c (100%) rename drivers/video/{ => fbdev}/kyro/fbdev.c (100%) rename drivers/video/{ => fbdev}/leo.c (100%) rename drivers/video/{ => fbdev}/macfb.c (100%) rename drivers/video/{ => fbdev}/macmodes.c (100%) rename drivers/video/{ => fbdev}/macmodes.h (100%) rename drivers/video/{ => fbdev}/matrox/Makefile (100%) rename drivers/video/{ => fbdev}/matrox/g450_pll.c (100%) rename drivers/video/{ => fbdev}/matrox/g450_pll.h (100%) rename drivers/video/{ => fbdev}/matrox/i2c-matroxfb.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_DAC1064.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_DAC1064.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_Ti3026.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_Ti3026.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_accel.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_accel.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_base.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_base.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_crtc2.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_crtc2.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_g450.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_g450.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_maven.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_maven.h (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_misc.c (100%) rename drivers/video/{ => fbdev}/matrox/matroxfb_misc.h (100%) rename drivers/video/{ => fbdev}/maxinefb.c (100%) rename drivers/video/{ => fbdev}/mb862xx/Makefile (100%) rename drivers/video/{ => fbdev}/mb862xx/mb862xx-i2c.c (100%) rename drivers/video/{ => fbdev}/mb862xx/mb862xx_reg.h (100%) rename drivers/video/{ => fbdev}/mb862xx/mb862xxfb.h (100%) rename drivers/video/{ => fbdev}/mb862xx/mb862xxfb_accel.c (100%) rename drivers/video/{ => fbdev}/mb862xx/mb862xxfb_accel.h (100%) rename drivers/video/{ => fbdev}/mb862xx/mb862xxfbdrv.c (100%) rename drivers/video/{ => fbdev}/mbx/Makefile (100%) rename drivers/video/{ => fbdev}/mbx/mbxdebugfs.c (100%) rename drivers/video/{ => fbdev}/mbx/mbxfb.c (100%) rename drivers/video/{ => fbdev}/mbx/reg_bits.h (100%) rename drivers/video/{ => fbdev}/mbx/regs.h (100%) rename drivers/video/{ => fbdev}/metronomefb.c (100%) rename drivers/video/{ => fbdev}/mmp/Kconfig (61%) rename drivers/video/{ => fbdev}/mmp/Makefile (100%) rename drivers/video/{ => fbdev}/mmp/core.c (100%) rename drivers/video/{ => fbdev}/mmp/fb/Kconfig (100%) rename drivers/video/{ => fbdev}/mmp/fb/Makefile (100%) rename drivers/video/{ => fbdev}/mmp/fb/mmpfb.c (100%) rename drivers/video/{ => fbdev}/mmp/fb/mmpfb.h (100%) rename drivers/video/{ => fbdev}/mmp/hw/Kconfig (100%) rename drivers/video/{ => fbdev}/mmp/hw/Makefile (100%) rename drivers/video/{ => fbdev}/mmp/hw/mmp_ctrl.c (100%) rename drivers/video/{ => fbdev}/mmp/hw/mmp_ctrl.h (100%) rename drivers/video/{ => fbdev}/mmp/hw/mmp_spi.c (100%) rename drivers/video/{ => fbdev}/mmp/panel/Kconfig (100%) rename drivers/video/{ => fbdev}/mmp/panel/Makefile (100%) rename drivers/video/{ => fbdev}/mmp/panel/tpo_tj032md01bw.c (100%) rename drivers/video/{ => fbdev}/modedb.c (100%) rename drivers/video/{ => fbdev}/msm/Makefile (100%) rename drivers/video/{ => fbdev}/msm/mddi.c (100%) rename drivers/video/{ => fbdev}/msm/mddi_client_dummy.c (100%) rename drivers/video/{ => fbdev}/msm/mddi_client_nt35399.c (100%) rename drivers/video/{ => fbdev}/msm/mddi_client_toshiba.c (100%) rename drivers/video/{ => fbdev}/msm/mddi_hw.h (100%) rename drivers/video/{ => fbdev}/msm/mdp.c (100%) rename drivers/video/{ => fbdev}/msm/mdp_csc_table.h (100%) rename drivers/video/{ => fbdev}/msm/mdp_hw.h (100%) rename drivers/video/{ => fbdev}/msm/mdp_ppp.c (100%) rename drivers/video/{ => fbdev}/msm/mdp_scale_tables.c (100%) rename drivers/video/{ => fbdev}/msm/mdp_scale_tables.h (100%) rename drivers/video/{ => fbdev}/msm/msm_fb.c (100%) rename drivers/video/{ => fbdev}/mx3fb.c (100%) rename drivers/video/{ => fbdev}/mxsfb.c (100%) rename drivers/video/{ => fbdev}/n411.c (100%) rename drivers/video/{ => fbdev}/neofb.c (100%) rename drivers/video/{ => fbdev}/nuc900fb.c (100%) rename drivers/video/{ => fbdev}/nuc900fb.h (100%) rename drivers/video/{ => fbdev}/nvidia/Makefile (100%) rename drivers/video/{ => fbdev}/nvidia/nv_accel.c (100%) rename drivers/video/{ => fbdev}/nvidia/nv_backlight.c (100%) rename drivers/video/{ => fbdev}/nvidia/nv_dma.h (100%) rename drivers/video/{ => fbdev}/nvidia/nv_hw.c (100%) rename drivers/video/{ => fbdev}/nvidia/nv_i2c.c (100%) rename drivers/video/{ => fbdev}/nvidia/nv_local.h (100%) rename drivers/video/{ => fbdev}/nvidia/nv_of.c (100%) rename drivers/video/{ => fbdev}/nvidia/nv_proto.h (100%) rename drivers/video/{ => fbdev}/nvidia/nv_setup.c (100%) rename drivers/video/{ => fbdev}/nvidia/nv_type.h (100%) rename drivers/video/{ => fbdev}/nvidia/nvidia.c (100%) rename drivers/video/{ => fbdev}/ocfb.c (100%) rename drivers/video/{ => fbdev}/offb.c (100%) rename drivers/video/{ => fbdev}/omap/Kconfig (100%) rename drivers/video/{ => fbdev}/omap/Makefile (100%) rename drivers/video/{ => fbdev}/omap/hwa742.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_ams_delta.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_h3.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_htcherald.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_inn1510.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_inn1610.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_mipid.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_osk.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_palmte.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_palmtt.c (100%) rename drivers/video/{ => fbdev}/omap/lcd_palmz71.c (100%) rename drivers/video/{ => fbdev}/omap/lcdc.c (100%) rename drivers/video/{ => fbdev}/omap/lcdc.h (100%) rename drivers/video/{ => fbdev}/omap/omapfb.h (100%) rename drivers/video/{ => fbdev}/omap/omapfb_main.c (100%) rename drivers/video/{ => fbdev}/omap/sossi.c (100%) create mode 100644 drivers/video/fbdev/omap2/Kconfig rename drivers/video/{ => fbdev}/omap2/Makefile (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/Kconfig (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/Makefile (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/connector-analog-tv.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/connector-dvi.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/connector-hdmi.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/encoder-tfp410.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/encoder-tpd12s015.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-dpi.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-dsi-cm.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-lgphilips-lb035q02.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-nec-nl8048hl11.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-sharp-ls037v7dw01.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-sony-acx565akm.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-tpo-td028ttec1.c (100%) rename drivers/video/{ => fbdev}/omap2/displays-new/panel-tpo-td043mtea1.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/Kconfig (100%) rename drivers/video/{ => fbdev}/omap2/dss/Makefile (100%) rename drivers/video/{ => fbdev}/omap2/dss/apply.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/core.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dispc-compat.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dispc-compat.h (100%) rename drivers/video/{ => fbdev}/omap2/dss/dispc.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dispc.h (100%) rename drivers/video/{ => fbdev}/omap2/dss/dispc_coefs.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/display-sysfs.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/display.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dpi.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dsi.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dss-of.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dss.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dss.h (100%) rename drivers/video/{ => fbdev}/omap2/dss/dss_features.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/dss_features.h (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi.h (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi4.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi4_core.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi4_core.h (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi_common.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi_phy.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi_pll.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/hdmi_wp.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/manager-sysfs.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/manager.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/output.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/overlay-sysfs.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/overlay.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/rfbi.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/sdi.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/venc.c (100%) rename drivers/video/{ => fbdev}/omap2/dss/venc_panel.c (100%) rename drivers/video/{ => fbdev}/omap2/omapfb/Kconfig (100%) rename drivers/video/{ => fbdev}/omap2/omapfb/Makefile (100%) rename drivers/video/{ => fbdev}/omap2/omapfb/omapfb-ioctl.c (100%) rename drivers/video/{ => fbdev}/omap2/omapfb/omapfb-main.c (100%) rename drivers/video/{ => fbdev}/omap2/omapfb/omapfb-sysfs.c (100%) rename drivers/video/{ => fbdev}/omap2/omapfb/omapfb.h (100%) rename drivers/video/{ => fbdev}/omap2/vrfb.c (100%) rename drivers/video/{ => fbdev}/p9100.c (100%) rename drivers/video/{ => fbdev}/platinumfb.c (100%) rename drivers/video/{ => fbdev}/platinumfb.h (100%) rename drivers/video/{ => fbdev}/pm2fb.c (100%) rename drivers/video/{ => fbdev}/pm3fb.c (100%) rename drivers/video/{ => fbdev}/pmag-aa-fb.c (100%) rename drivers/video/{ => fbdev}/pmag-ba-fb.c (100%) rename drivers/video/{ => fbdev}/pmagb-b-fb.c (100%) rename drivers/video/{ => fbdev}/ps3fb.c (100%) rename drivers/video/{ => fbdev}/pvr2fb.c (100%) rename drivers/video/{ => fbdev}/pxa168fb.c (100%) rename drivers/video/{ => fbdev}/pxa168fb.h (100%) rename drivers/video/{ => fbdev}/pxa3xx-gcu.c (100%) rename drivers/video/{ => fbdev}/pxa3xx-gcu.h (100%) rename drivers/video/{ => fbdev}/pxafb.c (100%) rename drivers/video/{ => fbdev}/pxafb.h (100%) rename drivers/video/{ => fbdev}/q40fb.c (100%) rename drivers/video/{ => fbdev}/riva/Makefile (100%) rename drivers/video/{ => fbdev}/riva/fbdev.c (100%) rename drivers/video/{ => fbdev}/riva/nv_driver.c (100%) rename drivers/video/{ => fbdev}/riva/nv_type.h (100%) rename drivers/video/{ => fbdev}/riva/nvreg.h (100%) rename drivers/video/{ => fbdev}/riva/riva_hw.c (100%) rename drivers/video/{ => fbdev}/riva/riva_hw.h (100%) rename drivers/video/{ => fbdev}/riva/riva_tbl.h (100%) rename drivers/video/{ => fbdev}/riva/rivafb-i2c.c (100%) rename drivers/video/{ => fbdev}/riva/rivafb.h (100%) rename drivers/video/{ => fbdev}/s1d13xxxfb.c (100%) rename drivers/video/{ => fbdev}/s3c-fb.c (100%) rename drivers/video/{ => fbdev}/s3c2410fb.c (100%) rename drivers/video/{ => fbdev}/s3c2410fb.h (100%) rename drivers/video/{ => fbdev}/s3fb.c (100%) rename drivers/video/{ => fbdev}/sa1100fb.c (100%) rename drivers/video/{ => fbdev}/sa1100fb.h (100%) rename drivers/video/{ => fbdev}/savage/Makefile (100%) rename drivers/video/{ => fbdev}/savage/savagefb-i2c.c (100%) rename drivers/video/{ => fbdev}/savage/savagefb.h (100%) rename drivers/video/{ => fbdev}/savage/savagefb_accel.c (100%) rename drivers/video/{ => fbdev}/savage/savagefb_driver.c (100%) rename drivers/video/{ => fbdev}/sbuslib.c (100%) rename drivers/video/{ => fbdev}/sbuslib.h (100%) rename drivers/video/{ => fbdev}/sh7760fb.c (100%) rename drivers/video/{ => fbdev}/sh_mipi_dsi.c (100%) rename drivers/video/{ => fbdev}/sh_mobile_hdmi.c (100%) rename drivers/video/{ => fbdev}/sh_mobile_lcdcfb.c (100%) rename drivers/video/{ => fbdev}/sh_mobile_lcdcfb.h (100%) rename drivers/video/{ => fbdev}/sh_mobile_meram.c (100%) rename drivers/video/{ => fbdev}/simplefb.c (100%) rename drivers/video/{ => fbdev}/sis/300vtbl.h (100%) rename drivers/video/{ => fbdev}/sis/310vtbl.h (100%) rename drivers/video/{ => fbdev}/sis/Makefile (100%) rename drivers/video/{ => fbdev}/sis/init.c (100%) rename drivers/video/{ => fbdev}/sis/init.h (100%) rename drivers/video/{ => fbdev}/sis/init301.c (100%) rename drivers/video/{ => fbdev}/sis/init301.h (100%) rename drivers/video/{ => fbdev}/sis/initdef.h (100%) rename drivers/video/{ => fbdev}/sis/initextlfb.c (100%) rename drivers/video/{ => fbdev}/sis/oem300.h (100%) rename drivers/video/{ => fbdev}/sis/oem310.h (100%) rename drivers/video/{ => fbdev}/sis/sis.h (100%) rename drivers/video/{ => fbdev}/sis/sis_accel.c (100%) rename drivers/video/{ => fbdev}/sis/sis_accel.h (100%) rename drivers/video/{ => fbdev}/sis/sis_main.c (100%) rename drivers/video/{ => fbdev}/sis/sis_main.h (100%) rename drivers/video/{ => fbdev}/sis/vgatypes.h (100%) rename drivers/video/{ => fbdev}/sis/vstruct.h (100%) rename drivers/video/{ => fbdev}/skeletonfb.c (100%) rename drivers/video/{ => fbdev}/sm501fb.c (100%) rename drivers/video/{ => fbdev}/smscufx.c (100%) rename drivers/video/{ => fbdev}/ssd1307fb.c (100%) rename drivers/video/{ => fbdev}/sstfb.c (100%) rename drivers/video/{ => fbdev}/sticore.h (100%) rename drivers/video/{ => fbdev}/stifb.c (100%) rename drivers/video/{ => fbdev}/sunxvr1000.c (100%) rename drivers/video/{ => fbdev}/sunxvr2500.c (100%) rename drivers/video/{ => fbdev}/sunxvr500.c (100%) rename drivers/video/{ => fbdev}/svgalib.c (100%) rename drivers/video/{ => fbdev}/syscopyarea.c (100%) rename drivers/video/{ => fbdev}/sysfillrect.c (100%) rename drivers/video/{ => fbdev}/sysimgblt.c (100%) rename drivers/video/{ => fbdev}/tcx.c (100%) rename drivers/video/{ => fbdev}/tdfxfb.c (100%) rename drivers/video/{ => fbdev}/tgafb.c (100%) rename drivers/video/{ => fbdev}/tmiofb.c (100%) rename drivers/video/{ => fbdev}/tridentfb.c (100%) rename drivers/video/{ => fbdev}/udlfb.c (100%) rename drivers/video/{ => fbdev}/uvesafb.c (100%) rename drivers/video/{ => fbdev}/valkyriefb.c (100%) rename drivers/video/{ => fbdev}/valkyriefb.h (100%) rename drivers/video/{ => fbdev}/vermilion/Makefile (100%) rename drivers/video/{ => fbdev}/vermilion/cr_pll.c (100%) rename drivers/video/{ => fbdev}/vermilion/vermilion.c (100%) rename drivers/video/{ => fbdev}/vermilion/vermilion.h (100%) rename drivers/video/{ => fbdev}/vesafb.c (100%) rename drivers/video/{ => fbdev}/vfb.c (100%) rename drivers/video/{ => fbdev}/vga16fb.c (100%) rename drivers/video/{ => fbdev}/via/Makefile (100%) rename drivers/video/{ => fbdev}/via/accel.c (100%) rename drivers/video/{ => fbdev}/via/accel.h (100%) rename drivers/video/{ => fbdev}/via/chip.h (100%) rename drivers/video/{ => fbdev}/via/debug.h (100%) rename drivers/video/{ => fbdev}/via/dvi.c (100%) rename drivers/video/{ => fbdev}/via/dvi.h (100%) rename drivers/video/{ => fbdev}/via/global.c (100%) rename drivers/video/{ => fbdev}/via/global.h (100%) rename drivers/video/{ => fbdev}/via/hw.c (100%) rename drivers/video/{ => fbdev}/via/hw.h (100%) rename drivers/video/{ => fbdev}/via/ioctl.c (100%) rename drivers/video/{ => fbdev}/via/ioctl.h (100%) rename drivers/video/{ => fbdev}/via/lcd.c (100%) rename drivers/video/{ => fbdev}/via/lcd.h (100%) rename drivers/video/{ => fbdev}/via/share.h (100%) rename drivers/video/{ => fbdev}/via/tblDPASetting.c (100%) rename drivers/video/{ => fbdev}/via/tblDPASetting.h (100%) rename drivers/video/{ => fbdev}/via/via-core.c (100%) rename drivers/video/{ => fbdev}/via/via-gpio.c (100%) rename drivers/video/{ => fbdev}/via/via_aux.c (100%) rename drivers/video/{ => fbdev}/via/via_aux.h (100%) rename drivers/video/{ => fbdev}/via/via_aux_ch7301.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_edid.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_sii164.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_vt1621.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_vt1622.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_vt1625.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_vt1631.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_vt1632.c (100%) rename drivers/video/{ => fbdev}/via/via_aux_vt1636.c (100%) rename drivers/video/{ => fbdev}/via/via_clock.c (100%) rename drivers/video/{ => fbdev}/via/via_clock.h (100%) rename drivers/video/{ => fbdev}/via/via_i2c.c (100%) rename drivers/video/{ => fbdev}/via/via_modesetting.c (100%) rename drivers/video/{ => fbdev}/via/via_modesetting.h (100%) rename drivers/video/{ => fbdev}/via/via_utility.c (100%) rename drivers/video/{ => fbdev}/via/via_utility.h (100%) rename drivers/video/{ => fbdev}/via/viafbdev.c (100%) rename drivers/video/{ => fbdev}/via/viafbdev.h (100%) rename drivers/video/{ => fbdev}/via/viamode.c (100%) rename drivers/video/{ => fbdev}/via/viamode.h (100%) rename drivers/video/{ => fbdev}/via/vt1636.c (100%) rename drivers/video/{ => fbdev}/via/vt1636.h (100%) rename drivers/video/{ => fbdev}/vt8500lcdfb.c (100%) rename drivers/video/{ => fbdev}/vt8500lcdfb.h (100%) rename drivers/video/{ => fbdev}/vt8623fb.c (100%) rename drivers/video/{ => fbdev}/w100fb.c (100%) rename drivers/video/{ => fbdev}/w100fb.h (100%) rename drivers/video/{ => fbdev}/wm8505fb.c (100%) rename drivers/video/{ => fbdev}/wm8505fb_regs.h (100%) rename drivers/video/{ => fbdev}/wmt_ge_rops.c (100%) rename drivers/video/{ => fbdev}/wmt_ge_rops.h (100%) rename drivers/video/{ => fbdev}/xen-fbfront.c (100%) rename drivers/video/{ => fbdev}/xilinxfb.c (100%) delete mode 100644 drivers/video/omap2/Kconfig diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index f5170082bdb3..4d1aa8b44be7 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -276,7 +276,7 @@ X!Isound/sound_firmware.c Frame Buffer Memory -!Edrivers/video/fbmem.c +!Edrivers/video/fbdev/fbmem.c Frame Buffer Colormap -!Edrivers/video/fbcmap.c +!Edrivers/video/fbdev/fbcmap.c Frame Buffer Video Mode Database -!Idrivers/video/modedb.c -!Edrivers/video/modedb.c +!Idrivers/video/fbdev/modedb.c +!Edrivers/video/fbdev/modedb.c Frame Buffer Macintosh Video Mode Database -!Edrivers/video/macmodes.c +!Edrivers/video/fbdev/macmodes.c Frame Buffer Fonts diff --git a/drivers/Makefile b/drivers/Makefile index e3ced91b1784..d05d81b19b50 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -53,8 +53,8 @@ obj-y += gpu/ obj-$(CONFIG_CONNECTOR) += connector/ # i810fb and intelfb depend on char/agp/ -obj-$(CONFIG_FB_I810) += video/i810/ -obj-$(CONFIG_FB_INTEL) += video/intelfb/ +obj-$(CONFIG_FB_I810) += video/fbdev/i810/ +obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/ obj-$(CONFIG_PARPORT) += parport/ obj-y += base/ block/ misc/ mfd/ nfc/ diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 5c739bebd8a5..949f0e5eed8d 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -1,6 +1,6 @@ #ifndef _VB_DEF_ #define _VB_DEF_ -#include "../../video/sis/initdef.h" +#include "../../video/fbdev/sis/initdef.h" #define VB_XGI301C 0x0020 /* for 301C */ diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index c08ff5b2d6ee..0d27594554ca 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -1,6 +1,6 @@ #ifndef _VB_STRUCT_ #define _VB_STRUCT_ -#include "../../video/sis/vstruct.h" +#include "../../video/fbdev/sis/vstruct.h" struct XGI_LVDSCRT1HDataStruct { unsigned char Reg[8]; diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index ddf7776c295b..264351441f99 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -2,8 +2,8 @@ #define _VGATYPES_ #include /* for struct fb_var_screeninfo for sis.h */ -#include "../../video/sis/vgatypes.h" -#include "../../video/sis/sis.h" /* for LCD_TYPE */ +#include "../../video/fbdev/sis/vgatypes.h" +#include "../../video/fbdev/sis/sis.h" /* for LCD_TYPE */ #ifndef XGI_VB_CHIP_TYPE enum XGI_VB_CHIP_TYPE { diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 3ad7ebe2a96d..ab05d6cb0796 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -23,6 +23,10 @@ source "drivers/gpu/host1x/Kconfig" source "drivers/gpu/drm/Kconfig" +source "drivers/video/fbdev/Kconfig" + +source "drivers/video/backlight/Kconfig" + config VGASTATE tristate default n @@ -33,2484 +37,14 @@ config VIDEOMODE_HELPERS config HDMI bool -menuconfig FB - tristate "Support for frame buffer devices" - ---help--- - The frame buffer device provides an abstraction for the graphics - hardware. It represents the frame buffer of some video hardware and - allows application software to access the graphics hardware through - a well-defined interface, so the software doesn't need to know - anything about the low-level (hardware register) stuff. - - Frame buffer devices work identically across the different - architectures supported by Linux and make the implementation of - application programs easier and more portable; at this point, an X - server exists which uses the frame buffer device exclusively. - On several non-X86 architectures, the frame buffer device is the - only way to use the graphics hardware. - - The device is accessed through special device nodes, usually located - in the /dev directory, i.e. /dev/fb*. - - You need an utility program called fbset to make full use of frame - buffer devices. Please read - and the Framebuffer-HOWTO at - for more - information. - - Say Y here and to the driver for your graphics board below if you - are compiling a kernel for a non-x86 architecture. - - If you are compiling for the x86 architecture, you can say Y if you - want to play with it, but it is not essential. Please note that - running graphical applications that directly touch the hardware - (e.g. an accelerated X server) and that are not frame buffer - device-aware may cause unexpected results. If unsure, say N. - -config FIRMWARE_EDID - bool "Enable firmware EDID" - depends on FB - default n - ---help--- - This enables access to the EDID transferred from the firmware. - On the i386, this is from the Video BIOS. Enable this if DDC/I2C - transfers do not work for your driver and if you are using - nvidiafb, i810fb or savagefb. - - In general, choosing Y for this option is safe. If you - experience extremely long delays while booting before you get - something on your display, try setting this to N. Matrox cards in - combination with certain motherboards and monitors are known to - suffer from this problem. - -config FB_DDC - tristate - depends on FB - select I2C_ALGOBIT - select I2C - default n - -config FB_BOOT_VESA_SUPPORT - bool - depends on FB - default n - ---help--- - If true, at least one selected framebuffer driver can take advantage - of VESA video modes set at an early boot stage via the vga= parameter. - -config FB_CFB_FILLRECT - tristate - depends on FB - default n - ---help--- - Include the cfb_fillrect function for generic software rectangle - filling. This is used by drivers that don't provide their own - (accelerated) version. - -config FB_CFB_COPYAREA - tristate - depends on FB - default n - ---help--- - Include the cfb_copyarea function for generic software area copying. - This is used by drivers that don't provide their own (accelerated) - version. - -config FB_CFB_IMAGEBLIT - tristate - depends on FB - default n - ---help--- - Include the cfb_imageblit function for generic software image - blitting. This is used by drivers that don't provide their own - (accelerated) version. - -config FB_CFB_REV_PIXELS_IN_BYTE - bool - depends on FB - default n - ---help--- - Allow generic frame-buffer functions to work on displays with 1, 2 - and 4 bits per pixel depths which has opposite order of pixels in - byte order to bytes in long order. - -config FB_SYS_FILLRECT - tristate - depends on FB - default n - ---help--- - Include the sys_fillrect function for generic software rectangle - filling. This is used by drivers that don't provide their own - (accelerated) version and the framebuffer is in system RAM. - -config FB_SYS_COPYAREA - tristate - depends on FB - default n - ---help--- - Include the sys_copyarea function for generic software area copying. - This is used by drivers that don't provide their own (accelerated) - version and the framebuffer is in system RAM. - -config FB_SYS_IMAGEBLIT - tristate - depends on FB - default n - ---help--- - Include the sys_imageblit function for generic software image - blitting. This is used by drivers that don't provide their own - (accelerated) version and the framebuffer is in system RAM. - -menuconfig FB_FOREIGN_ENDIAN - bool "Framebuffer foreign endianness support" - depends on FB - ---help--- - This menu will let you enable support for the framebuffers with - non-native endianness (e.g. Little-Endian framebuffer on a - Big-Endian machine). Most probably you don't have such hardware, - so it's safe to say "n" here. - -choice - prompt "Choice endianness support" - depends on FB_FOREIGN_ENDIAN - -config FB_BOTH_ENDIAN - bool "Support for Big- and Little-Endian framebuffers" - -config FB_BIG_ENDIAN - bool "Support for Big-Endian framebuffers only" - -config FB_LITTLE_ENDIAN - bool "Support for Little-Endian framebuffers only" - -endchoice - -config FB_SYS_FOPS - tristate - depends on FB - default n - -config FB_DEFERRED_IO - bool - depends on FB - -config FB_HECUBA - tristate - depends on FB - depends on FB_DEFERRED_IO - -config FB_SVGALIB - tristate - depends on FB - default n - ---help--- - Common utility functions useful to fbdev drivers of VGA-based - cards. - -config FB_MACMODES - tristate - depends on FB - default n - -config FB_BACKLIGHT - bool - depends on FB - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE - default n - -config FB_MODE_HELPERS - bool "Enable Video Mode Handling Helpers" - depends on FB - default n - ---help--- - This enables functions for handling video modes using the - Generalized Timing Formula and the EDID parser. A few drivers rely - on this feature such as the radeonfb, rivafb, and the i810fb. If - your driver does not take advantage of this feature, choosing Y will - just increase the kernel size by about 5K. - -config FB_TILEBLITTING - bool "Enable Tile Blitting Support" - depends on FB - default n - ---help--- - This enables tile blitting. Tile blitting is a drawing technique - where the screen is divided into rectangular sections (tiles), whereas - the standard blitting divides the screen into pixels. Because the - default drawing element is a tile, drawing functions will be passed - parameters in terms of number of tiles instead of number of pixels. - For example, to draw a single character, instead of using bitmaps, - an index to an array of bitmaps will be used. To clear or move a - rectangular section of a screen, the rectangle will be described in - terms of number of tiles in the x- and y-axis. - - This is particularly important to one driver, matroxfb. If - unsure, say N. - -comment "Frame buffer hardware drivers" - depends on FB - -config FB_GRVGA - tristate "Aeroflex Gaisler framebuffer support" - depends on FB && SPARC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler. - -config FB_CIRRUS - tristate "Cirrus Logic support" - depends on FB && (ZORRO || PCI) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - This enables support for Cirrus Logic GD542x/543x based boards on - Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. - - If you have a PCI-based system, this enables support for these - chips: GD-543x, GD-544x, GD-5480. - - Please read the file . - - Say N unless you have such a graphics board or plan to get one - before you next recompile the kernel. - -config FB_PM2 - tristate "Permedia2 support" - depends on FB && ((AMIGA && BROKEN) || PCI) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for cards based on - the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. - The driver was tested on the following cards: - Diamond FireGL 1000 PRO AGP - ELSA Gloria Synergy PCI - Appian Jeronimo PRO (both heads) PCI - 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI - Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC - ASK Graphic Blaster Exxtreme AGP - - To compile this driver as a module, choose M here: the - module will be called pm2fb. - -config FB_PM2_FIFO_DISCONNECT - bool "enable FIFO disconnect feature" - depends on FB_PM2 && PCI - help - Support the Permedia2 FIFO disconnect feature. - -config FB_ARMCLCD - tristate "ARM PrimeCell PL110 support" - depends on ARM || ARM64 || COMPILE_TEST - depends on FB && ARM_AMBA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This framebuffer device driver is for the ARM PrimeCell PL110 - Colour LCD controller. ARM PrimeCells provide the building - blocks for System on a Chip devices. - - If you want to compile this as a module (=code which can be - inserted into and removed from the running kernel), say M - here and read . The module - will be called amba-clcd. - -config FB_ACORN - bool "Acorn VIDC support" - depends on (FB = y) && ARM && ARCH_ACORN - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Acorn VIDC graphics - hardware found in Acorn RISC PCs and other ARM-based machines. If - unsure, say N. - -config FB_CLPS711X - bool "CLPS711X LCD support" - depends on (FB = y) && ARM && ARCH_CLPS711X - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Say Y to enable the Framebuffer driver for the CLPS7111 and - EP7212 processors. - -config FB_SA1100 - bool "SA-1100 LCD support" - depends on (FB = y) && ARM && ARCH_SA1100 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is a framebuffer device for the SA-1100 LCD Controller. - See for information on framebuffer - devices. - - If you plan to use the LCD display with your SA-1100 system, say - Y here. - -config FB_IMX - tristate "Freescale i.MX1/21/25/27 LCD support" - depends on FB && ARCH_MXC - select BACKLIGHT_LCD_SUPPORT - select LCD_CLASS_DEVICE - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - -config FB_CYBER2000 - tristate "CyberPro 2000/2010/5000 support" - depends on FB && PCI && (BROKEN || !SPARC64) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This enables support for the Integraphics CyberPro 20x0 and 5000 - VGA chips used in the Rebel.com Netwinder and other machines. - Say Y if you have a NetWinder or a graphics card containing this - device, otherwise say N. - -config FB_CYBER2000_DDC - bool "DDC for CyberPro support" - depends on FB_CYBER2000 - select FB_DDC - default y - help - Say Y here if you want DDC support for your CyberPro graphics - card. This is only I2C bus support, driver does not use EDID. - -config FB_CYBER2000_I2C - bool "CyberPro 2000/2010/5000 I2C support" - depends on FB_CYBER2000 && I2C && ARCH_NETWINDER - select I2C_ALGOBIT - help - Enable support for the I2C video decoder interface on the - Integraphics CyberPro 20x0 and 5000 VGA chips. This is used - on the Netwinder machines for the SAA7111 video capture. - -config FB_APOLLO - bool - depends on (FB = y) && APOLLO - default y - select FB_CFB_FILLRECT - select FB_CFB_IMAGEBLIT - -config FB_Q40 - bool - depends on (FB = y) && Q40 - default y - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - -config FB_AMIGA - tristate "Amiga native chipset support" - depends on FB && AMIGA - help - This is the frame buffer device driver for the builtin graphics - chipset found in Amigas. - - To compile this driver as a module, choose M here: the - module will be called amifb. - -config FB_AMIGA_OCS - bool "Amiga OCS chipset support" - depends on FB_AMIGA - help - This enables support for the original Agnus and Denise video chips, - found in the Amiga 1000 and most A500's and A2000's. If you intend - to run Linux on any of these systems, say Y; otherwise say N. - -config FB_AMIGA_ECS - bool "Amiga ECS chipset support" - depends on FB_AMIGA - help - This enables support for the Enhanced Chip Set, found in later - A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If - you intend to run Linux on any of these systems, say Y; otherwise - say N. - -config FB_AMIGA_AGA - bool "Amiga AGA chipset support" - depends on FB_AMIGA - help - This enables support for the Advanced Graphics Architecture (also - known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T - and CD32. If you intend to run Linux on any of these systems, say Y; - otherwise say N. - -config FB_FM2 - bool "Amiga FrameMaster II/Rainbow II support" - depends on (FB = y) && ZORRO - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Amiga FrameMaster - card from BSC (exhibited 1992 but not shipped as a CBM product). - -config FB_ARC - tristate "Arc Monochrome LCD board support" - depends on FB && X86 - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - help - This enables support for the Arc Monochrome LCD board. The board - is based on the KS-108 lcd controller and is typically a matrix - of 2*n chips. This driver was tested with a 128x64 panel. This - driver supports it for use with x86 SBCs through a 16 bit GPIO - interface (8 bit data, 8 bit control). If you anticipate using - this driver, say Y or M; otherwise say N. You must specify the - GPIO IO address to be used for setting control and data. - -config FB_ATARI - bool "Atari native chipset support" - depends on (FB = y) && ATARI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the builtin graphics - chipset found in Ataris. - -config FB_OF - bool "Open Firmware frame buffer device support" - depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES - help - Say Y if you want support with Open Firmware for your graphics - board. - -config FB_CONTROL - bool "Apple \"control\" display support" - depends on (FB = y) && PPC_PMAC && PPC32 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES - help - This driver supports a frame buffer for the graphics adapter in the - Power Macintosh 7300 and others. - -config FB_PLATINUM - bool "Apple \"platinum\" display support" - depends on (FB = y) && PPC_PMAC && PPC32 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES - help - This driver supports a frame buffer for the "platinum" graphics - adapter in some Power Macintoshes. - -config FB_VALKYRIE - bool "Apple \"valkyrie\" display support" - depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES - help - This driver supports a frame buffer for the "valkyrie" graphics - adapter in some Power Macintoshes. - -config FB_CT65550 - bool "Chips 65550 display support" - depends on (FB = y) && PPC32 && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Chips & Technologies - 65550 graphics chip in PowerBooks. - -config FB_ASILIANT - bool "Asiliant (Chips) 69000 display support" - depends on (FB = y) && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Asiliant 69030 chipset - -config FB_IMSTT - bool "IMS Twin Turbo display support" - depends on (FB = y) && PCI - select FB_CFB_IMAGEBLIT - select FB_MACMODES if PPC - help - The IMS Twin Turbo is a PCI-based frame buffer card bundled with - many Macintosh and compatible computers. - -config FB_VGA16 - tristate "VGA 16-color graphics support" - depends on FB && (X86 || PPC) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VGASTATE - select FONT_8x16 if FRAMEBUFFER_CONSOLE - help - This is the frame buffer device driver for VGA 16 color graphic - cards. Say Y if you have such a card. - - To compile this driver as a module, choose M here: the - module will be called vga16fb. - -config FB_BF54X_LQ043 - tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)" - depends on FB && (BF54x) && !BF542 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD - -config FB_BFIN_T350MCQB - tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)" - depends on FB && BLACKFIN - select BFIN_GPTIMERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD - This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI - It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. - -config FB_BFIN_LQ035Q1 - tristate "SHARP LQ035Q1DH02 TFT LCD" - depends on FB && BLACKFIN && SPI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select BFIN_GPTIMERS - help - This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on - the Blackfin Landscape LCD EZ-Extender Card. - This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI - It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK. - - To compile this driver as a module, choose M here: the - module will be called bfin-lq035q1-fb. - -config FB_BF537_LQ035 - tristate "SHARP LQ035 TFT LCD (BF537 STAMP)" - depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select BFIN_GPTIMERS - help - This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD - attached to a BF537. - - To compile this driver as a module, choose M here: the - module will be called bf537-lq035. - -config FB_BFIN_7393 - tristate "Blackfin ADV7393 Video encoder" - depends on FB && BLACKFIN - select I2C - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for a ADV7393 video encoder - attached to a Blackfin on the PPI port. - If your Blackfin board has a ADV7393 select Y. - - To compile this driver as a module, choose M here: the - module will be called bfin_adv7393fb. - -choice - prompt "Video mode support" - depends on FB_BFIN_7393 - default NTSC - -config NTSC - bool 'NTSC 720x480' - -config PAL - bool 'PAL 720x576' - -config NTSC_640x480 - bool 'NTSC 640x480 (Experimental)' - -config PAL_640x480 - bool 'PAL 640x480 (Experimental)' - -config NTSC_YCBCR - bool 'NTSC 720x480 YCbCR input' - -config PAL_YCBCR - bool 'PAL 720x576 YCbCR input' - -endchoice - -choice - prompt "Size of ADV7393 frame buffer memory Single/Double Size" - depends on (FB_BFIN_7393) - default ADV7393_1XMEM - -config ADV7393_1XMEM - bool 'Single' - -config ADV7393_2XMEM - bool 'Double' -endchoice - -config FB_STI - tristate "HP STI frame buffer device support" - depends on FB && PARISC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select STI_CONSOLE - select VT - default y - ---help--- - STI refers to the HP "Standard Text Interface" which is a set of - BIOS routines contained in a ROM chip in HP PA-RISC based machines. - Enabling this option will implement the linux framebuffer device - using calls to the STI BIOS routines for initialisation. - - If you enable this option, you will get a planar framebuffer device - /dev/fb which will work on the most common HP graphic cards of the - NGLE family, including the artist chips (in the 7xx and Bxxx series), - HCRX, HCRX24, CRX, CRX24 and VisEG series. - - It is safe to enable this option, so you should probably say "Y". - -config FB_MAC - bool "Generic Macintosh display support" - depends on (FB = y) && MAC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES - -config FB_HP300 - bool - depends on (FB = y) && DIO - select FB_CFB_IMAGEBLIT - default y - -config FB_TGA - tristate "TGA/SFB+ framebuffer support" - depends on FB && (ALPHA || TC) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select BITREVERSE - ---help--- - This is the frame buffer device driver for generic TGA and SFB+ - graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards, - also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3 - TURBOchannel cards, also known as PMAGD-A, -B and -C. - - Due to hardware limitations ZLX-E2 and E3 cards are not supported - for DECstation 5000/200 systems. Additionally due to firmware - limitations these cards may cause troubles with booting DECstation - 5000/240 and /260 systems, but are fully supported under Linux if - you manage to get it going. ;-) - - Say Y if you have one of those. - -config FB_UVESA - tristate "Userspace VESA VGA graphics support" - depends on FB && CONNECTOR - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MODE_HELPERS - help - This is the frame buffer driver for generic VBE 2.0 compliant - graphic cards. It can also take advantage of VBE 3.0 features, - such as refresh rate adjustment. - - This driver generally provides more features than vesafb but - requires a userspace helper application called 'v86d'. See - for more information. - - If unsure, say N. - -config FB_VESA - bool "VESA VGA graphics support" - depends on (FB = y) && X86 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_BOOT_VESA_SUPPORT - help - This is the frame buffer device driver for generic VESA 2.0 - compliant graphic cards. The older VESA 1.2 cards are not supported. - You will get a boot time penguin logo at no additional cost. Please - read . If unsure, say Y. - -config FB_EFI - bool "EFI-based Framebuffer Support" - depends on (FB = y) && X86 && EFI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the EFI frame buffer device driver. If the firmware on - your platform is EFI 1.10 or UEFI 2.0, select Y to add support for - using the EFI framebuffer as your console. - -config FB_N411 - tristate "N411 Apollo/Hecuba devkit support" - depends on FB && X86 && MMU - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - select FB_HECUBA - help - This enables support for the Apollo display controller in its - Hecuba form using the n411 devkit. - -config FB_HGA - tristate "Hercules mono graphics support" - depends on FB && X86 - help - Say Y here if you have a Hercules mono graphics card. - - To compile this driver as a module, choose M here: the - module will be called hgafb. - - As this card technology is at least 25 years old, - most people will answer N here. - -config FB_GBE - bool "SGI Graphics Backend frame buffer support" - depends on (FB = y) && SGI_IP32 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for SGI Graphics Backend. - This chip is used in SGI O2 and Visual Workstation 320/540. - -config FB_GBE_MEM - int "Video memory size in MB" - depends on FB_GBE - default 4 - help - This is the amount of memory reserved for the framebuffer, - which can be any value between 1MB and 8MB. - -config FB_SBUS - bool "SBUS and UPA framebuffers" - depends on (FB = y) && SPARC - help - Say Y if you want support for SBUS or UPA based frame buffer device. - -config FB_BW2 - bool "BWtwo support" - depends on (FB = y) && (SPARC && FB_SBUS) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the BWtwo frame buffer. - -config FB_CG3 - bool "CGthree support" - depends on (FB = y) && (SPARC && FB_SBUS) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the CGthree frame buffer. - -config FB_CG6 - bool "CGsix (GX,TurboGX) support" - depends on (FB = y) && (SPARC && FB_SBUS) - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the CGsix (GX, TurboGX) - frame buffer. - -config FB_FFB - bool "Creator/Creator3D/Elite3D support" - depends on FB_SBUS && SPARC64 - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Creator, Creator3D, - and Elite3D graphics boards. - -config FB_TCX - bool "TCX (SS4/SS5 only) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the TCX 24/8bit frame - buffer. - -config FB_CG14 - bool "CGfourteen (SX) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the CGfourteen frame - buffer on Desktop SPARCsystems with the SX graphics option. - -config FB_P9100 - bool "P9100 (Sparcbook 3 only) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the P9100 card - supported on Sparcbook 3 machines. - -config FB_LEO - bool "Leo (ZX) support" - depends on FB_SBUS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the SBUS-based Sun ZX - (leo) frame buffer cards. - -config FB_IGA - bool "IGA 168x display support" - depends on (FB = y) && SPARC32 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the INTERGRAPHICS 1680 and - successor frame buffer cards. - -config FB_XVR500 - bool "Sun XVR-500 3DLABS Wildcat support" - depends on (FB = y) && PCI && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-500 and similar - graphics cards based upon the 3DLABS Wildcat chipset. The driver - only works on sparc64 systems where the system firmware has - mostly initialized the card already. It is treated as a - completely dumb framebuffer device. - -config FB_XVR2500 - bool "Sun XVR-2500 3DLABS Wildcat support" - depends on (FB = y) && PCI && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-2500 and similar - graphics cards based upon the 3DLABS Wildcat chipset. The driver - only works on sparc64 systems where the system firmware has - mostly initialized the card already. It is treated as a - completely dumb framebuffer device. - -config FB_XVR1000 - bool "Sun XVR-1000 support" - depends on (FB = y) && SPARC64 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer device for the Sun XVR-1000 and similar - graphics cards. The driver only works on sparc64 systems where - the system firmware has mostly initialized the card already. It - is treated as a completely dumb framebuffer device. - -config FB_PVR2 - tristate "NEC PowerVR 2 display support" - depends on FB && SH_DREAMCAST - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Say Y here if you have a PowerVR 2 card in your box. If you plan to - run linux on your Dreamcast, you will have to say Y here. - This driver may or may not work on other PowerVR 2 cards, but is - totally untested. Use at your own risk. If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called pvr2fb. - - You can pass several parameters to the driver at boot time or at - module load time. The parameters look like "video=pvr2:XXX", where - the meaning of XXX can be found at the end of the main source file - (). Please see the file - . - -config FB_OPENCORES - tristate "OpenCores VGA/LCD core 2.0 framebuffer support" - depends on FB && HAS_DMA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This enables support for the OpenCores VGA/LCD core. - - The OpenCores VGA/LCD core is typically used together with - softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor - systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs. - - The source code and specification for the core is available at - - -config FB_S1D13XXX - tristate "Epson S1D13XXX framebuffer support" - depends on FB - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for S1D13XXX framebuffer device family (currently only - working with S1D13806). Product specs at - - -config FB_ATMEL - tristate "AT91/AT32 LCD Controller support" - depends on FB && HAVE_FB_ATMEL - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - help - This enables support for the AT91/AT32 LCD Controller. - -config FB_INTSRAM - bool "Frame Buffer in internal SRAM" - depends on FB_ATMEL && ARCH_AT91SAM9261 - help - Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want - to let frame buffer in external SDRAM. - -config FB_ATMEL_STN - bool "Use a STN display with AT91/AT32 LCD Controller" - depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) - default n - help - Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD - Controller. Say N if you want to connect a TFT. - - If unsure, say N. - -config FB_NVIDIA - tristate "nVidia Framebuffer Support" - depends on FB && PCI - select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select BITREVERSE - select VGASTATE - help - This driver supports graphics boards with the nVidia chips, TNT - and newer. For very old chipsets, such as the RIVA128, then use - the rivafb. - Say Y if you have such a graphics board. - - To compile this driver as a module, choose M here: the - module will be called nvidiafb. - -config FB_NVIDIA_I2C - bool "Enable DDC Support" - depends on FB_NVIDIA - select FB_DDC - help - This enables I2C support for nVidia Chipsets. This is used - only for getting EDID information from the attached display - allowing for robust video mode handling and switching. - - Because fbdev-2.6 requires that drivers must be able to - independently validate video mode parameters, you should say Y - here. - -config FB_NVIDIA_DEBUG - bool "Lots of debug output" - depends on FB_NVIDIA - default n - help - Say Y here if you want the nVidia driver to output all sorts - of debugging information to provide to the maintainer when - something goes wrong. - -config FB_NVIDIA_BACKLIGHT - bool "Support for backlight control" - depends on FB_NVIDIA - default y - help - Say Y here if you want to control the backlight of your display. - -config FB_RIVA - tristate "nVidia Riva support" - depends on FB && PCI - select FB_BACKLIGHT if FB_RIVA_BACKLIGHT - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select BITREVERSE - select VGASTATE - help - This driver supports graphics boards with the nVidia Riva/Geforce - chips. - Say Y if you have such a graphics board. - - To compile this driver as a module, choose M here: the - module will be called rivafb. - -config FB_RIVA_I2C - bool "Enable DDC Support" - depends on FB_RIVA - select FB_DDC - help - This enables I2C support for nVidia Chipsets. This is used - only for getting EDID information from the attached display - allowing for robust video mode handling and switching. - - Because fbdev-2.6 requires that drivers must be able to - independently validate video mode parameters, you should say Y - here. - -config FB_RIVA_DEBUG - bool "Lots of debug output" - depends on FB_RIVA - default n - help - Say Y here if you want the Riva driver to output all sorts - of debugging information to provide to the maintainer when - something goes wrong. - -config FB_RIVA_BACKLIGHT - bool "Support for backlight control" - depends on FB_RIVA - default y - help - Say Y here if you want to control the backlight of your display. - -config FB_I740 - tristate "Intel740 support" - depends on FB && PCI - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VGASTATE - select FB_DDC - help - This driver supports graphics cards based on Intel740 chip. - -config FB_I810 - tristate "Intel 810/815 support" - depends on FB && PCI && X86_32 && AGP_INTEL - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VGASTATE - help - This driver supports the on-board graphics built in to the Intel 810 - and 815 chipsets. Say Y if you have and plan to use such a board. - - To compile this driver as a module, choose M here: the - module will be called i810fb. - - For more information, please read - - -config FB_I810_GTF - bool "use VESA Generalized Timing Formula" - depends on FB_I810 - help - If you say Y, then the VESA standard, Generalized Timing Formula - or GTF, will be used to calculate the required video timing values - per video mode. Since the GTF allows nondiscrete timings - (nondiscrete being a range of values as opposed to discrete being a - set of values), you'll be able to use any combination of horizontal - and vertical resolutions, and vertical refresh rates without having - to specify your own timing parameters. This is especially useful - to maximize the performance of an aging display, or if you just - have a display with nonstandard dimensions. A VESA compliant - monitor is recommended, but can still work with non-compliant ones. - If you need or want this, then select this option. The timings may - not be compliant with Intel's recommended values. Use at your own - risk. - - If you say N, the driver will revert to discrete video timings - using a set recommended by Intel in their documentation. - - If unsure, say N. - -config FB_I810_I2C - bool "Enable DDC Support" - depends on FB_I810 && FB_I810_GTF - select FB_DDC - help - -config FB_LE80578 - tristate "Intel LE80578 (Vermilion) support" - depends on FB && PCI && X86 - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This driver supports the LE80578 (Vermilion Range) chipset - -config FB_CARILLO_RANCH - tristate "Intel Carillo Ranch support" - depends on FB_LE80578 && FB && PCI && X86 - help - This driver supports the LE80578 (Carillo Ranch) board - -config FB_INTEL - tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" - depends on FB && PCI && X86 && AGP_INTEL && EXPERT - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_BOOT_VESA_SUPPORT if FB_INTEL = y - depends on !DRM_I915 - help - This driver supports the on-board graphics built in to the Intel - 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. - Say Y if you have and plan to use such a board. - - To make FB_INTELFB=Y work you need to say AGP_INTEL=y too. - - To compile this driver as a module, choose M here: the - module will be called intelfb. - - For more information, please read - -config FB_INTEL_DEBUG - bool "Intel driver Debug Messages" - depends on FB_INTEL - ---help--- - Say Y here if you want the Intel driver to output all sorts - of debugging information to provide to the maintainer when - something goes wrong. - -config FB_INTEL_I2C - bool "DDC/I2C for Intel framebuffer support" - depends on FB_INTEL - select FB_DDC - default y - help - Say Y here if you want DDC/I2C support for your on-board Intel graphics. - -config FB_MATROX - tristate "Matrox acceleration" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_TILEBLITTING - select FB_MACMODES if PPC_PMAC - ---help--- - Say Y here if you have a Matrox Millennium, Matrox Millennium II, - Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox - Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video, - Matrox G400, G450 or G550 card in your box. - - To compile this driver as a module, choose M here: the - module will be called matroxfb. - - You can pass several parameters to the driver at boot time or at - module load time. The parameters look like "video=matroxfb:XXX", and - are described in . - -config FB_MATROX_MILLENIUM - bool "Millennium I/II support" - depends on FB_MATROX - help - Say Y here if you have a Matrox Millennium or Matrox Millennium II - video card. If you select "Advanced lowlevel driver options" below, - you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp - packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can - also use font widths different from 8. - -config FB_MATROX_MYSTIQUE - bool "Mystique support" - depends on FB_MATROX - help - Say Y here if you have a Matrox Mystique or Matrox Mystique 220 - video card. If you select "Advanced lowlevel driver options" below, - you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp - packed pixel and 32 bpp packed pixel. You can also use font widths - different from 8. - -config FB_MATROX_G - bool "G100/G200/G400/G450/G550 support" - depends on FB_MATROX - ---help--- - Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based - video card. If you select "Advanced lowlevel driver options", you - should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed - pixel and 32 bpp packed pixel. You can also use font widths - different from 8. - - If you need support for G400 secondary head, you must say Y to - "Matrox I2C support" and "G400 second head support" right below. - G450/G550 secondary head and digital output are supported without - additional modules. - - The driver starts in monitor mode. You must use the matroxset tool - (available at ) to - swap primary and secondary head outputs, or to change output mode. - Secondary head driver always start in 640x480 resolution and you - must use fbset to change it. - - Do not forget that second head supports only 16 and 32 bpp - packed pixels, so it is a good idea to compile them into the kernel - too. You can use only some font widths, as the driver uses generic - painting procedures (the secondary head does not use acceleration - engine). - - G450/G550 hardware can display TV picture only from secondary CRTC, - and it performs no scaling, so picture must have 525 or 625 lines. - -config FB_MATROX_I2C - tristate "Matrox I2C support" - depends on FB_MATROX - select FB_DDC - ---help--- - This drivers creates I2C buses which are needed for accessing the - DDC (I2C) bus present on all Matroxes, an I2C bus which - interconnects Matrox optional devices, like MGA-TVO on G200 and - G400, and the secondary head DDC bus, present on G400 only. - - You can say Y or M here if you want to experiment with monitor - detection code. You must say Y or M here if you want to use either - second head of G400 or MGA-TVO on G200 or G400. - - If you compile it as module, it will create a module named - i2c-matroxfb. - -config FB_MATROX_MAVEN - tristate "G400 second head support" - depends on FB_MATROX_G && FB_MATROX_I2C - ---help--- - WARNING !!! This support does not work with G450 !!! - - Say Y or M here if you want to use a secondary head (meaning two - monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary - head is not compatible with accelerated XFree 3.3.x SVGA servers - - secondary head output is blanked while you are in X. With XFree - 3.9.17 preview you can use both heads if you use SVGA over fbdev or - the fbdev driver on first head and the fbdev driver on second head. - - If you compile it as module, two modules are created, - matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for - both G200 and G400, matroxfb_crtc2 is needed only by G400. You must - also load i2c-matroxfb to get it to run. - - The driver starts in monitor mode and you must use the matroxset - tool (available at - ) to switch it to - PAL or NTSC or to swap primary and secondary head outputs. - Secondary head driver also always start in 640x480 resolution, you - must use fbset to change it. - - Also do not forget that second head supports only 16 and 32 bpp - packed pixels, so it is a good idea to compile them into the kernel - too. You can use only some font widths, as the driver uses generic - painting procedures (the secondary head does not use acceleration - engine). - -config FB_RADEON - tristate "ATI Radeon display support" - depends on FB && PCI - select FB_BACKLIGHT if FB_RADEON_BACKLIGHT - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MACMODES if PPC_OF - help - Choose this option if you want to use an ATI Radeon graphics card as - a framebuffer device. There are both PCI and AGP versions. You - don't need to choose this to run the Radeon in plain VGA mode. - - There is a product page at - http://products.amd.com/en-us/GraphicCardResult.aspx - -config FB_RADEON_I2C - bool "DDC/I2C for ATI Radeon support" - depends on FB_RADEON - select FB_DDC - default y - help - Say Y here if you want DDC/I2C support for your Radeon board. - -config FB_RADEON_BACKLIGHT - bool "Support for backlight control" - depends on FB_RADEON - default y - help - Say Y here if you want to control the backlight of your display. - -config FB_RADEON_DEBUG - bool "Lots of debug output from Radeon driver" - depends on FB_RADEON - default n - help - Say Y here if you want the Radeon driver to output all sorts - of debugging information to provide to the maintainer when - something goes wrong. - -config FB_ATY128 - tristate "ATI Rage128 display support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_BACKLIGHT if FB_ATY128_BACKLIGHT - select FB_MACMODES if PPC_PMAC - help - This driver supports graphics boards with the ATI Rage128 chips. - Say Y if you have such a graphics board and read - . - - To compile this driver as a module, choose M here: the - module will be called aty128fb. - -config FB_ATY128_BACKLIGHT - bool "Support for backlight control" - depends on FB_ATY128 - default y - help - Say Y here if you want to control the backlight of your display. - -config FB_ATY - tristate "ATI Mach64 display support" if PCI || ATARI - depends on FB && !SPARC32 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_BACKLIGHT if FB_ATY_BACKLIGHT - select FB_MACMODES if PPC - help - This driver supports graphics boards with the ATI Mach64 chips. - Say Y if you have such a graphics board. - - To compile this driver as a module, choose M here: the - module will be called atyfb. - -config FB_ATY_CT - bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" - depends on PCI && FB_ATY - default y if SPARC64 && PCI - help - Say Y here to support use of ATI's 64-bit Rage boards (or other - boards based on the Mach64 CT, VT, GT, and LT chipsets) as a - framebuffer device. The ATI product support page for these boards - is at . - -config FB_ATY_GENERIC_LCD - bool "Mach64 generic LCD support" - depends on FB_ATY_CT - help - Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, - Rage XC, or Rage XL chipset. - -config FB_ATY_GX - bool "Mach64 GX support" if PCI - depends on FB_ATY - default y if ATARI - help - Say Y here to support use of the ATI Mach64 Graphics Expression - board (or other boards based on the Mach64 GX chipset) as a - framebuffer device. The ATI product support page for these boards - is at - . - -config FB_ATY_BACKLIGHT - bool "Support for backlight control" - depends on FB_ATY - default y - help - Say Y here if you want to control the backlight of your display. - -config FB_S3 - tristate "S3 Trio/Virge support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_TILEBLITTING - select FB_SVGALIB - select VGASTATE - select FONT_8x16 if FRAMEBUFFER_CONSOLE - ---help--- - Driver for graphics boards with S3 Trio / S3 Virge chip. - -config FB_S3_DDC - bool "DDC for S3 support" - depends on FB_S3 - select FB_DDC - default y - help - Say Y here if you want DDC support for your S3 graphics card. - -config FB_SAVAGE - tristate "S3 Savage support" - depends on FB && PCI - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VGASTATE - help - This driver supports notebooks and computers with S3 Savage PCI/AGP - chips. - - Say Y if you have such a graphics card. - - To compile this driver as a module, choose M here; the module - will be called savagefb. - -config FB_SAVAGE_I2C - bool "Enable DDC2 Support" - depends on FB_SAVAGE - select FB_DDC - help - This enables I2C support for S3 Savage Chipsets. This is used - only for getting EDID information from the attached display - allowing for robust video mode handling and switching. - - Because fbdev-2.6 requires that drivers must be able to - independently validate video mode parameters, you should say Y - here. - -config FB_SAVAGE_ACCEL - bool "Enable Console Acceleration" - depends on FB_SAVAGE - default n - help - This option will compile in console acceleration support. If - the resulting framebuffer console has bothersome glitches, then - choose N here. - -config FB_SIS - tristate "SiS/XGI display support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_BOOT_VESA_SUPPORT if FB_SIS = y - help - This is the frame buffer device driver for the SiS 300, 315, 330 - and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. - Specs available at and . - - To compile this driver as a module, choose M here; the module - will be called sisfb. - -config FB_SIS_300 - bool "SiS 300 series support" - depends on FB_SIS - help - Say Y here to support use of the SiS 300/305, 540, 630 and 730. - -config FB_SIS_315 - bool "SiS 315/330/340 series and XGI support" - depends on FB_SIS - help - Say Y here to support use of the SiS 315, 330 and 340 series - (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well - as XGI V3XT, V5, V8 and Z7. - -config FB_VIA - tristate "VIA UniChrome (Pro) and Chrome9 display support" - depends on FB && PCI && X86 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select I2C_ALGOBIT - select I2C - select GPIOLIB - help - This is the frame buffer device driver for Graphics chips of VIA - UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ - CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 - /P4M900,VX800) - Say Y if you have a VIA UniChrome graphics board. - - To compile this driver as a module, choose M here: the - module will be called viafb. - -if FB_VIA - -config FB_VIA_DIRECT_PROCFS - bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)" - depends on FB_VIA - default n - help - Allow direct hardware access to some output registers via procfs. - This is dangerous but may provide the only chance to get the - correct output device configuration. - Its use is strongly discouraged. - -config FB_VIA_X_COMPATIBILITY - bool "X server compatibility" - depends on FB_VIA - default n - help - This option reduces the functionality (power saving, ...) of the - framebuffer to avoid negative impact on the OpenChrome X server. - If you use any X server other than fbdev you should enable this - otherwise it should be safe to disable it and allow using all - features. - -endif - -config FB_NEOMAGIC - tristate "NeoMagic display support" - depends on FB && PCI - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select VGASTATE - help - This driver supports notebooks with NeoMagic PCI chips. - Say Y if you have such a graphics card. - - To compile this driver as a module, choose M here: the - module will be called neofb. - -config FB_KYRO - tristate "IMG Kyro support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Say Y here if you have a STG4000 / Kyro / PowerVR 3 based - graphics board. - - To compile this driver as a module, choose M here: the - module will be called kyrofb. - -config FB_3DFX - tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" - depends on FB && PCI - select FB_CFB_IMAGEBLIT - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_MODE_HELPERS - help - This driver supports graphics boards with the 3Dfx Banshee, - Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have - such a graphics board. - - To compile this driver as a module, choose M here: the - module will be called tdfxfb. - -config FB_3DFX_ACCEL - bool "3Dfx Acceleration functions" - depends on FB_3DFX - ---help--- - This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer - device driver with acceleration functions. - -config FB_3DFX_I2C - bool "Enable DDC/I2C support" - depends on FB_3DFX - select FB_DDC - default y - help - Say Y here if you want DDC/I2C support for your 3dfx Voodoo3. - -config FB_VOODOO1 - tristate "3Dfx Voodoo Graphics (sst1) support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or - Voodoo2 (cvg) based graphics card. - - To compile this driver as a module, choose M here: the - module will be called sstfb. - - WARNING: Do not use any application that uses the 3D engine - (namely glide) while using this driver. - Please read the for supported - options and other important info support. - -config FB_VT8623 - tristate "VIA VT8623 support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_TILEBLITTING - select FB_SVGALIB - select VGASTATE - select FONT_8x16 if FRAMEBUFFER_CONSOLE - ---help--- - Driver for CastleRock integrated graphics core in the - VIA VT8623 [Apollo CLE266] chipset. - -config FB_TRIDENT - tristate "Trident/CyberXXX/CyberBlade support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - This is the frame buffer device driver for Trident PCI/AGP chipsets. - Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D - and Blade XP. - There are also integrated versions of these chips called CyberXXXX, - CyberImage or CyberBlade. These chips are mostly found in laptops - but also on some motherboards including early VIA EPIA motherboards. - For more information, read - - Say Y if you have such a graphics board. - - To compile this driver as a module, choose M here: the - module will be called tridentfb. - -config FB_ARK - tristate "ARK 2000PV support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_TILEBLITTING - select FB_SVGALIB - select VGASTATE - select FONT_8x16 if FRAMEBUFFER_CONSOLE - ---help--- - Driver for PCI graphics boards with ARK 2000PV chip - and ICS 5342 RAMDAC. - -config FB_PM3 - tristate "Permedia3 support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the 3DLabs Permedia3 - chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & - similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 - and maybe other boards. - -config FB_CARMINE - tristate "Fujitsu carmine frame buffer support" - depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Fujitsu Carmine chip. - The driver provides two independent frame buffer devices. - -choice - depends on FB_CARMINE - prompt "DRAM timing" - default FB_CARMINE_DRAM_EVAL - -config FB_CARMINE_DRAM_EVAL - bool "Eval board timings" - help - Use timings which work on the eval card. - -config CARMINE_DRAM_CUSTOM - bool "Custom board timings" - help - Use custom board timings. -endchoice - -config FB_AU1100 - bool "Au1100 LCD Driver" - depends on (FB = y) && MIPS_ALCHEMY - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the framebuffer driver for the AMD Au1100 SOC. It can drive - various panels and CRTs by passing in kernel cmd line option - au1100fb:panel=. - -config FB_AU1200 - bool "Au1200/Au1300 LCD Driver" - depends on (FB = y) && MIPS_ALCHEMY - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - help - This is the framebuffer driver for the Au1200/Au1300 SOCs. - It can drive various panels and CRTs by passing in kernel cmd line - option au1200fb:panel=. - -config FB_VT8500 - bool "VIA VT8500 framebuffer support" - depends on (FB = y) && ARM && ARCH_VT8500 - select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) - select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) - select FB_SYS_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - help - This is the framebuffer driver for VIA VT8500 integrated LCD - controller. - -config FB_WM8505 - bool "Wondermedia WM8xxx-series frame buffer support" - depends on (FB = y) && ARM && ARCH_VT8500 - select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) - select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) - select FB_SYS_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - help - This is the framebuffer driver for WonderMedia WM8xxx-series - integrated LCD controller. This driver covers the WM8505, WM8650 - and WM8850 SoCs. - -config FB_WMT_GE_ROPS - bool "VT8500/WM8xxx accelerated raster ops support" - depends on (FB = y) && (FB_VT8500 || FB_WM8505) - default n - help - This adds support for accelerated raster operations on the - VIA VT8500 and Wondermedia 85xx series SoCs. - -source "drivers/video/geode/Kconfig" - -config FB_HIT - tristate "HD64461 Frame Buffer support" - depends on FB && HD64461 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This is the frame buffer device driver for the Hitachi HD64461 LCD - frame buffer card. - -config FB_PMAG_AA - bool "PMAG-AA TURBOchannel framebuffer support" - depends on (FB = y) && TC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) - used mainly in the MIPS-based DECstation series. - -config FB_PMAG_BA - tristate "PMAG-BA TURBOchannel framebuffer support" - depends on FB && TC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) - used mainly in the MIPS-based DECstation series. - -config FB_PMAGB_B - tristate "PMAGB-B TURBOchannel framebuffer support" - depends on FB && TC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for the PMAGB-B TURBOchannel framebuffer card used mainly - in the MIPS-based DECstation series. The card is currently only - supported in 1280x1024x8 mode. - -config FB_MAXINE - bool "Maxine (Personal DECstation) onboard framebuffer support" - depends on (FB = y) && MACH_DECSTATION - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Support for the onboard framebuffer (1024x768x8) in the Personal - DECstation series (Personal DECstation 5000/20, /25, /33, /50, - Codename "Maxine"). - -config FB_G364 - bool "G364 frame buffer support" - depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - The G364 driver is the framebuffer used in MIPS Magnum 4000 and - Olivetti M700-10 systems. - -config FB_68328 - bool "Motorola 68328 native frame buffer support" - depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Say Y here if you want to support the built-in frame buffer of - the Motorola 68328 CPU family. - -config FB_PXA168 - tristate "PXA168/910 LCD framebuffer support" - depends on FB && (CPU_PXA168 || CPU_PXA910) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in LCD controller in the Marvell - MMP processor. - -config FB_PXA - tristate "PXA LCD framebuffer support" - depends on FB && ARCH_PXA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in LCD controller in the Intel - PXA2x0 processor. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called pxafb. If you want to compile it as a module, - say M here and read . - - If unsure, say N. - -config FB_PXA_OVERLAY - bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer" - default n - depends on FB_PXA && (PXA27x || PXA3xx) - -config FB_PXA_SMARTPANEL - bool "PXA Smartpanel LCD support" - default n - depends on FB_PXA - -config FB_PXA_PARAMETERS - bool "PXA LCD command line parameters" - default n - depends on FB_PXA - ---help--- - Enable the use of kernel command line or module parameters - to configure the physical properties of the LCD panel when - using the PXA LCD driver. - - This option allows you to override the panel parameters - supplied by the platform in order to support multiple - different models of flatpanel. If you will only be using a - single model of flatpanel then you can safely leave this - option disabled. - - describes the available parameters. - -config PXA3XX_GCU - tristate "PXA3xx 2D graphics accelerator driver" - depends on FB_PXA - help - Kernelspace driver for the 2D graphics controller unit (GCU) - found on PXA3xx processors. There is a counterpart driver in the - DirectFB suite, see http://www.directfb.org/ - - If you compile this as a module, it will be called pxa3xx_gcu. - -config FB_MBX - tristate "2700G LCD framebuffer support" - depends on FB && ARCH_PXA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Framebuffer driver for the Intel 2700G (Marathon) Graphics - Accelerator - -config FB_MBX_DEBUG - bool "Enable debugging info via debugfs" - depends on FB_MBX && DEBUG_FS - default n - ---help--- - Enable this if you want debugging information using the debug - filesystem (debugfs) - - If unsure, say N. - -config FB_FSL_DIU - tristate "Freescale DIU framebuffer support" - depends on FB && FSL_SOC - select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select PPC_LIB_RHEAP - ---help--- - Framebuffer driver for the Freescale SoC DIU - -config FB_W100 - tristate "W100 frame buffer support" - depends on FB && ARCH_PXA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. - It can also drive the w3220 chip found on iPAQ hx4700. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called w100fb. If you want to compile it as a module, - say M here and read . - - If unsure, say N. - -config FB_SH_MOBILE_LCDC - tristate "SuperH Mobile LCDC framebuffer support" - depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - select FB_BACKLIGHT - select SH_MIPI_DSI if SH_LCD_MIPI_DSI - ---help--- - Frame buffer driver for the on-chip SH-Mobile LCD controller. - -config FB_SH_MOBILE_HDMI - tristate "SuperH Mobile HDMI controller support" - depends on FB_SH_MOBILE_LCDC - select FB_MODE_HELPERS - select SOUND - select SND - select SND_SOC - ---help--- - Driver for the on-chip SH-Mobile HDMI controller. - -config FB_TMIO - tristate "Toshiba Mobile IO FrameBuffer support" - depends on FB && MFD_CORE - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the Toshiba Mobile IO integrated as found - on the Sharp SL-6000 series - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called tmiofb. If you want to compile it as a module, - say M here and read . - - If unsure, say N. - -config FB_TMIO_ACCELL - bool "tmiofb acceleration" - depends on FB_TMIO - default y - -config FB_S3C - tristate "Samsung S3C framebuffer support" - depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \ - ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in FB controller in the Samsung - SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, - and the S3C64XX series such as the S3C6400 and S3C6410. - - These chips all have the same basic framebuffer design with the - actual capabilities depending on the chip. For instance the S3C6400 - and S3C6410 support 4 hardware windows whereas the S3C24XX series - currently only have two. - - Currently the support is only for the S3C6400 and S3C6410 SoCs. - -config FB_S3C_DEBUG_REGWRITE - bool "Debug register writes" - depends on FB_S3C - ---help--- - Show all register writes via pr_debug() - -config FB_S3C2410 - tristate "S3C2410 LCD framebuffer support" - depends on FB && ARCH_S3C24XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in LCD controller in the Samsung - S3C2410 processor. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called s3c2410fb. If you want to compile it as a module, - say M here and read . - - If unsure, say N. -config FB_S3C2410_DEBUG - bool "S3C2410 lcd debug messages" - depends on FB_S3C2410 - help - Turn on debugging messages. Note that you can set/unset at run time - through sysfs - -config FB_NUC900 - bool "NUC900 LCD framebuffer support" - depends on FB && ARCH_W90X900 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the built-in LCD controller in the Nuvoton - NUC900 processor - -config GPM1040A0_320X240 - bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" - depends on FB_NUC900 - -config FB_SM501 - tristate "Silicon Motion SM501 framebuffer support" - depends on FB && MFD_SM501 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for the CRT and LCD controllers in the Silicon - Motion SM501. - - This driver is also available as a module ( = code which can be - inserted and removed from the running kernel whenever you want). The - module will be called sm501fb. If you want to compile it as a module, - say M here and read . - - If unsure, say N. - -config FB_SMSCUFX - tristate "SMSC UFX6000/7000 USB Framebuffer support" - depends on FB && USB - select FB_MODE_HELPERS - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - ---help--- - This is a kernel framebuffer driver for SMSC UFX USB devices. - Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and - mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000 - (USB 3.0) devices. - To compile as a module, choose M here: the module name is smscufx. - -config FB_UDL - tristate "Displaylink USB Framebuffer support" - depends on FB && USB - select FB_MODE_HELPERS - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - ---help--- - This is a kernel framebuffer driver for DisplayLink USB devices. - Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and - mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. - To compile as a module, choose M here: the module name is udlfb. - -config FB_IBM_GXT4500 - tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors" - depends on FB && PPC - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Say Y here to enable support for the IBM GXT4000P/6000P and - GXT4500P/6500P display adaptor based on Raster Engine RC1000, - found on some IBM System P (pSeries) machines. This driver - doesn't use Geometry Engine GT1000. - -config FB_PS3 - tristate "PS3 GPU framebuffer driver" - depends on FB && PS3_PS3AV - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE - ---help--- - Include support for the virtual frame buffer in the PS3 platform. - -config FB_PS3_DEFAULT_SIZE_M - int "PS3 default frame buffer size (in MiB)" - depends on FB_PS3 - default 9 - ---help--- - This is the default size (in MiB) of the virtual frame buffer in - the PS3. - The default value can be overridden on the kernel command line - using the "ps3fb" option (e.g. "ps3fb=9M"); - -config FB_XILINX - tristate "Xilinx frame buffer support" - depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Include support for the Xilinx ML300/ML403 reference design - framebuffer. ML300 carries a 640*480 LCD display on the board, - ML403 uses a standard DB15 VGA connector. - -config FB_GOLDFISH - tristate "Goldfish Framebuffer" - depends on FB && HAS_DMA - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Framebuffer driver for Goldfish Virtual Platform - -config FB_COBALT - tristate "Cobalt server LCD frame buffer support" - depends on FB && (MIPS_COBALT || MIPS_SEAD3) - -config FB_SH7760 - bool "SH7760/SH7763/SH7720/SH7721 LCDC support" - depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ - || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Support for the SH7760/SH7763/SH7720/SH7721 integrated - (D)STN/TFT LCD Controller. - Supports display resolutions up to 1024x1024 pixel, grayscale and - color operation, with depths ranging from 1 bpp to 8 bpp monochrome - and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for - panels <= 320 pixel horizontal resolution. - -config FB_DA8XX - tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" - depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_CFB_REV_PIXELS_IN_BYTE - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - ---help--- - This is the frame buffer device driver for the TI LCD controller - found on DA8xx/OMAP-L1xx/AM335x SoCs. - If unsure, say N. - -config FB_VIRTUAL - tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" - depends on FB - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - ---help--- - This is a `virtual' frame buffer device. It operates on a chunk of - unswappable kernel memory instead of on the memory of a graphics - board. This means you cannot see any output sent to this frame - buffer device, while it does consume precious memory. The main use - of this frame buffer device is testing and debugging the frame - buffer subsystem. Do NOT enable it for normal systems! To protect - the innocent, it has to be enabled explicitly at boot time using the - kernel option `video=vfb:'. - - To compile this driver as a module, choose M here: the - module will be called vfb. In order to load it, you must use - the vfb_enable=1 option. - - If unsure, say N. - -config XEN_FBDEV_FRONTEND - tristate "Xen virtual frame buffer support" - depends on FB && XEN - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC - select XEN_XENBUS_FRONTEND - default y - help - This driver implements the front-end of the Xen virtual - frame buffer driver. It communicates with a back-end - in another domain. - -config FB_METRONOME - tristate "E-Ink Metronome/8track controller support" - depends on FB - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - help - This driver implements support for the E-Ink Metronome - controller. The pre-release name for this device was 8track - and could also have been called by some vendors as PVI-nnnn. - -config FB_MB862XX - tristate "Fujitsu MB862xx GDC support" - depends on FB - depends on PCI || (OF && PPC) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. - -choice - prompt "GDC variant" - depends on FB_MB862XX - -config FB_MB862XX_PCI_GDC - bool "Carmine/Coral-P(A) GDC" - depends on PCI - ---help--- - This enables framebuffer support for Fujitsu Carmine/Coral-P(A) - PCI graphics controller devices. - -config FB_MB862XX_LIME - bool "Lime GDC" - depends on OF && PPC - select FB_FOREIGN_ENDIAN - select FB_LITTLE_ENDIAN - ---help--- - Framebuffer support for Fujitsu Lime GDC on host CPU bus. - -endchoice - -config FB_MB862XX_I2C - bool "Support I2C bus on MB862XX GDC" - depends on FB_MB862XX && I2C - default y - help - Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter - driver to support accessing I2C devices on controller's I2C bus. - These are usually some video decoder chips. - -config FB_EP93XX - tristate "EP93XX frame buffer support" - depends on FB && ARCH_EP93XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - ---help--- - Framebuffer driver for the Cirrus Logic EP93XX series of processors. - This driver is also available as a module. The module will be called - ep93xx-fb. - -config FB_PRE_INIT_FB - bool "Don't reinitialize, use bootloader's GDC/Display configuration" - depends on FB && FB_MB862XX_LIME - ---help--- - Select this option if display contents should be inherited as set by - the bootloader. - -config FB_MSM - tristate "MSM Framebuffer support" - depends on FB && ARCH_MSM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - -config FB_MX3 - tristate "MX3 Framebuffer support" - depends on FB && MX3_IPU - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default y - help - This is a framebuffer device for the i.MX31 LCD Controller. So - far only synchronous displays are supported. If you plan to use - an LCD display with your i.MX31 system, say Y here. - -config FB_BROADSHEET - tristate "E-Ink Broadsheet/Epson S1D13521 controller support" - depends on FB - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - help - This driver implements support for the E-Ink Broadsheet - controller. The release name for this device was Epson S1D13521 - and could also have been called by other names when coupled with - a bridge adapter. - -config FB_AUO_K190X - tristate "AUO-K190X EPD controller support" - depends on FB - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - select FB_DEFERRED_IO - help - Provides support for epaper controllers from the K190X series - of AUO. These controllers can be used to drive epaper displays - from Sipix. - - This option enables the common support, shared by the individual - controller drivers. You will also have to enable the driver - for the controller type used in your device. - -config FB_AUO_K1900 - tristate "AUO-K1900 EPD controller support" - depends on FB && FB_AUO_K190X - help - This driver implements support for the AUO K1900 epd-controller. - This controller can drive Sipix epaper displays but can only do - serial updates, reducing the number of possible frames per second. - -config FB_AUO_K1901 - tristate "AUO-K1901 EPD controller support" - depends on FB && FB_AUO_K190X - help - This driver implements support for the AUO K1901 epd-controller. - This controller can drive Sipix epaper displays and supports - concurrent updates, making higher frames per second possible. - -config FB_JZ4740 - tristate "JZ4740 LCD framebuffer support" - depends on FB && MACH_JZ4740 - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - help - Framebuffer support for the JZ4740 SoC. - -config FB_MXS - tristate "MXS LCD framebuffer support" - depends on FB && ARCH_MXS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - select FB_MODE_HELPERS - select VIDEOMODE_HELPERS - help - Framebuffer support for the MXS SoC. - -config FB_PUV3_UNIGFX - tristate "PKUnity v3 Unigfx framebuffer support" - depends on FB && UNICORE32 && ARCH_PUV3 - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_SYS_FOPS - help - Choose this option if you want to use the Unigfx device as a - framebuffer device. Without the support of PCI & AGP. - -config FB_HYPERV - tristate "Microsoft Hyper-V Synthetic Video support" - depends on FB && HYPERV - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - This framebuffer driver supports Microsoft Hyper-V Synthetic Video. - -config FB_SIMPLE - bool "Simple framebuffer support" - depends on (FB = y) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - help - Say Y if you want support for a simple frame-buffer. - - This driver assumes that the display hardware has been initialized - before the kernel boots, and the kernel will simply render to the - pre-allocated frame buffer surface. - - Configuration re: surface address, size, and format must be provided - through device tree, or plain old platform data. - -source "drivers/video/omap/Kconfig" -source "drivers/video/omap2/Kconfig" -source "drivers/video/exynos/Kconfig" -source "drivers/video/mmp/Kconfig" -source "drivers/video/backlight/Kconfig" - if VT source "drivers/video/console/Kconfig" endif if FB || SGI_NEWPORT_CONSOLE source "drivers/video/logo/Kconfig" -endif -config FB_SH_MOBILE_MERAM - tristate "SuperH Mobile MERAM read ahead support" - depends on (SUPERH || ARCH_SHMOBILE) - select GENERIC_ALLOCATOR - ---help--- - Enable MERAM support for the SuperH controller. - - This will allow for caching of the framebuffer to provide more - reliable access under heavy main memory bus traffic situations. - Up to 4 memory channels can be configured, allowing 4 RGB or - 2 YCbCr framebuffers to be configured. +endif -config FB_SSD1307 - tristate "Solomon SSD1307 framebuffer support" - depends on FB && I2C - depends on OF - depends on GPIOLIB - select FB_SYS_FOPS - select FB_SYS_FILLRECT - select FB_SYS_COPYAREA - select FB_SYS_IMAGEBLIT - select FB_DEFERRED_IO - select PWM - help - This driver implements support for the Solomon SSD1307 - OLED controller over I2C. endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 1be26fe10592..9ad3c17d6456 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,175 +1,11 @@ -# Makefile for the Linux video drivers. -# 5 Aug 1999, James Simmons, -# Rewritten to use lists instead of if-statements. - -# Each configuration option enables a list of files. - obj-$(CONFIG_VGASTATE) += vgastate.o obj-$(CONFIG_HDMI) += hdmi.o -obj-y += fb_notify.o -obj-$(CONFIG_FB) += fb.o -fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ - modedb.o fbcvt.o -fb-objs := $(fb-y) obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ obj-y += backlight/ -obj-$(CONFIG_EXYNOS_VIDEO) += exynos/ - -obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o -obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o -obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o -obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o -obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o -obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o -obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o -obj-$(CONFIG_FB_SVGALIB) += svgalib.o -obj-$(CONFIG_FB_MACMODES) += macmodes.o -obj-$(CONFIG_FB_DDC) += fb_ddc.o -obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o -obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o - -# Hardware specific drivers go first -obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o -obj-$(CONFIG_FB_ARC) += arcfb.o -obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o -obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o -obj-$(CONFIG_FB_GRVGA) += grvga.o -obj-$(CONFIG_FB_PM2) += pm2fb.o -obj-$(CONFIG_FB_PM3) += pm3fb.o - -obj-$(CONFIG_FB_I740) += i740fb.o -obj-$(CONFIG_FB_MATROX) += matrox/ -obj-$(CONFIG_FB_RIVA) += riva/ -obj-$(CONFIG_FB_NVIDIA) += nvidia/ -obj-$(CONFIG_FB_ATY) += aty/ macmodes.o -obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o -obj-$(CONFIG_FB_RADEON) += aty/ -obj-$(CONFIG_FB_SIS) += sis/ -obj-$(CONFIG_FB_VIA) += via/ -obj-$(CONFIG_FB_KYRO) += kyro/ -obj-$(CONFIG_FB_SAVAGE) += savage/ -obj-$(CONFIG_FB_GEODE) += geode/ -obj-$(CONFIG_FB_MBX) += mbx/ -obj-$(CONFIG_FB_NEOMAGIC) += neofb.o -obj-$(CONFIG_FB_3DFX) += tdfxfb.o -obj-$(CONFIG_FB_CONTROL) += controlfb.o -obj-$(CONFIG_FB_PLATINUM) += platinumfb.o -obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o -obj-$(CONFIG_FB_CT65550) += chipsfb.o -obj-$(CONFIG_FB_IMSTT) += imsttfb.o -obj-$(CONFIG_FB_FM2) += fm2fb.o -obj-$(CONFIG_FB_VT8623) += vt8623fb.o -obj-$(CONFIG_FB_TRIDENT) += tridentfb.o -obj-$(CONFIG_FB_LE80578) += vermilion/ -obj-$(CONFIG_FB_S3) += s3fb.o -obj-$(CONFIG_FB_ARK) += arkfb.o -obj-$(CONFIG_FB_STI) += stifb.o -obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o -obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o -obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o -obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o -obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o -obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o -obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o -obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o -obj-$(CONFIG_FB_ACORN) += acornfb.o -obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ - atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o -obj-$(CONFIG_FB_MAC) += macfb.o -obj-$(CONFIG_FB_HECUBA) += hecubafb.o -obj-$(CONFIG_FB_N411) += n411.o -obj-$(CONFIG_FB_HGA) += hgafb.o -obj-$(CONFIG_FB_XVR500) += sunxvr500.o -obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o -obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o -obj-$(CONFIG_FB_IGA) += igafb.o -obj-$(CONFIG_FB_APOLLO) += dnfb.o -obj-$(CONFIG_FB_Q40) += q40fb.o -obj-$(CONFIG_FB_TGA) += tgafb.o -obj-$(CONFIG_FB_HP300) += hpfb.o -obj-$(CONFIG_FB_G364) += g364fb.o -obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o -obj-$(CONFIG_FB_SA1100) += sa1100fb.o -obj-$(CONFIG_FB_HIT) += hitfb.o -obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o -obj-$(CONFIG_FB_PVR2) += pvr2fb.o -obj-$(CONFIG_FB_VOODOO1) += sstfb.o -obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o -obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o -obj-$(CONFIG_FB_68328) += 68328fb.o -obj-$(CONFIG_FB_GBE) += gbefb.o -obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o -obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o -obj-$(CONFIG_FB_PXA) += pxafb.o -obj-$(CONFIG_FB_PXA168) += pxa168fb.o -obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o -obj-$(CONFIG_MMP_DISP) += mmp/ -obj-$(CONFIG_FB_W100) += w100fb.o -obj-$(CONFIG_FB_TMIO) += tmiofb.o -obj-$(CONFIG_FB_AU1100) += au1100fb.o -obj-$(CONFIG_FB_AU1200) += au1200fb.o -obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o -obj-$(CONFIG_FB_WM8505) += wm8505fb.o -obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o -obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o -obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o -obj-$(CONFIG_FB_MAXINE) += maxinefb.o -obj-$(CONFIG_FB_METRONOME) += metronomefb.o -obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o -obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o -obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o -obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o -obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o -obj-$(CONFIG_FB_SH7760) += sh7760fb.o -obj-$(CONFIG_FB_IMX) += imxfb.o -obj-$(CONFIG_FB_S3C) += s3c-fb.o -obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o -obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o -obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o -obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o -obj-$(CONFIG_FB_PS3) += ps3fb.o -obj-$(CONFIG_FB_SM501) += sm501fb.o -obj-$(CONFIG_FB_UDL) += udlfb.o -obj-$(CONFIG_FB_SMSCUFX) += smscufx.o -obj-$(CONFIG_FB_XILINX) += xilinxfb.o -obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o -obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o -obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o -obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o -obj-$(CONFIG_FB_OMAP) += omap/ -obj-y += omap2/ -obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o -obj-$(CONFIG_FB_CARMINE) += carminefb.o -obj-$(CONFIG_FB_MB862XX) += mb862xx/ -obj-$(CONFIG_FB_MSM) += msm/ -obj-$(CONFIG_FB_NUC900) += nuc900fb.o -obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o -obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o -obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o -obj-$(CONFIG_FB_OPENCORES) += ocfb.o - -# Platform or fallback drivers go here -obj-$(CONFIG_FB_UVESA) += uvesafb.o -obj-$(CONFIG_FB_VESA) += vesafb.o -obj-$(CONFIG_FB_EFI) += efifb.o -obj-$(CONFIG_FB_VGA16) += vga16fb.o -obj-$(CONFIG_FB_OF) += offb.o -obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o -obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o -obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o -obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o -obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o -obj-$(CONFIG_FB_MX3) += mx3fb.o -obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o -obj-$(CONFIG_FB_MXS) += mxsfb.o -obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o -obj-$(CONFIG_FB_SIMPLE) += simplefb.o - -# the test framebuffer is last -obj-$(CONFIG_FB_VIRTUAL) += vfb.o +obj-y += fbdev/ obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o ifeq ($(CONFIG_OF),y) diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 5f65ca3d8564..026fd1215933 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -46,7 +46,7 @@ #include -#include "../sticore.h" +#include "../fbdev/sticore.h" /* switching to graphics mode */ #define BLANK 0 diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index cecd3de01c24..7da1ad03acb5 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -28,7 +28,7 @@ #include #include -#include "../sticore.h" +#include "../fbdev/sticore.h" #define STI_DRIVERVERSION "Version 0.9b" diff --git a/drivers/video/68328fb.c b/drivers/video/fbdev/68328fb.c similarity index 100% rename from drivers/video/68328fb.c rename to drivers/video/fbdev/68328fb.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig new file mode 100644 index 000000000000..e1f47272fdea --- /dev/null +++ b/drivers/video/fbdev/Kconfig @@ -0,0 +1,2474 @@ +# +# fbdev configuration +# + +menuconfig FB + tristate "Support for frame buffer devices" + ---help--- + The frame buffer device provides an abstraction for the graphics + hardware. It represents the frame buffer of some video hardware and + allows application software to access the graphics hardware through + a well-defined interface, so the software doesn't need to know + anything about the low-level (hardware register) stuff. + + Frame buffer devices work identically across the different + architectures supported by Linux and make the implementation of + application programs easier and more portable; at this point, an X + server exists which uses the frame buffer device exclusively. + On several non-X86 architectures, the frame buffer device is the + only way to use the graphics hardware. + + The device is accessed through special device nodes, usually located + in the /dev directory, i.e. /dev/fb*. + + You need an utility program called fbset to make full use of frame + buffer devices. Please read + and the Framebuffer-HOWTO at + for more + information. + + Say Y here and to the driver for your graphics board below if you + are compiling a kernel for a non-x86 architecture. + + If you are compiling for the x86 architecture, you can say Y if you + want to play with it, but it is not essential. Please note that + running graphical applications that directly touch the hardware + (e.g. an accelerated X server) and that are not frame buffer + device-aware may cause unexpected results. If unsure, say N. + +config FIRMWARE_EDID + bool "Enable firmware EDID" + depends on FB + default n + ---help--- + This enables access to the EDID transferred from the firmware. + On the i386, this is from the Video BIOS. Enable this if DDC/I2C + transfers do not work for your driver and if you are using + nvidiafb, i810fb or savagefb. + + In general, choosing Y for this option is safe. If you + experience extremely long delays while booting before you get + something on your display, try setting this to N. Matrox cards in + combination with certain motherboards and monitors are known to + suffer from this problem. + +config FB_DDC + tristate + depends on FB + select I2C_ALGOBIT + select I2C + default n + +config FB_BOOT_VESA_SUPPORT + bool + depends on FB + default n + ---help--- + If true, at least one selected framebuffer driver can take advantage + of VESA video modes set at an early boot stage via the vga= parameter. + +config FB_CFB_FILLRECT + tristate + depends on FB + default n + ---help--- + Include the cfb_fillrect function for generic software rectangle + filling. This is used by drivers that don't provide their own + (accelerated) version. + +config FB_CFB_COPYAREA + tristate + depends on FB + default n + ---help--- + Include the cfb_copyarea function for generic software area copying. + This is used by drivers that don't provide their own (accelerated) + version. + +config FB_CFB_IMAGEBLIT + tristate + depends on FB + default n + ---help--- + Include the cfb_imageblit function for generic software image + blitting. This is used by drivers that don't provide their own + (accelerated) version. + +config FB_CFB_REV_PIXELS_IN_BYTE + bool + depends on FB + default n + ---help--- + Allow generic frame-buffer functions to work on displays with 1, 2 + and 4 bits per pixel depths which has opposite order of pixels in + byte order to bytes in long order. + +config FB_SYS_FILLRECT + tristate + depends on FB + default n + ---help--- + Include the sys_fillrect function for generic software rectangle + filling. This is used by drivers that don't provide their own + (accelerated) version and the framebuffer is in system RAM. + +config FB_SYS_COPYAREA + tristate + depends on FB + default n + ---help--- + Include the sys_copyarea function for generic software area copying. + This is used by drivers that don't provide their own (accelerated) + version and the framebuffer is in system RAM. + +config FB_SYS_IMAGEBLIT + tristate + depends on FB + default n + ---help--- + Include the sys_imageblit function for generic software image + blitting. This is used by drivers that don't provide their own + (accelerated) version and the framebuffer is in system RAM. + +menuconfig FB_FOREIGN_ENDIAN + bool "Framebuffer foreign endianness support" + depends on FB + ---help--- + This menu will let you enable support for the framebuffers with + non-native endianness (e.g. Little-Endian framebuffer on a + Big-Endian machine). Most probably you don't have such hardware, + so it's safe to say "n" here. + +choice + prompt "Choice endianness support" + depends on FB_FOREIGN_ENDIAN + +config FB_BOTH_ENDIAN + bool "Support for Big- and Little-Endian framebuffers" + +config FB_BIG_ENDIAN + bool "Support for Big-Endian framebuffers only" + +config FB_LITTLE_ENDIAN + bool "Support for Little-Endian framebuffers only" + +endchoice + +config FB_SYS_FOPS + tristate + depends on FB + default n + +config FB_DEFERRED_IO + bool + depends on FB + +config FB_HECUBA + tristate + depends on FB + depends on FB_DEFERRED_IO + +config FB_SVGALIB + tristate + depends on FB + default n + ---help--- + Common utility functions useful to fbdev drivers of VGA-based + cards. + +config FB_MACMODES + tristate + depends on FB + default n + +config FB_BACKLIGHT + bool + depends on FB + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE + default n + +config FB_MODE_HELPERS + bool "Enable Video Mode Handling Helpers" + depends on FB + default n + ---help--- + This enables functions for handling video modes using the + Generalized Timing Formula and the EDID parser. A few drivers rely + on this feature such as the radeonfb, rivafb, and the i810fb. If + your driver does not take advantage of this feature, choosing Y will + just increase the kernel size by about 5K. + +config FB_TILEBLITTING + bool "Enable Tile Blitting Support" + depends on FB + default n + ---help--- + This enables tile blitting. Tile blitting is a drawing technique + where the screen is divided into rectangular sections (tiles), whereas + the standard blitting divides the screen into pixels. Because the + default drawing element is a tile, drawing functions will be passed + parameters in terms of number of tiles instead of number of pixels. + For example, to draw a single character, instead of using bitmaps, + an index to an array of bitmaps will be used. To clear or move a + rectangular section of a screen, the rectangle will be described in + terms of number of tiles in the x- and y-axis. + + This is particularly important to one driver, matroxfb. If + unsure, say N. + +comment "Frame buffer hardware drivers" + depends on FB + +config FB_GRVGA + tristate "Aeroflex Gaisler framebuffer support" + depends on FB && SPARC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler. + +config FB_CIRRUS + tristate "Cirrus Logic support" + depends on FB && (ZORRO || PCI) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + This enables support for Cirrus Logic GD542x/543x based boards on + Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. + + If you have a PCI-based system, this enables support for these + chips: GD-543x, GD-544x, GD-5480. + + Please read the file . + + Say N unless you have such a graphics board or plan to get one + before you next recompile the kernel. + +config FB_PM2 + tristate "Permedia2 support" + depends on FB && ((AMIGA && BROKEN) || PCI) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for cards based on + the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. + The driver was tested on the following cards: + Diamond FireGL 1000 PRO AGP + ELSA Gloria Synergy PCI + Appian Jeronimo PRO (both heads) PCI + 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI + Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC + ASK Graphic Blaster Exxtreme AGP + + To compile this driver as a module, choose M here: the + module will be called pm2fb. + +config FB_PM2_FIFO_DISCONNECT + bool "enable FIFO disconnect feature" + depends on FB_PM2 && PCI + help + Support the Permedia2 FIFO disconnect feature. + +config FB_ARMCLCD + tristate "ARM PrimeCell PL110 support" + depends on ARM || ARM64 || COMPILE_TEST + depends on FB && ARM_AMBA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This framebuffer device driver is for the ARM PrimeCell PL110 + Colour LCD controller. ARM PrimeCells provide the building + blocks for System on a Chip devices. + + If you want to compile this as a module (=code which can be + inserted into and removed from the running kernel), say M + here and read . The module + will be called amba-clcd. + +config FB_ACORN + bool "Acorn VIDC support" + depends on (FB = y) && ARM && ARCH_ACORN + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Acorn VIDC graphics + hardware found in Acorn RISC PCs and other ARM-based machines. If + unsure, say N. + +config FB_CLPS711X + bool "CLPS711X LCD support" + depends on (FB = y) && ARM && ARCH_CLPS711X + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y to enable the Framebuffer driver for the CLPS7111 and + EP7212 processors. + +config FB_SA1100 + bool "SA-1100 LCD support" + depends on (FB = y) && ARM && ARCH_SA1100 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is a framebuffer device for the SA-1100 LCD Controller. + See for information on framebuffer + devices. + + If you plan to use the LCD display with your SA-1100 system, say + Y here. + +config FB_IMX + tristate "Freescale i.MX1/21/25/27 LCD support" + depends on FB && ARCH_MXC + select BACKLIGHT_LCD_SUPPORT + select LCD_CLASS_DEVICE + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + +config FB_CYBER2000 + tristate "CyberPro 2000/2010/5000 support" + depends on FB && PCI && (BROKEN || !SPARC64) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the Integraphics CyberPro 20x0 and 5000 + VGA chips used in the Rebel.com Netwinder and other machines. + Say Y if you have a NetWinder or a graphics card containing this + device, otherwise say N. + +config FB_CYBER2000_DDC + bool "DDC for CyberPro support" + depends on FB_CYBER2000 + select FB_DDC + default y + help + Say Y here if you want DDC support for your CyberPro graphics + card. This is only I2C bus support, driver does not use EDID. + +config FB_CYBER2000_I2C + bool "CyberPro 2000/2010/5000 I2C support" + depends on FB_CYBER2000 && I2C && ARCH_NETWINDER + select I2C_ALGOBIT + help + Enable support for the I2C video decoder interface on the + Integraphics CyberPro 20x0 and 5000 VGA chips. This is used + on the Netwinder machines for the SAA7111 video capture. + +config FB_APOLLO + bool + depends on (FB = y) && APOLLO + default y + select FB_CFB_FILLRECT + select FB_CFB_IMAGEBLIT + +config FB_Q40 + bool + depends on (FB = y) && Q40 + default y + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + +config FB_AMIGA + tristate "Amiga native chipset support" + depends on FB && AMIGA + help + This is the frame buffer device driver for the builtin graphics + chipset found in Amigas. + + To compile this driver as a module, choose M here: the + module will be called amifb. + +config FB_AMIGA_OCS + bool "Amiga OCS chipset support" + depends on FB_AMIGA + help + This enables support for the original Agnus and Denise video chips, + found in the Amiga 1000 and most A500's and A2000's. If you intend + to run Linux on any of these systems, say Y; otherwise say N. + +config FB_AMIGA_ECS + bool "Amiga ECS chipset support" + depends on FB_AMIGA + help + This enables support for the Enhanced Chip Set, found in later + A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If + you intend to run Linux on any of these systems, say Y; otherwise + say N. + +config FB_AMIGA_AGA + bool "Amiga AGA chipset support" + depends on FB_AMIGA + help + This enables support for the Advanced Graphics Architecture (also + known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T + and CD32. If you intend to run Linux on any of these systems, say Y; + otherwise say N. + +config FB_FM2 + bool "Amiga FrameMaster II/Rainbow II support" + depends on (FB = y) && ZORRO + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Amiga FrameMaster + card from BSC (exhibited 1992 but not shipped as a CBM product). + +config FB_ARC + tristate "Arc Monochrome LCD board support" + depends on FB && X86 + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + help + This enables support for the Arc Monochrome LCD board. The board + is based on the KS-108 lcd controller and is typically a matrix + of 2*n chips. This driver was tested with a 128x64 panel. This + driver supports it for use with x86 SBCs through a 16 bit GPIO + interface (8 bit data, 8 bit control). If you anticipate using + this driver, say Y or M; otherwise say N. You must specify the + GPIO IO address to be used for setting control and data. + +config FB_ATARI + bool "Atari native chipset support" + depends on (FB = y) && ATARI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the builtin graphics + chipset found in Ataris. + +config FB_OF + bool "Open Firmware frame buffer device support" + depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + Say Y if you want support with Open Firmware for your graphics + board. + +config FB_CONTROL + bool "Apple \"control\" display support" + depends on (FB = y) && PPC_PMAC && PPC32 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + This driver supports a frame buffer for the graphics adapter in the + Power Macintosh 7300 and others. + +config FB_PLATINUM + bool "Apple \"platinum\" display support" + depends on (FB = y) && PPC_PMAC && PPC32 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + This driver supports a frame buffer for the "platinum" graphics + adapter in some Power Macintoshes. + +config FB_VALKYRIE + bool "Apple \"valkyrie\" display support" + depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + help + This driver supports a frame buffer for the "valkyrie" graphics + adapter in some Power Macintoshes. + +config FB_CT65550 + bool "Chips 65550 display support" + depends on (FB = y) && PPC32 && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Chips & Technologies + 65550 graphics chip in PowerBooks. + +config FB_ASILIANT + bool "Asiliant (Chips) 69000 display support" + depends on (FB = y) && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Asiliant 69030 chipset + +config FB_IMSTT + bool "IMS Twin Turbo display support" + depends on (FB = y) && PCI + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC + help + The IMS Twin Turbo is a PCI-based frame buffer card bundled with + many Macintosh and compatible computers. + +config FB_VGA16 + tristate "VGA 16-color graphics support" + depends on FB && (X86 || PPC) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select VGASTATE + select FONT_8x16 if FRAMEBUFFER_CONSOLE + help + This is the frame buffer device driver for VGA 16 color graphic + cards. Say Y if you have such a card. + + To compile this driver as a module, choose M here: the + module will be called vga16fb. + +config FB_BF54X_LQ043 + tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)" + depends on FB && (BF54x) && !BF542 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD + +config FB_BFIN_T350MCQB + tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)" + depends on FB && BLACKFIN + select BFIN_GPTIMERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD + This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI + It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. + +config FB_BFIN_LQ035Q1 + tristate "SHARP LQ035Q1DH02 TFT LCD" + depends on FB && BLACKFIN && SPI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select BFIN_GPTIMERS + help + This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on + the Blackfin Landscape LCD EZ-Extender Card. + This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI + It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK. + + To compile this driver as a module, choose M here: the + module will be called bfin-lq035q1-fb. + +config FB_BF537_LQ035 + tristate "SHARP LQ035 TFT LCD (BF537 STAMP)" + depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select BFIN_GPTIMERS + help + This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD + attached to a BF537. + + To compile this driver as a module, choose M here: the + module will be called bf537-lq035. + +config FB_BFIN_7393 + tristate "Blackfin ADV7393 Video encoder" + depends on FB && BLACKFIN + select I2C + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for a ADV7393 video encoder + attached to a Blackfin on the PPI port. + If your Blackfin board has a ADV7393 select Y. + + To compile this driver as a module, choose M here: the + module will be called bfin_adv7393fb. + +choice + prompt "Video mode support" + depends on FB_BFIN_7393 + default NTSC + +config NTSC + bool 'NTSC 720x480' + +config PAL + bool 'PAL 720x576' + +config NTSC_640x480 + bool 'NTSC 640x480 (Experimental)' + +config PAL_640x480 + bool 'PAL 640x480 (Experimental)' + +config NTSC_YCBCR + bool 'NTSC 720x480 YCbCR input' + +config PAL_YCBCR + bool 'PAL 720x576 YCbCR input' + +endchoice + +choice + prompt "Size of ADV7393 frame buffer memory Single/Double Size" + depends on (FB_BFIN_7393) + default ADV7393_1XMEM + +config ADV7393_1XMEM + bool 'Single' + +config ADV7393_2XMEM + bool 'Double' +endchoice + +config FB_STI + tristate "HP STI frame buffer device support" + depends on FB && PARISC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select STI_CONSOLE + select VT + default y + ---help--- + STI refers to the HP "Standard Text Interface" which is a set of + BIOS routines contained in a ROM chip in HP PA-RISC based machines. + Enabling this option will implement the linux framebuffer device + using calls to the STI BIOS routines for initialisation. + + If you enable this option, you will get a planar framebuffer device + /dev/fb which will work on the most common HP graphic cards of the + NGLE family, including the artist chips (in the 7xx and Bxxx series), + HCRX, HCRX24, CRX, CRX24 and VisEG series. + + It is safe to enable this option, so you should probably say "Y". + +config FB_MAC + bool "Generic Macintosh display support" + depends on (FB = y) && MAC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES + +config FB_HP300 + bool + depends on (FB = y) && DIO + select FB_CFB_IMAGEBLIT + default y + +config FB_TGA + tristate "TGA/SFB+ framebuffer support" + depends on FB && (ALPHA || TC) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select BITREVERSE + ---help--- + This is the frame buffer device driver for generic TGA and SFB+ + graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards, + also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3 + TURBOchannel cards, also known as PMAGD-A, -B and -C. + + Due to hardware limitations ZLX-E2 and E3 cards are not supported + for DECstation 5000/200 systems. Additionally due to firmware + limitations these cards may cause troubles with booting DECstation + 5000/240 and /260 systems, but are fully supported under Linux if + you manage to get it going. ;-) + + Say Y if you have one of those. + +config FB_UVESA + tristate "Userspace VESA VGA graphics support" + depends on FB && CONNECTOR + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + help + This is the frame buffer driver for generic VBE 2.0 compliant + graphic cards. It can also take advantage of VBE 3.0 features, + such as refresh rate adjustment. + + This driver generally provides more features than vesafb but + requires a userspace helper application called 'v86d'. See + for more information. + + If unsure, say N. + +config FB_VESA + bool "VESA VGA graphics support" + depends on (FB = y) && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_BOOT_VESA_SUPPORT + help + This is the frame buffer device driver for generic VESA 2.0 + compliant graphic cards. The older VESA 1.2 cards are not supported. + You will get a boot time penguin logo at no additional cost. Please + read . If unsure, say Y. + +config FB_EFI + bool "EFI-based Framebuffer Support" + depends on (FB = y) && X86 && EFI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the EFI frame buffer device driver. If the firmware on + your platform is EFI 1.10 or UEFI 2.0, select Y to add support for + using the EFI framebuffer as your console. + +config FB_N411 + tristate "N411 Apollo/Hecuba devkit support" + depends on FB && X86 && MMU + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + select FB_HECUBA + help + This enables support for the Apollo display controller in its + Hecuba form using the n411 devkit. + +config FB_HGA + tristate "Hercules mono graphics support" + depends on FB && X86 + help + Say Y here if you have a Hercules mono graphics card. + + To compile this driver as a module, choose M here: the + module will be called hgafb. + + As this card technology is at least 25 years old, + most people will answer N here. + +config FB_GBE + bool "SGI Graphics Backend frame buffer support" + depends on (FB = y) && SGI_IP32 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for SGI Graphics Backend. + This chip is used in SGI O2 and Visual Workstation 320/540. + +config FB_GBE_MEM + int "Video memory size in MB" + depends on FB_GBE + default 4 + help + This is the amount of memory reserved for the framebuffer, + which can be any value between 1MB and 8MB. + +config FB_SBUS + bool "SBUS and UPA framebuffers" + depends on (FB = y) && SPARC + help + Say Y if you want support for SBUS or UPA based frame buffer device. + +config FB_BW2 + bool "BWtwo support" + depends on (FB = y) && (SPARC && FB_SBUS) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the BWtwo frame buffer. + +config FB_CG3 + bool "CGthree support" + depends on (FB = y) && (SPARC && FB_SBUS) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGthree frame buffer. + +config FB_CG6 + bool "CGsix (GX,TurboGX) support" + depends on (FB = y) && (SPARC && FB_SBUS) + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGsix (GX, TurboGX) + frame buffer. + +config FB_FFB + bool "Creator/Creator3D/Elite3D support" + depends on FB_SBUS && SPARC64 + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Creator, Creator3D, + and Elite3D graphics boards. + +config FB_TCX + bool "TCX (SS4/SS5 only) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the TCX 24/8bit frame + buffer. + +config FB_CG14 + bool "CGfourteen (SX) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the CGfourteen frame + buffer on Desktop SPARCsystems with the SX graphics option. + +config FB_P9100 + bool "P9100 (Sparcbook 3 only) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the P9100 card + supported on Sparcbook 3 machines. + +config FB_LEO + bool "Leo (ZX) support" + depends on FB_SBUS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the SBUS-based Sun ZX + (leo) frame buffer cards. + +config FB_IGA + bool "IGA 168x display support" + depends on (FB = y) && SPARC32 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the INTERGRAPHICS 1680 and + successor frame buffer cards. + +config FB_XVR500 + bool "Sun XVR-500 3DLABS Wildcat support" + depends on (FB = y) && PCI && SPARC64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the Sun XVR-500 and similar + graphics cards based upon the 3DLABS Wildcat chipset. The driver + only works on sparc64 systems where the system firmware has + mostly initialized the card already. It is treated as a + completely dumb framebuffer device. + +config FB_XVR2500 + bool "Sun XVR-2500 3DLABS Wildcat support" + depends on (FB = y) && PCI && SPARC64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the Sun XVR-2500 and similar + graphics cards based upon the 3DLABS Wildcat chipset. The driver + only works on sparc64 systems where the system firmware has + mostly initialized the card already. It is treated as a + completely dumb framebuffer device. + +config FB_XVR1000 + bool "Sun XVR-1000 support" + depends on (FB = y) && SPARC64 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer device for the Sun XVR-1000 and similar + graphics cards. The driver only works on sparc64 systems where + the system firmware has mostly initialized the card already. It + is treated as a completely dumb framebuffer device. + +config FB_PVR2 + tristate "NEC PowerVR 2 display support" + depends on FB && SH_DREAMCAST + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Say Y here if you have a PowerVR 2 card in your box. If you plan to + run linux on your Dreamcast, you will have to say Y here. + This driver may or may not work on other PowerVR 2 cards, but is + totally untested. Use at your own risk. If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called pvr2fb. + + You can pass several parameters to the driver at boot time or at + module load time. The parameters look like "video=pvr2:XXX", where + the meaning of XXX can be found at the end of the main source file + (). Please see the file + . + +config FB_OPENCORES + tristate "OpenCores VGA/LCD core 2.0 framebuffer support" + depends on FB && HAS_DMA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This enables support for the OpenCores VGA/LCD core. + + The OpenCores VGA/LCD core is typically used together with + softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor + systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs. + + The source code and specification for the core is available at + + +config FB_S1D13XXX + tristate "Epson S1D13XXX framebuffer support" + depends on FB + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for S1D13XXX framebuffer device family (currently only + working with S1D13806). Product specs at + + +config FB_ATMEL + tristate "AT91/AT32 LCD Controller support" + depends on FB && HAVE_FB_ATMEL + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + help + This enables support for the AT91/AT32 LCD Controller. + +config FB_INTSRAM + bool "Frame Buffer in internal SRAM" + depends on FB_ATMEL && ARCH_AT91SAM9261 + help + Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want + to let frame buffer in external SDRAM. + +config FB_ATMEL_STN + bool "Use a STN display with AT91/AT32 LCD Controller" + depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) + default n + help + Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD + Controller. Say N if you want to connect a TFT. + + If unsure, say N. + +config FB_NVIDIA + tristate "nVidia Framebuffer Support" + depends on FB && PCI + select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select BITREVERSE + select VGASTATE + help + This driver supports graphics boards with the nVidia chips, TNT + and newer. For very old chipsets, such as the RIVA128, then use + the rivafb. + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called nvidiafb. + +config FB_NVIDIA_I2C + bool "Enable DDC Support" + depends on FB_NVIDIA + select FB_DDC + help + This enables I2C support for nVidia Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. + +config FB_NVIDIA_DEBUG + bool "Lots of debug output" + depends on FB_NVIDIA + default n + help + Say Y here if you want the nVidia driver to output all sorts + of debugging information to provide to the maintainer when + something goes wrong. + +config FB_NVIDIA_BACKLIGHT + bool "Support for backlight control" + depends on FB_NVIDIA + default y + help + Say Y here if you want to control the backlight of your display. + +config FB_RIVA + tristate "nVidia Riva support" + depends on FB && PCI + select FB_BACKLIGHT if FB_RIVA_BACKLIGHT + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select BITREVERSE + select VGASTATE + help + This driver supports graphics boards with the nVidia Riva/Geforce + chips. + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called rivafb. + +config FB_RIVA_I2C + bool "Enable DDC Support" + depends on FB_RIVA + select FB_DDC + help + This enables I2C support for nVidia Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. + +config FB_RIVA_DEBUG + bool "Lots of debug output" + depends on FB_RIVA + default n + help + Say Y here if you want the Riva driver to output all sorts + of debugging information to provide to the maintainer when + something goes wrong. + +config FB_RIVA_BACKLIGHT + bool "Support for backlight control" + depends on FB_RIVA + default y + help + Say Y here if you want to control the backlight of your display. + +config FB_I740 + tristate "Intel740 support" + depends on FB && PCI + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select VGASTATE + select FB_DDC + help + This driver supports graphics cards based on Intel740 chip. + +config FB_I810 + tristate "Intel 810/815 support" + depends on FB && PCI && X86_32 && AGP_INTEL + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select VGASTATE + help + This driver supports the on-board graphics built in to the Intel 810 + and 815 chipsets. Say Y if you have and plan to use such a board. + + To compile this driver as a module, choose M here: the + module will be called i810fb. + + For more information, please read + + +config FB_I810_GTF + bool "use VESA Generalized Timing Formula" + depends on FB_I810 + help + If you say Y, then the VESA standard, Generalized Timing Formula + or GTF, will be used to calculate the required video timing values + per video mode. Since the GTF allows nondiscrete timings + (nondiscrete being a range of values as opposed to discrete being a + set of values), you'll be able to use any combination of horizontal + and vertical resolutions, and vertical refresh rates without having + to specify your own timing parameters. This is especially useful + to maximize the performance of an aging display, or if you just + have a display with nonstandard dimensions. A VESA compliant + monitor is recommended, but can still work with non-compliant ones. + If you need or want this, then select this option. The timings may + not be compliant with Intel's recommended values. Use at your own + risk. + + If you say N, the driver will revert to discrete video timings + using a set recommended by Intel in their documentation. + + If unsure, say N. + +config FB_I810_I2C + bool "Enable DDC Support" + depends on FB_I810 && FB_I810_GTF + select FB_DDC + help + +config FB_LE80578 + tristate "Intel LE80578 (Vermilion) support" + depends on FB && PCI && X86 + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This driver supports the LE80578 (Vermilion Range) chipset + +config FB_CARILLO_RANCH + tristate "Intel Carillo Ranch support" + depends on FB_LE80578 && FB && PCI && X86 + help + This driver supports the LE80578 (Carillo Ranch) board + +config FB_INTEL + tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" + depends on FB && PCI && X86 && AGP_INTEL && EXPERT + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_BOOT_VESA_SUPPORT if FB_INTEL = y + depends on !DRM_I915 + help + This driver supports the on-board graphics built in to the Intel + 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. + Say Y if you have and plan to use such a board. + + To make FB_INTELFB=Y work you need to say AGP_INTEL=y too. + + To compile this driver as a module, choose M here: the + module will be called intelfb. + + For more information, please read + +config FB_INTEL_DEBUG + bool "Intel driver Debug Messages" + depends on FB_INTEL + ---help--- + Say Y here if you want the Intel driver to output all sorts + of debugging information to provide to the maintainer when + something goes wrong. + +config FB_INTEL_I2C + bool "DDC/I2C for Intel framebuffer support" + depends on FB_INTEL + select FB_DDC + default y + help + Say Y here if you want DDC/I2C support for your on-board Intel graphics. + +config FB_MATROX + tristate "Matrox acceleration" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_TILEBLITTING + select FB_MACMODES if PPC_PMAC + ---help--- + Say Y here if you have a Matrox Millennium, Matrox Millennium II, + Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox + Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video, + Matrox G400, G450 or G550 card in your box. + + To compile this driver as a module, choose M here: the + module will be called matroxfb. + + You can pass several parameters to the driver at boot time or at + module load time. The parameters look like "video=matroxfb:XXX", and + are described in . + +config FB_MATROX_MILLENIUM + bool "Millennium I/II support" + depends on FB_MATROX + help + Say Y here if you have a Matrox Millennium or Matrox Millennium II + video card. If you select "Advanced lowlevel driver options" below, + you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp + packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can + also use font widths different from 8. + +config FB_MATROX_MYSTIQUE + bool "Mystique support" + depends on FB_MATROX + help + Say Y here if you have a Matrox Mystique or Matrox Mystique 220 + video card. If you select "Advanced lowlevel driver options" below, + you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp + packed pixel and 32 bpp packed pixel. You can also use font widths + different from 8. + +config FB_MATROX_G + bool "G100/G200/G400/G450/G550 support" + depends on FB_MATROX + ---help--- + Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based + video card. If you select "Advanced lowlevel driver options", you + should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed + pixel and 32 bpp packed pixel. You can also use font widths + different from 8. + + If you need support for G400 secondary head, you must say Y to + "Matrox I2C support" and "G400 second head support" right below. + G450/G550 secondary head and digital output are supported without + additional modules. + + The driver starts in monitor mode. You must use the matroxset tool + (available at ) to + swap primary and secondary head outputs, or to change output mode. + Secondary head driver always start in 640x480 resolution and you + must use fbset to change it. + + Do not forget that second head supports only 16 and 32 bpp + packed pixels, so it is a good idea to compile them into the kernel + too. You can use only some font widths, as the driver uses generic + painting procedures (the secondary head does not use acceleration + engine). + + G450/G550 hardware can display TV picture only from secondary CRTC, + and it performs no scaling, so picture must have 525 or 625 lines. + +config FB_MATROX_I2C + tristate "Matrox I2C support" + depends on FB_MATROX + select FB_DDC + ---help--- + This drivers creates I2C buses which are needed for accessing the + DDC (I2C) bus present on all Matroxes, an I2C bus which + interconnects Matrox optional devices, like MGA-TVO on G200 and + G400, and the secondary head DDC bus, present on G400 only. + + You can say Y or M here if you want to experiment with monitor + detection code. You must say Y or M here if you want to use either + second head of G400 or MGA-TVO on G200 or G400. + + If you compile it as module, it will create a module named + i2c-matroxfb. + +config FB_MATROX_MAVEN + tristate "G400 second head support" + depends on FB_MATROX_G && FB_MATROX_I2C + ---help--- + WARNING !!! This support does not work with G450 !!! + + Say Y or M here if you want to use a secondary head (meaning two + monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary + head is not compatible with accelerated XFree 3.3.x SVGA servers - + secondary head output is blanked while you are in X. With XFree + 3.9.17 preview you can use both heads if you use SVGA over fbdev or + the fbdev driver on first head and the fbdev driver on second head. + + If you compile it as module, two modules are created, + matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for + both G200 and G400, matroxfb_crtc2 is needed only by G400. You must + also load i2c-matroxfb to get it to run. + + The driver starts in monitor mode and you must use the matroxset + tool (available at + ) to switch it to + PAL or NTSC or to swap primary and secondary head outputs. + Secondary head driver also always start in 640x480 resolution, you + must use fbset to change it. + + Also do not forget that second head supports only 16 and 32 bpp + packed pixels, so it is a good idea to compile them into the kernel + too. You can use only some font widths, as the driver uses generic + painting procedures (the secondary head does not use acceleration + engine). + +config FB_RADEON + tristate "ATI Radeon display support" + depends on FB && PCI + select FB_BACKLIGHT if FB_RADEON_BACKLIGHT + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MACMODES if PPC_OF + help + Choose this option if you want to use an ATI Radeon graphics card as + a framebuffer device. There are both PCI and AGP versions. You + don't need to choose this to run the Radeon in plain VGA mode. + + There is a product page at + http://products.amd.com/en-us/GraphicCardResult.aspx + +config FB_RADEON_I2C + bool "DDC/I2C for ATI Radeon support" + depends on FB_RADEON + select FB_DDC + default y + help + Say Y here if you want DDC/I2C support for your Radeon board. + +config FB_RADEON_BACKLIGHT + bool "Support for backlight control" + depends on FB_RADEON + default y + help + Say Y here if you want to control the backlight of your display. + +config FB_RADEON_DEBUG + bool "Lots of debug output from Radeon driver" + depends on FB_RADEON + default n + help + Say Y here if you want the Radeon driver to output all sorts + of debugging information to provide to the maintainer when + something goes wrong. + +config FB_ATY128 + tristate "ATI Rage128 display support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_BACKLIGHT if FB_ATY128_BACKLIGHT + select FB_MACMODES if PPC_PMAC + help + This driver supports graphics boards with the ATI Rage128 chips. + Say Y if you have such a graphics board and read + . + + To compile this driver as a module, choose M here: the + module will be called aty128fb. + +config FB_ATY128_BACKLIGHT + bool "Support for backlight control" + depends on FB_ATY128 + default y + help + Say Y here if you want to control the backlight of your display. + +config FB_ATY + tristate "ATI Mach64 display support" if PCI || ATARI + depends on FB && !SPARC32 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_BACKLIGHT if FB_ATY_BACKLIGHT + select FB_MACMODES if PPC + help + This driver supports graphics boards with the ATI Mach64 chips. + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called atyfb. + +config FB_ATY_CT + bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" + depends on PCI && FB_ATY + default y if SPARC64 && PCI + help + Say Y here to support use of ATI's 64-bit Rage boards (or other + boards based on the Mach64 CT, VT, GT, and LT chipsets) as a + framebuffer device. The ATI product support page for these boards + is at . + +config FB_ATY_GENERIC_LCD + bool "Mach64 generic LCD support" + depends on FB_ATY_CT + help + Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, + Rage XC, or Rage XL chipset. + +config FB_ATY_GX + bool "Mach64 GX support" if PCI + depends on FB_ATY + default y if ATARI + help + Say Y here to support use of the ATI Mach64 Graphics Expression + board (or other boards based on the Mach64 GX chipset) as a + framebuffer device. The ATI product support page for these boards + is at + . + +config FB_ATY_BACKLIGHT + bool "Support for backlight control" + depends on FB_ATY + default y + help + Say Y here if you want to control the backlight of your display. + +config FB_S3 + tristate "S3 Trio/Virge support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_TILEBLITTING + select FB_SVGALIB + select VGASTATE + select FONT_8x16 if FRAMEBUFFER_CONSOLE + ---help--- + Driver for graphics boards with S3 Trio / S3 Virge chip. + +config FB_S3_DDC + bool "DDC for S3 support" + depends on FB_S3 + select FB_DDC + default y + help + Say Y here if you want DDC support for your S3 graphics card. + +config FB_SAVAGE + tristate "S3 Savage support" + depends on FB && PCI + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select VGASTATE + help + This driver supports notebooks and computers with S3 Savage PCI/AGP + chips. + + Say Y if you have such a graphics card. + + To compile this driver as a module, choose M here; the module + will be called savagefb. + +config FB_SAVAGE_I2C + bool "Enable DDC2 Support" + depends on FB_SAVAGE + select FB_DDC + help + This enables I2C support for S3 Savage Chipsets. This is used + only for getting EDID information from the attached display + allowing for robust video mode handling and switching. + + Because fbdev-2.6 requires that drivers must be able to + independently validate video mode parameters, you should say Y + here. + +config FB_SAVAGE_ACCEL + bool "Enable Console Acceleration" + depends on FB_SAVAGE + default n + help + This option will compile in console acceleration support. If + the resulting framebuffer console has bothersome glitches, then + choose N here. + +config FB_SIS + tristate "SiS/XGI display support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_BOOT_VESA_SUPPORT if FB_SIS = y + help + This is the frame buffer device driver for the SiS 300, 315, 330 + and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. + Specs available at and . + + To compile this driver as a module, choose M here; the module + will be called sisfb. + +config FB_SIS_300 + bool "SiS 300 series support" + depends on FB_SIS + help + Say Y here to support use of the SiS 300/305, 540, 630 and 730. + +config FB_SIS_315 + bool "SiS 315/330/340 series and XGI support" + depends on FB_SIS + help + Say Y here to support use of the SiS 315, 330 and 340 series + (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well + as XGI V3XT, V5, V8 and Z7. + +config FB_VIA + tristate "VIA UniChrome (Pro) and Chrome9 display support" + depends on FB && PCI && X86 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select I2C_ALGOBIT + select I2C + select GPIOLIB + help + This is the frame buffer device driver for Graphics chips of VIA + UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ + CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 + /P4M900,VX800) + Say Y if you have a VIA UniChrome graphics board. + + To compile this driver as a module, choose M here: the + module will be called viafb. + +if FB_VIA + +config FB_VIA_DIRECT_PROCFS + bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)" + depends on FB_VIA + default n + help + Allow direct hardware access to some output registers via procfs. + This is dangerous but may provide the only chance to get the + correct output device configuration. + Its use is strongly discouraged. + +config FB_VIA_X_COMPATIBILITY + bool "X server compatibility" + depends on FB_VIA + default n + help + This option reduces the functionality (power saving, ...) of the + framebuffer to avoid negative impact on the OpenChrome X server. + If you use any X server other than fbdev you should enable this + otherwise it should be safe to disable it and allow using all + features. + +endif + +config FB_NEOMAGIC + tristate "NeoMagic display support" + depends on FB && PCI + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select VGASTATE + help + This driver supports notebooks with NeoMagic PCI chips. + Say Y if you have such a graphics card. + + To compile this driver as a module, choose M here: the + module will be called neofb. + +config FB_KYRO + tristate "IMG Kyro support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y here if you have a STG4000 / Kyro / PowerVR 3 based + graphics board. + + To compile this driver as a module, choose M here: the + module will be called kyrofb. + +config FB_3DFX + tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" + depends on FB && PCI + select FB_CFB_IMAGEBLIT + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_MODE_HELPERS + help + This driver supports graphics boards with the 3Dfx Banshee, + Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have + such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called tdfxfb. + +config FB_3DFX_ACCEL + bool "3Dfx Acceleration functions" + depends on FB_3DFX + ---help--- + This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer + device driver with acceleration functions. + +config FB_3DFX_I2C + bool "Enable DDC/I2C support" + depends on FB_3DFX + select FB_DDC + default y + help + Say Y here if you want DDC/I2C support for your 3dfx Voodoo3. + +config FB_VOODOO1 + tristate "3Dfx Voodoo Graphics (sst1) support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or + Voodoo2 (cvg) based graphics card. + + To compile this driver as a module, choose M here: the + module will be called sstfb. + + WARNING: Do not use any application that uses the 3D engine + (namely glide) while using this driver. + Please read the for supported + options and other important info support. + +config FB_VT8623 + tristate "VIA VT8623 support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_TILEBLITTING + select FB_SVGALIB + select VGASTATE + select FONT_8x16 if FRAMEBUFFER_CONSOLE + ---help--- + Driver for CastleRock integrated graphics core in the + VIA VT8623 [Apollo CLE266] chipset. + +config FB_TRIDENT + tristate "Trident/CyberXXX/CyberBlade support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + This is the frame buffer device driver for Trident PCI/AGP chipsets. + Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D + and Blade XP. + There are also integrated versions of these chips called CyberXXXX, + CyberImage or CyberBlade. These chips are mostly found in laptops + but also on some motherboards including early VIA EPIA motherboards. + For more information, read + + Say Y if you have such a graphics board. + + To compile this driver as a module, choose M here: the + module will be called tridentfb. + +config FB_ARK + tristate "ARK 2000PV support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_TILEBLITTING + select FB_SVGALIB + select VGASTATE + select FONT_8x16 if FRAMEBUFFER_CONSOLE + ---help--- + Driver for PCI graphics boards with ARK 2000PV chip + and ICS 5342 RAMDAC. + +config FB_PM3 + tristate "Permedia3 support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the 3DLabs Permedia3 + chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & + similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 + and maybe other boards. + +config FB_CARMINE + tristate "Fujitsu carmine frame buffer support" + depends on FB && PCI + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Fujitsu Carmine chip. + The driver provides two independent frame buffer devices. + +choice + depends on FB_CARMINE + prompt "DRAM timing" + default FB_CARMINE_DRAM_EVAL + +config FB_CARMINE_DRAM_EVAL + bool "Eval board timings" + help + Use timings which work on the eval card. + +config CARMINE_DRAM_CUSTOM + bool "Custom board timings" + help + Use custom board timings. +endchoice + +config FB_AU1100 + bool "Au1100 LCD Driver" + depends on (FB = y) && MIPS_ALCHEMY + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the framebuffer driver for the AMD Au1100 SOC. It can drive + various panels and CRTs by passing in kernel cmd line option + au1100fb:panel=. + +config FB_AU1200 + bool "Au1200/Au1300 LCD Driver" + depends on (FB = y) && MIPS_ALCHEMY + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + help + This is the framebuffer driver for the Au1200/Au1300 SOCs. + It can drive various panels and CRTs by passing in kernel cmd line + option au1200fb:panel=. + +config FB_VT8500 + bool "VIA VT8500 framebuffer support" + depends on (FB = y) && ARM && ARCH_VT8500 + select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) + select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) + select FB_SYS_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + help + This is the framebuffer driver for VIA VT8500 integrated LCD + controller. + +config FB_WM8505 + bool "Wondermedia WM8xxx-series frame buffer support" + depends on (FB = y) && ARM && ARCH_VT8500 + select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) + select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) + select FB_SYS_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + help + This is the framebuffer driver for WonderMedia WM8xxx-series + integrated LCD controller. This driver covers the WM8505, WM8650 + and WM8850 SoCs. + +config FB_WMT_GE_ROPS + bool "VT8500/WM8xxx accelerated raster ops support" + depends on (FB = y) && (FB_VT8500 || FB_WM8505) + default n + help + This adds support for accelerated raster operations on the + VIA VT8500 and Wondermedia 85xx series SoCs. + +source "drivers/video/fbdev/geode/Kconfig" + +config FB_HIT + tristate "HD64461 Frame Buffer support" + depends on FB && HD64461 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This is the frame buffer device driver for the Hitachi HD64461 LCD + frame buffer card. + +config FB_PMAG_AA + bool "PMAG-AA TURBOchannel framebuffer support" + depends on (FB = y) && TC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) + used mainly in the MIPS-based DECstation series. + +config FB_PMAG_BA + tristate "PMAG-BA TURBOchannel framebuffer support" + depends on FB && TC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) + used mainly in the MIPS-based DECstation series. + +config FB_PMAGB_B + tristate "PMAGB-B TURBOchannel framebuffer support" + depends on FB && TC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the PMAGB-B TURBOchannel framebuffer card used mainly + in the MIPS-based DECstation series. The card is currently only + supported in 1280x1024x8 mode. + +config FB_MAXINE + bool "Maxine (Personal DECstation) onboard framebuffer support" + depends on (FB = y) && MACH_DECSTATION + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Support for the onboard framebuffer (1024x768x8) in the Personal + DECstation series (Personal DECstation 5000/20, /25, /33, /50, + Codename "Maxine"). + +config FB_G364 + bool "G364 frame buffer support" + depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + The G364 driver is the framebuffer used in MIPS Magnum 4000 and + Olivetti M700-10 systems. + +config FB_68328 + bool "Motorola 68328 native frame buffer support" + depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y here if you want to support the built-in frame buffer of + the Motorola 68328 CPU family. + +config FB_PXA168 + tristate "PXA168/910 LCD framebuffer support" + depends on FB && (CPU_PXA168 || CPU_PXA910) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Marvell + MMP processor. + +config FB_PXA + tristate "PXA LCD framebuffer support" + depends on FB && ARCH_PXA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Intel + PXA2x0 processor. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called pxafb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. + +config FB_PXA_OVERLAY + bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer" + default n + depends on FB_PXA && (PXA27x || PXA3xx) + +config FB_PXA_SMARTPANEL + bool "PXA Smartpanel LCD support" + default n + depends on FB_PXA + +config FB_PXA_PARAMETERS + bool "PXA LCD command line parameters" + default n + depends on FB_PXA + ---help--- + Enable the use of kernel command line or module parameters + to configure the physical properties of the LCD panel when + using the PXA LCD driver. + + This option allows you to override the panel parameters + supplied by the platform in order to support multiple + different models of flatpanel. If you will only be using a + single model of flatpanel then you can safely leave this + option disabled. + + describes the available parameters. + +config PXA3XX_GCU + tristate "PXA3xx 2D graphics accelerator driver" + depends on FB_PXA + help + Kernelspace driver for the 2D graphics controller unit (GCU) + found on PXA3xx processors. There is a counterpart driver in the + DirectFB suite, see http://www.directfb.org/ + + If you compile this as a module, it will be called pxa3xx_gcu. + +config FB_MBX + tristate "2700G LCD framebuffer support" + depends on FB && ARCH_PXA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Framebuffer driver for the Intel 2700G (Marathon) Graphics + Accelerator + +config FB_MBX_DEBUG + bool "Enable debugging info via debugfs" + depends on FB_MBX && DEBUG_FS + default n + ---help--- + Enable this if you want debugging information using the debug + filesystem (debugfs) + + If unsure, say N. + +config FB_FSL_DIU + tristate "Freescale DIU framebuffer support" + depends on FB && FSL_SOC + select FB_MODE_HELPERS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select PPC_LIB_RHEAP + ---help--- + Framebuffer driver for the Freescale SoC DIU + +config FB_W100 + tristate "W100 frame buffer support" + depends on FB && ARCH_PXA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. + It can also drive the w3220 chip found on iPAQ hx4700. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called w100fb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. + +config FB_SH_MOBILE_LCDC + tristate "SuperH Mobile LCDC framebuffer support" + depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + select FB_BACKLIGHT + select SH_MIPI_DSI if SH_LCD_MIPI_DSI + ---help--- + Frame buffer driver for the on-chip SH-Mobile LCD controller. + +config FB_SH_MOBILE_HDMI + tristate "SuperH Mobile HDMI controller support" + depends on FB_SH_MOBILE_LCDC + select FB_MODE_HELPERS + select SOUND + select SND + select SND_SOC + ---help--- + Driver for the on-chip SH-Mobile HDMI controller. + +config FB_TMIO + tristate "Toshiba Mobile IO FrameBuffer support" + depends on FB && MFD_CORE + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the Toshiba Mobile IO integrated as found + on the Sharp SL-6000 series + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called tmiofb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. + +config FB_TMIO_ACCELL + bool "tmiofb acceleration" + depends on FB_TMIO + default y + +config FB_S3C + tristate "Samsung S3C framebuffer support" + depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \ + ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in FB controller in the Samsung + SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, + and the S3C64XX series such as the S3C6400 and S3C6410. + + These chips all have the same basic framebuffer design with the + actual capabilities depending on the chip. For instance the S3C6400 + and S3C6410 support 4 hardware windows whereas the S3C24XX series + currently only have two. + + Currently the support is only for the S3C6400 and S3C6410 SoCs. + +config FB_S3C_DEBUG_REGWRITE + bool "Debug register writes" + depends on FB_S3C + ---help--- + Show all register writes via pr_debug() + +config FB_S3C2410 + tristate "S3C2410 LCD framebuffer support" + depends on FB && ARCH_S3C24XX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Samsung + S3C2410 processor. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called s3c2410fb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. +config FB_S3C2410_DEBUG + bool "S3C2410 lcd debug messages" + depends on FB_S3C2410 + help + Turn on debugging messages. Note that you can set/unset at run time + through sysfs + +config FB_NUC900 + bool "NUC900 LCD framebuffer support" + depends on FB && ARCH_W90X900 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the built-in LCD controller in the Nuvoton + NUC900 processor + +config GPM1040A0_320X240 + bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" + depends on FB_NUC900 + +config FB_SM501 + tristate "Silicon Motion SM501 framebuffer support" + depends on FB && MFD_SM501 + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for the CRT and LCD controllers in the Silicon + Motion SM501. + + This driver is also available as a module ( = code which can be + inserted and removed from the running kernel whenever you want). The + module will be called sm501fb. If you want to compile it as a module, + say M here and read . + + If unsure, say N. + +config FB_SMSCUFX + tristate "SMSC UFX6000/7000 USB Framebuffer support" + depends on FB && USB + select FB_MODE_HELPERS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + ---help--- + This is a kernel framebuffer driver for SMSC UFX USB devices. + Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and + mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000 + (USB 3.0) devices. + To compile as a module, choose M here: the module name is smscufx. + +config FB_UDL + tristate "Displaylink USB Framebuffer support" + depends on FB && USB + select FB_MODE_HELPERS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + ---help--- + This is a kernel framebuffer driver for DisplayLink USB devices. + Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and + mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. + To compile as a module, choose M here: the module name is udlfb. + +config FB_IBM_GXT4500 + tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors" + depends on FB && PPC + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Say Y here to enable support for the IBM GXT4000P/6000P and + GXT4500P/6500P display adaptor based on Raster Engine RC1000, + found on some IBM System P (pSeries) machines. This driver + doesn't use Geometry Engine GT1000. + +config FB_PS3 + tristate "PS3 GPU framebuffer driver" + depends on FB && PS3_PS3AV + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE + ---help--- + Include support for the virtual frame buffer in the PS3 platform. + +config FB_PS3_DEFAULT_SIZE_M + int "PS3 default frame buffer size (in MiB)" + depends on FB_PS3 + default 9 + ---help--- + This is the default size (in MiB) of the virtual frame buffer in + the PS3. + The default value can be overridden on the kernel command line + using the "ps3fb" option (e.g. "ps3fb=9M"); + +config FB_XILINX + tristate "Xilinx frame buffer support" + depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Include support for the Xilinx ML300/ML403 reference design + framebuffer. ML300 carries a 640*480 LCD display on the board, + ML403 uses a standard DB15 VGA connector. + +config FB_GOLDFISH + tristate "Goldfish Framebuffer" + depends on FB && HAS_DMA + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Framebuffer driver for Goldfish Virtual Platform + +config FB_COBALT + tristate "Cobalt server LCD frame buffer support" + depends on FB && (MIPS_COBALT || MIPS_SEAD3) + +config FB_SH7760 + bool "SH7760/SH7763/SH7720/SH7721 LCDC support" + depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ + || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Support for the SH7760/SH7763/SH7720/SH7721 integrated + (D)STN/TFT LCD Controller. + Supports display resolutions up to 1024x1024 pixel, grayscale and + color operation, with depths ranging from 1 bpp to 8 bpp monochrome + and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for + panels <= 320 pixel horizontal resolution. + +config FB_DA8XX + tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" + depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_CFB_REV_PIXELS_IN_BYTE + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + ---help--- + This is the frame buffer device driver for the TI LCD controller + found on DA8xx/OMAP-L1xx/AM335x SoCs. + If unsure, say N. + +config FB_VIRTUAL + tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" + depends on FB + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + ---help--- + This is a `virtual' frame buffer device. It operates on a chunk of + unswappable kernel memory instead of on the memory of a graphics + board. This means you cannot see any output sent to this frame + buffer device, while it does consume precious memory. The main use + of this frame buffer device is testing and debugging the frame + buffer subsystem. Do NOT enable it for normal systems! To protect + the innocent, it has to be enabled explicitly at boot time using the + kernel option `video=vfb:'. + + To compile this driver as a module, choose M here: the + module will be called vfb. In order to load it, you must use + the vfb_enable=1 option. + + If unsure, say N. + +config XEN_FBDEV_FRONTEND + tristate "Xen virtual frame buffer support" + depends on FB && XEN + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC + select XEN_XENBUS_FRONTEND + default y + help + This driver implements the front-end of the Xen virtual + frame buffer driver. It communicates with a back-end + in another domain. + +config FB_METRONOME + tristate "E-Ink Metronome/8track controller support" + depends on FB + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + help + This driver implements support for the E-Ink Metronome + controller. The pre-release name for this device was 8track + and could also have been called by some vendors as PVI-nnnn. + +config FB_MB862XX + tristate "Fujitsu MB862xx GDC support" + depends on FB + depends on PCI || (OF && PPC) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. + +choice + prompt "GDC variant" + depends on FB_MB862XX + +config FB_MB862XX_PCI_GDC + bool "Carmine/Coral-P(A) GDC" + depends on PCI + ---help--- + This enables framebuffer support for Fujitsu Carmine/Coral-P(A) + PCI graphics controller devices. + +config FB_MB862XX_LIME + bool "Lime GDC" + depends on OF && PPC + select FB_FOREIGN_ENDIAN + select FB_LITTLE_ENDIAN + ---help--- + Framebuffer support for Fujitsu Lime GDC on host CPU bus. + +endchoice + +config FB_MB862XX_I2C + bool "Support I2C bus on MB862XX GDC" + depends on FB_MB862XX && I2C + default y + help + Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter + driver to support accessing I2C devices on controller's I2C bus. + These are usually some video decoder chips. + +config FB_EP93XX + tristate "EP93XX frame buffer support" + depends on FB && ARCH_EP93XX + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + ---help--- + Framebuffer driver for the Cirrus Logic EP93XX series of processors. + This driver is also available as a module. The module will be called + ep93xx-fb. + +config FB_PRE_INIT_FB + bool "Don't reinitialize, use bootloader's GDC/Display configuration" + depends on FB && FB_MB862XX_LIME + ---help--- + Select this option if display contents should be inherited as set by + the bootloader. + +config FB_MSM + tristate "MSM Framebuffer support" + depends on FB && ARCH_MSM + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + +config FB_MX3 + tristate "MX3 Framebuffer support" + depends on FB && MX3_IPU + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + help + This is a framebuffer device for the i.MX31 LCD Controller. So + far only synchronous displays are supported. If you plan to use + an LCD display with your i.MX31 system, say Y here. + +config FB_BROADSHEET + tristate "E-Ink Broadsheet/Epson S1D13521 controller support" + depends on FB + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + help + This driver implements support for the E-Ink Broadsheet + controller. The release name for this device was Epson S1D13521 + and could also have been called by other names when coupled with + a bridge adapter. + +config FB_AUO_K190X + tristate "AUO-K190X EPD controller support" + depends on FB + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + select FB_DEFERRED_IO + help + Provides support for epaper controllers from the K190X series + of AUO. These controllers can be used to drive epaper displays + from Sipix. + + This option enables the common support, shared by the individual + controller drivers. You will also have to enable the driver + for the controller type used in your device. + +config FB_AUO_K1900 + tristate "AUO-K1900 EPD controller support" + depends on FB && FB_AUO_K190X + help + This driver implements support for the AUO K1900 epd-controller. + This controller can drive Sipix epaper displays but can only do + serial updates, reducing the number of possible frames per second. + +config FB_AUO_K1901 + tristate "AUO-K1901 EPD controller support" + depends on FB && FB_AUO_K190X + help + This driver implements support for the AUO K1901 epd-controller. + This controller can drive Sipix epaper displays and supports + concurrent updates, making higher frames per second possible. + +config FB_JZ4740 + tristate "JZ4740 LCD framebuffer support" + depends on FB && MACH_JZ4740 + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + help + Framebuffer support for the JZ4740 SoC. + +config FB_MXS + tristate "MXS LCD framebuffer support" + depends on FB && ARCH_MXS + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_MODE_HELPERS + select VIDEOMODE_HELPERS + help + Framebuffer support for the MXS SoC. + +config FB_PUV3_UNIGFX + tristate "PKUnity v3 Unigfx framebuffer support" + depends on FB && UNICORE32 && ARCH_PUV3 + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_SYS_FOPS + help + Choose this option if you want to use the Unigfx device as a + framebuffer device. Without the support of PCI & AGP. + +config FB_HYPERV + tristate "Microsoft Hyper-V Synthetic Video support" + depends on FB && HYPERV + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + This framebuffer driver supports Microsoft Hyper-V Synthetic Video. + +config FB_SIMPLE + bool "Simple framebuffer support" + depends on (FB = y) + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + help + Say Y if you want support for a simple frame-buffer. + + This driver assumes that the display hardware has been initialized + before the kernel boots, and the kernel will simply render to the + pre-allocated frame buffer surface. + + Configuration re: surface address, size, and format must be provided + through device tree, or plain old platform data. + +source "drivers/video/fbdev/omap/Kconfig" +source "drivers/video/fbdev/omap2/Kconfig" +source "drivers/video/fbdev/exynos/Kconfig" +source "drivers/video/fbdev/mmp/Kconfig" + +config FB_SH_MOBILE_MERAM + tristate "SuperH Mobile MERAM read ahead support" + depends on (SUPERH || ARCH_SHMOBILE) + select GENERIC_ALLOCATOR + ---help--- + Enable MERAM support for the SuperH controller. + + This will allow for caching of the framebuffer to provide more + reliable access under heavy main memory bus traffic situations. + Up to 4 memory channels can be configured, allowing 4 RGB or + 2 YCbCr framebuffers to be configured. + +config FB_SSD1307 + tristate "Solomon SSD1307 framebuffer support" + depends on FB && I2C + depends on OF + depends on GPIOLIB + select FB_SYS_FOPS + select FB_SYS_FILLRECT + select FB_SYS_COPYAREA + select FB_SYS_IMAGEBLIT + select FB_DEFERRED_IO + select PWM + help + This driver implements support for the Solomon SSD1307 + OLED controller over I2C. diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile new file mode 100644 index 000000000000..8a79eec2113b --- /dev/null +++ b/drivers/video/fbdev/Makefile @@ -0,0 +1,166 @@ +# Makefile for the Linux video drivers. +# 5 Aug 1999, James Simmons, +# Rewritten to use lists instead of if-statements. + +# Each configuration option enables a list of files. + +obj-y += fb_notify.o +obj-$(CONFIG_FB) += fb.o +fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ + modedb.o fbcvt.o +fb-objs := $(fb-y) + +obj-$(CONFIG_EXYNOS_VIDEO) += exynos/ + +obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o +obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o +obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o +obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o +obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o +obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o +obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o +obj-$(CONFIG_FB_SVGALIB) += svgalib.o +obj-$(CONFIG_FB_MACMODES) += macmodes.o +obj-$(CONFIG_FB_DDC) += fb_ddc.o +obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o +obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o + +# Hardware specific drivers go first +obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o +obj-$(CONFIG_FB_ARC) += arcfb.o +obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o +obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o +obj-$(CONFIG_FB_GRVGA) += grvga.o +obj-$(CONFIG_FB_PM2) += pm2fb.o +obj-$(CONFIG_FB_PM3) += pm3fb.o + +obj-$(CONFIG_FB_I740) += i740fb.o +obj-$(CONFIG_FB_MATROX) += matrox/ +obj-$(CONFIG_FB_RIVA) += riva/ +obj-$(CONFIG_FB_NVIDIA) += nvidia/ +obj-$(CONFIG_FB_ATY) += aty/ macmodes.o +obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o +obj-$(CONFIG_FB_RADEON) += aty/ +obj-$(CONFIG_FB_SIS) += sis/ +obj-$(CONFIG_FB_VIA) += via/ +obj-$(CONFIG_FB_KYRO) += kyro/ +obj-$(CONFIG_FB_SAVAGE) += savage/ +obj-$(CONFIG_FB_GEODE) += geode/ +obj-$(CONFIG_FB_MBX) += mbx/ +obj-$(CONFIG_FB_NEOMAGIC) += neofb.o +obj-$(CONFIG_FB_3DFX) += tdfxfb.o +obj-$(CONFIG_FB_CONTROL) += controlfb.o +obj-$(CONFIG_FB_PLATINUM) += platinumfb.o +obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o +obj-$(CONFIG_FB_CT65550) += chipsfb.o +obj-$(CONFIG_FB_IMSTT) += imsttfb.o +obj-$(CONFIG_FB_FM2) += fm2fb.o +obj-$(CONFIG_FB_VT8623) += vt8623fb.o +obj-$(CONFIG_FB_TRIDENT) += tridentfb.o +obj-$(CONFIG_FB_LE80578) += vermilion/ +obj-$(CONFIG_FB_S3) += s3fb.o +obj-$(CONFIG_FB_ARK) += arkfb.o +obj-$(CONFIG_FB_STI) += stifb.o +obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o +obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o +obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o +obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o +obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o +obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o +obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o +obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o +obj-$(CONFIG_FB_ACORN) += acornfb.o +obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \ + atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o +obj-$(CONFIG_FB_MAC) += macfb.o +obj-$(CONFIG_FB_HECUBA) += hecubafb.o +obj-$(CONFIG_FB_N411) += n411.o +obj-$(CONFIG_FB_HGA) += hgafb.o +obj-$(CONFIG_FB_XVR500) += sunxvr500.o +obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o +obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o +obj-$(CONFIG_FB_IGA) += igafb.o +obj-$(CONFIG_FB_APOLLO) += dnfb.o +obj-$(CONFIG_FB_Q40) += q40fb.o +obj-$(CONFIG_FB_TGA) += tgafb.o +obj-$(CONFIG_FB_HP300) += hpfb.o +obj-$(CONFIG_FB_G364) += g364fb.o +obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o +obj-$(CONFIG_FB_SA1100) += sa1100fb.o +obj-$(CONFIG_FB_HIT) += hitfb.o +obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o +obj-$(CONFIG_FB_PVR2) += pvr2fb.o +obj-$(CONFIG_FB_VOODOO1) += sstfb.o +obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o +obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o +obj-$(CONFIG_FB_68328) += 68328fb.o +obj-$(CONFIG_FB_GBE) += gbefb.o +obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o +obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o +obj-$(CONFIG_FB_PXA) += pxafb.o +obj-$(CONFIG_FB_PXA168) += pxa168fb.o +obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o +obj-$(CONFIG_MMP_DISP) += mmp/ +obj-$(CONFIG_FB_W100) += w100fb.o +obj-$(CONFIG_FB_TMIO) += tmiofb.o +obj-$(CONFIG_FB_AU1100) += au1100fb.o +obj-$(CONFIG_FB_AU1200) += au1200fb.o +obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o +obj-$(CONFIG_FB_WM8505) += wm8505fb.o +obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o +obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o +obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o +obj-$(CONFIG_FB_MAXINE) += maxinefb.o +obj-$(CONFIG_FB_METRONOME) += metronomefb.o +obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o +obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o +obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o +obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o +obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o +obj-$(CONFIG_FB_SH7760) += sh7760fb.o +obj-$(CONFIG_FB_IMX) += imxfb.o +obj-$(CONFIG_FB_S3C) += s3c-fb.o +obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o +obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o +obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o +obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o +obj-$(CONFIG_FB_PS3) += ps3fb.o +obj-$(CONFIG_FB_SM501) += sm501fb.o +obj-$(CONFIG_FB_UDL) += udlfb.o +obj-$(CONFIG_FB_SMSCUFX) += smscufx.o +obj-$(CONFIG_FB_XILINX) += xilinxfb.o +obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o +obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o +obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o +obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o +obj-$(CONFIG_FB_OMAP) += omap/ +obj-y += omap2/ +obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o +obj-$(CONFIG_FB_CARMINE) += carminefb.o +obj-$(CONFIG_FB_MB862XX) += mb862xx/ +obj-$(CONFIG_FB_MSM) += msm/ +obj-$(CONFIG_FB_NUC900) += nuc900fb.o +obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o +obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o +obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o +obj-$(CONFIG_FB_OPENCORES) += ocfb.o + +# Platform or fallback drivers go here +obj-$(CONFIG_FB_UVESA) += uvesafb.o +obj-$(CONFIG_FB_VESA) += vesafb.o +obj-$(CONFIG_FB_EFI) += efifb.o +obj-$(CONFIG_FB_VGA16) += vga16fb.o +obj-$(CONFIG_FB_OF) += offb.o +obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o +obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o +obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o +obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o +obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o +obj-$(CONFIG_FB_MX3) += mx3fb.o +obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o +obj-$(CONFIG_FB_MXS) += mxsfb.o +obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o +obj-$(CONFIG_FB_SIMPLE) += simplefb.o + +# the test framebuffer is last +obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/acornfb.c b/drivers/video/fbdev/acornfb.c similarity index 100% rename from drivers/video/acornfb.c rename to drivers/video/fbdev/acornfb.c diff --git a/drivers/video/acornfb.h b/drivers/video/fbdev/acornfb.h similarity index 100% rename from drivers/video/acornfb.h rename to drivers/video/fbdev/acornfb.h diff --git a/drivers/video/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c similarity index 100% rename from drivers/video/amba-clcd.c rename to drivers/video/fbdev/amba-clcd.c diff --git a/drivers/video/amifb.c b/drivers/video/fbdev/amifb.c similarity index 100% rename from drivers/video/amifb.c rename to drivers/video/fbdev/amifb.c diff --git a/drivers/video/arcfb.c b/drivers/video/fbdev/arcfb.c similarity index 100% rename from drivers/video/arcfb.c rename to drivers/video/fbdev/arcfb.c diff --git a/drivers/video/arkfb.c b/drivers/video/fbdev/arkfb.c similarity index 100% rename from drivers/video/arkfb.c rename to drivers/video/fbdev/arkfb.c diff --git a/drivers/video/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c similarity index 100% rename from drivers/video/asiliantfb.c rename to drivers/video/fbdev/asiliantfb.c diff --git a/drivers/video/atafb.c b/drivers/video/fbdev/atafb.c similarity index 100% rename from drivers/video/atafb.c rename to drivers/video/fbdev/atafb.c diff --git a/drivers/video/atafb.h b/drivers/video/fbdev/atafb.h similarity index 100% rename from drivers/video/atafb.h rename to drivers/video/fbdev/atafb.h diff --git a/drivers/video/atafb_iplan2p2.c b/drivers/video/fbdev/atafb_iplan2p2.c similarity index 100% rename from drivers/video/atafb_iplan2p2.c rename to drivers/video/fbdev/atafb_iplan2p2.c diff --git a/drivers/video/atafb_iplan2p4.c b/drivers/video/fbdev/atafb_iplan2p4.c similarity index 100% rename from drivers/video/atafb_iplan2p4.c rename to drivers/video/fbdev/atafb_iplan2p4.c diff --git a/drivers/video/atafb_iplan2p8.c b/drivers/video/fbdev/atafb_iplan2p8.c similarity index 100% rename from drivers/video/atafb_iplan2p8.c rename to drivers/video/fbdev/atafb_iplan2p8.c diff --git a/drivers/video/atafb_mfb.c b/drivers/video/fbdev/atafb_mfb.c similarity index 100% rename from drivers/video/atafb_mfb.c rename to drivers/video/fbdev/atafb_mfb.c diff --git a/drivers/video/atafb_utils.h b/drivers/video/fbdev/atafb_utils.h similarity index 100% rename from drivers/video/atafb_utils.h rename to drivers/video/fbdev/atafb_utils.h diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c similarity index 100% rename from drivers/video/atmel_lcdfb.c rename to drivers/video/fbdev/atmel_lcdfb.c diff --git a/drivers/video/aty/Makefile b/drivers/video/fbdev/aty/Makefile similarity index 100% rename from drivers/video/aty/Makefile rename to drivers/video/fbdev/aty/Makefile diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/fbdev/aty/ati_ids.h similarity index 100% rename from drivers/video/aty/ati_ids.h rename to drivers/video/fbdev/aty/ati_ids.h diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c similarity index 100% rename from drivers/video/aty/aty128fb.c rename to drivers/video/fbdev/aty/aty128fb.c diff --git a/drivers/video/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h similarity index 100% rename from drivers/video/aty/atyfb.h rename to drivers/video/fbdev/aty/atyfb.h diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c similarity index 100% rename from drivers/video/aty/atyfb_base.c rename to drivers/video/fbdev/aty/atyfb_base.c diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c similarity index 100% rename from drivers/video/aty/mach64_accel.c rename to drivers/video/fbdev/aty/mach64_accel.c diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c similarity index 100% rename from drivers/video/aty/mach64_ct.c rename to drivers/video/fbdev/aty/mach64_ct.c diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c similarity index 100% rename from drivers/video/aty/mach64_cursor.c rename to drivers/video/fbdev/aty/mach64_cursor.c diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/fbdev/aty/mach64_gx.c similarity index 100% rename from drivers/video/aty/mach64_gx.c rename to drivers/video/fbdev/aty/mach64_gx.c diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/fbdev/aty/radeon_accel.c similarity index 100% rename from drivers/video/aty/radeon_accel.c rename to drivers/video/fbdev/aty/radeon_accel.c diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c similarity index 100% rename from drivers/video/aty/radeon_backlight.c rename to drivers/video/fbdev/aty/radeon_backlight.c diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c similarity index 100% rename from drivers/video/aty/radeon_base.c rename to drivers/video/fbdev/aty/radeon_base.c diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/fbdev/aty/radeon_i2c.c similarity index 100% rename from drivers/video/aty/radeon_i2c.c rename to drivers/video/fbdev/aty/radeon_i2c.c diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c similarity index 100% rename from drivers/video/aty/radeon_monitor.c rename to drivers/video/fbdev/aty/radeon_monitor.c diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/fbdev/aty/radeon_pm.c similarity index 100% rename from drivers/video/aty/radeon_pm.c rename to drivers/video/fbdev/aty/radeon_pm.c diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/fbdev/aty/radeonfb.h similarity index 100% rename from drivers/video/aty/radeonfb.h rename to drivers/video/fbdev/aty/radeonfb.h diff --git a/drivers/video/au1100fb.c b/drivers/video/fbdev/au1100fb.c similarity index 100% rename from drivers/video/au1100fb.c rename to drivers/video/fbdev/au1100fb.c diff --git a/drivers/video/au1100fb.h b/drivers/video/fbdev/au1100fb.h similarity index 100% rename from drivers/video/au1100fb.h rename to drivers/video/fbdev/au1100fb.h diff --git a/drivers/video/au1200fb.c b/drivers/video/fbdev/au1200fb.c similarity index 100% rename from drivers/video/au1200fb.c rename to drivers/video/fbdev/au1200fb.c diff --git a/drivers/video/au1200fb.h b/drivers/video/fbdev/au1200fb.h similarity index 100% rename from drivers/video/au1200fb.h rename to drivers/video/fbdev/au1200fb.h diff --git a/drivers/video/auo_k1900fb.c b/drivers/video/fbdev/auo_k1900fb.c similarity index 100% rename from drivers/video/auo_k1900fb.c rename to drivers/video/fbdev/auo_k1900fb.c diff --git a/drivers/video/auo_k1901fb.c b/drivers/video/fbdev/auo_k1901fb.c similarity index 100% rename from drivers/video/auo_k1901fb.c rename to drivers/video/fbdev/auo_k1901fb.c diff --git a/drivers/video/auo_k190x.c b/drivers/video/fbdev/auo_k190x.c similarity index 100% rename from drivers/video/auo_k190x.c rename to drivers/video/fbdev/auo_k190x.c diff --git a/drivers/video/auo_k190x.h b/drivers/video/fbdev/auo_k190x.h similarity index 100% rename from drivers/video/auo_k190x.h rename to drivers/video/fbdev/auo_k190x.h diff --git a/drivers/video/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c similarity index 100% rename from drivers/video/bf537-lq035.c rename to drivers/video/fbdev/bf537-lq035.c diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/fbdev/bf54x-lq043fb.c similarity index 100% rename from drivers/video/bf54x-lq043fb.c rename to drivers/video/fbdev/bf54x-lq043fb.c diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/fbdev/bfin-lq035q1-fb.c similarity index 100% rename from drivers/video/bfin-lq035q1-fb.c rename to drivers/video/fbdev/bfin-lq035q1-fb.c diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/fbdev/bfin-t350mcqb-fb.c similarity index 100% rename from drivers/video/bfin-t350mcqb-fb.c rename to drivers/video/fbdev/bfin-t350mcqb-fb.c diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c similarity index 100% rename from drivers/video/bfin_adv7393fb.c rename to drivers/video/fbdev/bfin_adv7393fb.c diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/fbdev/bfin_adv7393fb.h similarity index 100% rename from drivers/video/bfin_adv7393fb.h rename to drivers/video/fbdev/bfin_adv7393fb.h diff --git a/drivers/video/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c similarity index 100% rename from drivers/video/broadsheetfb.c rename to drivers/video/fbdev/broadsheetfb.c diff --git a/drivers/video/bt431.h b/drivers/video/fbdev/bt431.h similarity index 100% rename from drivers/video/bt431.h rename to drivers/video/fbdev/bt431.h diff --git a/drivers/video/bt455.h b/drivers/video/fbdev/bt455.h similarity index 100% rename from drivers/video/bt455.h rename to drivers/video/fbdev/bt455.h diff --git a/drivers/video/bw2.c b/drivers/video/fbdev/bw2.c similarity index 100% rename from drivers/video/bw2.c rename to drivers/video/fbdev/bw2.c diff --git a/drivers/video/c2p.h b/drivers/video/fbdev/c2p.h similarity index 100% rename from drivers/video/c2p.h rename to drivers/video/fbdev/c2p.h diff --git a/drivers/video/c2p_core.h b/drivers/video/fbdev/c2p_core.h similarity index 100% rename from drivers/video/c2p_core.h rename to drivers/video/fbdev/c2p_core.h diff --git a/drivers/video/c2p_iplan2.c b/drivers/video/fbdev/c2p_iplan2.c similarity index 100% rename from drivers/video/c2p_iplan2.c rename to drivers/video/fbdev/c2p_iplan2.c diff --git a/drivers/video/c2p_planar.c b/drivers/video/fbdev/c2p_planar.c similarity index 100% rename from drivers/video/c2p_planar.c rename to drivers/video/fbdev/c2p_planar.c diff --git a/drivers/video/carminefb.c b/drivers/video/fbdev/carminefb.c similarity index 100% rename from drivers/video/carminefb.c rename to drivers/video/fbdev/carminefb.c diff --git a/drivers/video/carminefb.h b/drivers/video/fbdev/carminefb.h similarity index 100% rename from drivers/video/carminefb.h rename to drivers/video/fbdev/carminefb.h diff --git a/drivers/video/carminefb_regs.h b/drivers/video/fbdev/carminefb_regs.h similarity index 100% rename from drivers/video/carminefb_regs.h rename to drivers/video/fbdev/carminefb_regs.h diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/fbdev/cfbcopyarea.c similarity index 100% rename from drivers/video/cfbcopyarea.c rename to drivers/video/fbdev/cfbcopyarea.c diff --git a/drivers/video/cfbfillrect.c b/drivers/video/fbdev/cfbfillrect.c similarity index 100% rename from drivers/video/cfbfillrect.c rename to drivers/video/fbdev/cfbfillrect.c diff --git a/drivers/video/cfbimgblt.c b/drivers/video/fbdev/cfbimgblt.c similarity index 100% rename from drivers/video/cfbimgblt.c rename to drivers/video/fbdev/cfbimgblt.c diff --git a/drivers/video/cg14.c b/drivers/video/fbdev/cg14.c similarity index 100% rename from drivers/video/cg14.c rename to drivers/video/fbdev/cg14.c diff --git a/drivers/video/cg3.c b/drivers/video/fbdev/cg3.c similarity index 100% rename from drivers/video/cg3.c rename to drivers/video/fbdev/cg3.c diff --git a/drivers/video/cg6.c b/drivers/video/fbdev/cg6.c similarity index 100% rename from drivers/video/cg6.c rename to drivers/video/fbdev/cg6.c diff --git a/drivers/video/chipsfb.c b/drivers/video/fbdev/chipsfb.c similarity index 100% rename from drivers/video/chipsfb.c rename to drivers/video/fbdev/chipsfb.c diff --git a/drivers/video/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c similarity index 100% rename from drivers/video/cirrusfb.c rename to drivers/video/fbdev/cirrusfb.c diff --git a/drivers/video/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c similarity index 100% rename from drivers/video/clps711xfb.c rename to drivers/video/fbdev/clps711xfb.c diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c similarity index 100% rename from drivers/video/cobalt_lcdfb.c rename to drivers/video/fbdev/cobalt_lcdfb.c diff --git a/drivers/video/controlfb.c b/drivers/video/fbdev/controlfb.c similarity index 100% rename from drivers/video/controlfb.c rename to drivers/video/fbdev/controlfb.c diff --git a/drivers/video/controlfb.h b/drivers/video/fbdev/controlfb.h similarity index 100% rename from drivers/video/controlfb.h rename to drivers/video/fbdev/controlfb.h diff --git a/drivers/video/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c similarity index 100% rename from drivers/video/cyber2000fb.c rename to drivers/video/fbdev/cyber2000fb.c diff --git a/drivers/video/cyber2000fb.h b/drivers/video/fbdev/cyber2000fb.h similarity index 100% rename from drivers/video/cyber2000fb.h rename to drivers/video/fbdev/cyber2000fb.h diff --git a/drivers/video/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c similarity index 100% rename from drivers/video/da8xx-fb.c rename to drivers/video/fbdev/da8xx-fb.c diff --git a/drivers/video/dnfb.c b/drivers/video/fbdev/dnfb.c similarity index 100% rename from drivers/video/dnfb.c rename to drivers/video/fbdev/dnfb.c diff --git a/drivers/video/edid.h b/drivers/video/fbdev/edid.h similarity index 100% rename from drivers/video/edid.h rename to drivers/video/fbdev/edid.h diff --git a/drivers/video/efifb.c b/drivers/video/fbdev/efifb.c similarity index 100% rename from drivers/video/efifb.c rename to drivers/video/fbdev/efifb.c diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c similarity index 100% rename from drivers/video/ep93xx-fb.c rename to drivers/video/fbdev/ep93xx-fb.c diff --git a/drivers/video/exynos/Kconfig b/drivers/video/fbdev/exynos/Kconfig similarity index 100% rename from drivers/video/exynos/Kconfig rename to drivers/video/fbdev/exynos/Kconfig diff --git a/drivers/video/exynos/Makefile b/drivers/video/fbdev/exynos/Makefile similarity index 100% rename from drivers/video/exynos/Makefile rename to drivers/video/fbdev/exynos/Makefile diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c similarity index 100% rename from drivers/video/exynos/exynos_mipi_dsi.c rename to drivers/video/fbdev/exynos/exynos_mipi_dsi.c diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c similarity index 100% rename from drivers/video/exynos/exynos_mipi_dsi_common.c rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h similarity index 100% rename from drivers/video/exynos/exynos_mipi_dsi_common.h rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c similarity index 100% rename from drivers/video/exynos/exynos_mipi_dsi_lowlevel.c rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h similarity index 100% rename from drivers/video/exynos/exynos_mipi_dsi_lowlevel.h rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h similarity index 100% rename from drivers/video/exynos/exynos_mipi_dsi_regs.h rename to drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/fbdev/exynos/s6e8ax0.c similarity index 100% rename from drivers/video/exynos/s6e8ax0.c rename to drivers/video/fbdev/exynos/s6e8ax0.c diff --git a/drivers/video/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c similarity index 100% rename from drivers/video/fb-puv3.c rename to drivers/video/fbdev/fb-puv3.c diff --git a/drivers/video/fb_ddc.c b/drivers/video/fbdev/fb_ddc.c similarity index 100% rename from drivers/video/fb_ddc.c rename to drivers/video/fbdev/fb_ddc.c diff --git a/drivers/video/fb_defio.c b/drivers/video/fbdev/fb_defio.c similarity index 100% rename from drivers/video/fb_defio.c rename to drivers/video/fbdev/fb_defio.c diff --git a/drivers/video/fb_draw.h b/drivers/video/fbdev/fb_draw.h similarity index 100% rename from drivers/video/fb_draw.h rename to drivers/video/fbdev/fb_draw.h diff --git a/drivers/video/fb_notify.c b/drivers/video/fbdev/fb_notify.c similarity index 100% rename from drivers/video/fb_notify.c rename to drivers/video/fbdev/fb_notify.c diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fbdev/fb_sys_fops.c similarity index 100% rename from drivers/video/fb_sys_fops.c rename to drivers/video/fbdev/fb_sys_fops.c diff --git a/drivers/video/fbcmap.c b/drivers/video/fbdev/fbcmap.c similarity index 100% rename from drivers/video/fbcmap.c rename to drivers/video/fbdev/fbcmap.c diff --git a/drivers/video/fbcvt.c b/drivers/video/fbdev/fbcvt.c similarity index 100% rename from drivers/video/fbcvt.c rename to drivers/video/fbdev/fbcvt.c diff --git a/drivers/video/fbmem.c b/drivers/video/fbdev/fbmem.c similarity index 100% rename from drivers/video/fbmem.c rename to drivers/video/fbdev/fbmem.c diff --git a/drivers/video/fbmon.c b/drivers/video/fbdev/fbmon.c similarity index 100% rename from drivers/video/fbmon.c rename to drivers/video/fbdev/fbmon.c diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbdev/fbsysfs.c similarity index 100% rename from drivers/video/fbsysfs.c rename to drivers/video/fbdev/fbsysfs.c diff --git a/drivers/video/ffb.c b/drivers/video/fbdev/ffb.c similarity index 100% rename from drivers/video/ffb.c rename to drivers/video/fbdev/ffb.c diff --git a/drivers/video/fm2fb.c b/drivers/video/fbdev/fm2fb.c similarity index 100% rename from drivers/video/fm2fb.c rename to drivers/video/fbdev/fm2fb.c diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c similarity index 100% rename from drivers/video/fsl-diu-fb.c rename to drivers/video/fbdev/fsl-diu-fb.c diff --git a/drivers/video/g364fb.c b/drivers/video/fbdev/g364fb.c similarity index 100% rename from drivers/video/g364fb.c rename to drivers/video/fbdev/g364fb.c diff --git a/drivers/video/gbefb.c b/drivers/video/fbdev/gbefb.c similarity index 100% rename from drivers/video/gbefb.c rename to drivers/video/fbdev/gbefb.c diff --git a/drivers/video/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig similarity index 100% rename from drivers/video/geode/Kconfig rename to drivers/video/fbdev/geode/Kconfig diff --git a/drivers/video/geode/Makefile b/drivers/video/fbdev/geode/Makefile similarity index 100% rename from drivers/video/geode/Makefile rename to drivers/video/fbdev/geode/Makefile diff --git a/drivers/video/geode/display_gx.c b/drivers/video/fbdev/geode/display_gx.c similarity index 100% rename from drivers/video/geode/display_gx.c rename to drivers/video/fbdev/geode/display_gx.c diff --git a/drivers/video/geode/display_gx1.c b/drivers/video/fbdev/geode/display_gx1.c similarity index 100% rename from drivers/video/geode/display_gx1.c rename to drivers/video/fbdev/geode/display_gx1.c diff --git a/drivers/video/geode/display_gx1.h b/drivers/video/fbdev/geode/display_gx1.h similarity index 100% rename from drivers/video/geode/display_gx1.h rename to drivers/video/fbdev/geode/display_gx1.h diff --git a/drivers/video/geode/geodefb.h b/drivers/video/fbdev/geode/geodefb.h similarity index 100% rename from drivers/video/geode/geodefb.h rename to drivers/video/fbdev/geode/geodefb.h diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c similarity index 100% rename from drivers/video/geode/gx1fb_core.c rename to drivers/video/fbdev/geode/gx1fb_core.c diff --git a/drivers/video/geode/gxfb.h b/drivers/video/fbdev/geode/gxfb.h similarity index 100% rename from drivers/video/geode/gxfb.h rename to drivers/video/fbdev/geode/gxfb.h diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c similarity index 100% rename from drivers/video/geode/gxfb_core.c rename to drivers/video/fbdev/geode/gxfb_core.c diff --git a/drivers/video/geode/lxfb.h b/drivers/video/fbdev/geode/lxfb.h similarity index 100% rename from drivers/video/geode/lxfb.h rename to drivers/video/fbdev/geode/lxfb.h diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c similarity index 100% rename from drivers/video/geode/lxfb_core.c rename to drivers/video/fbdev/geode/lxfb_core.c diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/fbdev/geode/lxfb_ops.c similarity index 100% rename from drivers/video/geode/lxfb_ops.c rename to drivers/video/fbdev/geode/lxfb_ops.c diff --git a/drivers/video/geode/suspend_gx.c b/drivers/video/fbdev/geode/suspend_gx.c similarity index 100% rename from drivers/video/geode/suspend_gx.c rename to drivers/video/fbdev/geode/suspend_gx.c diff --git a/drivers/video/geode/video_cs5530.c b/drivers/video/fbdev/geode/video_cs5530.c similarity index 100% rename from drivers/video/geode/video_cs5530.c rename to drivers/video/fbdev/geode/video_cs5530.c diff --git a/drivers/video/geode/video_cs5530.h b/drivers/video/fbdev/geode/video_cs5530.h similarity index 100% rename from drivers/video/geode/video_cs5530.h rename to drivers/video/fbdev/geode/video_cs5530.h diff --git a/drivers/video/geode/video_gx.c b/drivers/video/fbdev/geode/video_gx.c similarity index 100% rename from drivers/video/geode/video_gx.c rename to drivers/video/fbdev/geode/video_gx.c diff --git a/drivers/video/goldfishfb.c b/drivers/video/fbdev/goldfishfb.c similarity index 100% rename from drivers/video/goldfishfb.c rename to drivers/video/fbdev/goldfishfb.c diff --git a/drivers/video/grvga.c b/drivers/video/fbdev/grvga.c similarity index 100% rename from drivers/video/grvga.c rename to drivers/video/fbdev/grvga.c diff --git a/drivers/video/gxt4500.c b/drivers/video/fbdev/gxt4500.c similarity index 100% rename from drivers/video/gxt4500.c rename to drivers/video/fbdev/gxt4500.c diff --git a/drivers/video/hecubafb.c b/drivers/video/fbdev/hecubafb.c similarity index 100% rename from drivers/video/hecubafb.c rename to drivers/video/fbdev/hecubafb.c diff --git a/drivers/video/hgafb.c b/drivers/video/fbdev/hgafb.c similarity index 100% rename from drivers/video/hgafb.c rename to drivers/video/fbdev/hgafb.c diff --git a/drivers/video/hitfb.c b/drivers/video/fbdev/hitfb.c similarity index 100% rename from drivers/video/hitfb.c rename to drivers/video/fbdev/hitfb.c diff --git a/drivers/video/hpfb.c b/drivers/video/fbdev/hpfb.c similarity index 100% rename from drivers/video/hpfb.c rename to drivers/video/fbdev/hpfb.c diff --git a/drivers/video/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c similarity index 100% rename from drivers/video/hyperv_fb.c rename to drivers/video/fbdev/hyperv_fb.c diff --git a/drivers/video/i740_reg.h b/drivers/video/fbdev/i740_reg.h similarity index 100% rename from drivers/video/i740_reg.h rename to drivers/video/fbdev/i740_reg.h diff --git a/drivers/video/i740fb.c b/drivers/video/fbdev/i740fb.c similarity index 100% rename from drivers/video/i740fb.c rename to drivers/video/fbdev/i740fb.c diff --git a/drivers/video/i810/Makefile b/drivers/video/fbdev/i810/Makefile similarity index 100% rename from drivers/video/i810/Makefile rename to drivers/video/fbdev/i810/Makefile diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/fbdev/i810/i810-i2c.c similarity index 100% rename from drivers/video/i810/i810-i2c.c rename to drivers/video/fbdev/i810/i810-i2c.c diff --git a/drivers/video/i810/i810.h b/drivers/video/fbdev/i810/i810.h similarity index 100% rename from drivers/video/i810/i810.h rename to drivers/video/fbdev/i810/i810.h diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/fbdev/i810/i810_accel.c similarity index 100% rename from drivers/video/i810/i810_accel.c rename to drivers/video/fbdev/i810/i810_accel.c diff --git a/drivers/video/i810/i810_dvt.c b/drivers/video/fbdev/i810/i810_dvt.c similarity index 100% rename from drivers/video/i810/i810_dvt.c rename to drivers/video/fbdev/i810/i810_dvt.c diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/fbdev/i810/i810_gtf.c similarity index 100% rename from drivers/video/i810/i810_gtf.c rename to drivers/video/fbdev/i810/i810_gtf.c diff --git a/drivers/video/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c similarity index 100% rename from drivers/video/i810/i810_main.c rename to drivers/video/fbdev/i810/i810_main.c diff --git a/drivers/video/i810/i810_main.h b/drivers/video/fbdev/i810/i810_main.h similarity index 100% rename from drivers/video/i810/i810_main.h rename to drivers/video/fbdev/i810/i810_main.h diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/fbdev/i810/i810_regs.h similarity index 100% rename from drivers/video/i810/i810_regs.h rename to drivers/video/fbdev/i810/i810_regs.h diff --git a/drivers/video/igafb.c b/drivers/video/fbdev/igafb.c similarity index 100% rename from drivers/video/igafb.c rename to drivers/video/fbdev/igafb.c diff --git a/drivers/video/imsttfb.c b/drivers/video/fbdev/imsttfb.c similarity index 100% rename from drivers/video/imsttfb.c rename to drivers/video/fbdev/imsttfb.c diff --git a/drivers/video/imxfb.c b/drivers/video/fbdev/imxfb.c similarity index 100% rename from drivers/video/imxfb.c rename to drivers/video/fbdev/imxfb.c diff --git a/drivers/video/intelfb/Makefile b/drivers/video/fbdev/intelfb/Makefile similarity index 100% rename from drivers/video/intelfb/Makefile rename to drivers/video/fbdev/intelfb/Makefile diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/fbdev/intelfb/intelfb.h similarity index 100% rename from drivers/video/intelfb/intelfb.h rename to drivers/video/fbdev/intelfb/intelfb.h diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/fbdev/intelfb/intelfb_i2c.c similarity index 100% rename from drivers/video/intelfb/intelfb_i2c.c rename to drivers/video/fbdev/intelfb/intelfb_i2c.c diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c similarity index 100% rename from drivers/video/intelfb/intelfbdrv.c rename to drivers/video/fbdev/intelfb/intelfbdrv.c diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c similarity index 100% rename from drivers/video/intelfb/intelfbhw.c rename to drivers/video/fbdev/intelfb/intelfbhw.c diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/fbdev/intelfb/intelfbhw.h similarity index 100% rename from drivers/video/intelfb/intelfbhw.h rename to drivers/video/fbdev/intelfb/intelfbhw.h diff --git a/drivers/video/jz4740_fb.c b/drivers/video/fbdev/jz4740_fb.c similarity index 100% rename from drivers/video/jz4740_fb.c rename to drivers/video/fbdev/jz4740_fb.c diff --git a/drivers/video/kyro/Makefile b/drivers/video/fbdev/kyro/Makefile similarity index 100% rename from drivers/video/kyro/Makefile rename to drivers/video/fbdev/kyro/Makefile diff --git a/drivers/video/kyro/STG4000InitDevice.c b/drivers/video/fbdev/kyro/STG4000InitDevice.c similarity index 100% rename from drivers/video/kyro/STG4000InitDevice.c rename to drivers/video/fbdev/kyro/STG4000InitDevice.c diff --git a/drivers/video/kyro/STG4000Interface.h b/drivers/video/fbdev/kyro/STG4000Interface.h similarity index 100% rename from drivers/video/kyro/STG4000Interface.h rename to drivers/video/fbdev/kyro/STG4000Interface.h diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/fbdev/kyro/STG4000OverlayDevice.c similarity index 100% rename from drivers/video/kyro/STG4000OverlayDevice.c rename to drivers/video/fbdev/kyro/STG4000OverlayDevice.c diff --git a/drivers/video/kyro/STG4000Ramdac.c b/drivers/video/fbdev/kyro/STG4000Ramdac.c similarity index 100% rename from drivers/video/kyro/STG4000Ramdac.c rename to drivers/video/fbdev/kyro/STG4000Ramdac.c diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/fbdev/kyro/STG4000Reg.h similarity index 100% rename from drivers/video/kyro/STG4000Reg.h rename to drivers/video/fbdev/kyro/STG4000Reg.h diff --git a/drivers/video/kyro/STG4000VTG.c b/drivers/video/fbdev/kyro/STG4000VTG.c similarity index 100% rename from drivers/video/kyro/STG4000VTG.c rename to drivers/video/fbdev/kyro/STG4000VTG.c diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c similarity index 100% rename from drivers/video/kyro/fbdev.c rename to drivers/video/fbdev/kyro/fbdev.c diff --git a/drivers/video/leo.c b/drivers/video/fbdev/leo.c similarity index 100% rename from drivers/video/leo.c rename to drivers/video/fbdev/leo.c diff --git a/drivers/video/macfb.c b/drivers/video/fbdev/macfb.c similarity index 100% rename from drivers/video/macfb.c rename to drivers/video/fbdev/macfb.c diff --git a/drivers/video/macmodes.c b/drivers/video/fbdev/macmodes.c similarity index 100% rename from drivers/video/macmodes.c rename to drivers/video/fbdev/macmodes.c diff --git a/drivers/video/macmodes.h b/drivers/video/fbdev/macmodes.h similarity index 100% rename from drivers/video/macmodes.h rename to drivers/video/fbdev/macmodes.h diff --git a/drivers/video/matrox/Makefile b/drivers/video/fbdev/matrox/Makefile similarity index 100% rename from drivers/video/matrox/Makefile rename to drivers/video/fbdev/matrox/Makefile diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/fbdev/matrox/g450_pll.c similarity index 100% rename from drivers/video/matrox/g450_pll.c rename to drivers/video/fbdev/matrox/g450_pll.c diff --git a/drivers/video/matrox/g450_pll.h b/drivers/video/fbdev/matrox/g450_pll.h similarity index 100% rename from drivers/video/matrox/g450_pll.h rename to drivers/video/fbdev/matrox/g450_pll.h diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/fbdev/matrox/i2c-matroxfb.c similarity index 100% rename from drivers/video/matrox/i2c-matroxfb.c rename to drivers/video/fbdev/matrox/i2c-matroxfb.c diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/fbdev/matrox/matroxfb_DAC1064.c similarity index 100% rename from drivers/video/matrox/matroxfb_DAC1064.c rename to drivers/video/fbdev/matrox/matroxfb_DAC1064.c diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h similarity index 100% rename from drivers/video/matrox/matroxfb_DAC1064.h rename to drivers/video/fbdev/matrox/matroxfb_DAC1064.h diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c similarity index 100% rename from drivers/video/matrox/matroxfb_Ti3026.c rename to drivers/video/fbdev/matrox/matroxfb_Ti3026.c diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h similarity index 100% rename from drivers/video/matrox/matroxfb_Ti3026.h rename to drivers/video/fbdev/matrox/matroxfb_Ti3026.h diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/fbdev/matrox/matroxfb_accel.c similarity index 100% rename from drivers/video/matrox/matroxfb_accel.c rename to drivers/video/fbdev/matrox/matroxfb_accel.c diff --git a/drivers/video/matrox/matroxfb_accel.h b/drivers/video/fbdev/matrox/matroxfb_accel.h similarity index 100% rename from drivers/video/matrox/matroxfb_accel.h rename to drivers/video/fbdev/matrox/matroxfb_accel.h diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c similarity index 100% rename from drivers/video/matrox/matroxfb_base.c rename to drivers/video/fbdev/matrox/matroxfb_base.c diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h similarity index 100% rename from drivers/video/matrox/matroxfb_base.h rename to drivers/video/fbdev/matrox/matroxfb_base.h diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c similarity index 100% rename from drivers/video/matrox/matroxfb_crtc2.c rename to drivers/video/fbdev/matrox/matroxfb_crtc2.c diff --git a/drivers/video/matrox/matroxfb_crtc2.h b/drivers/video/fbdev/matrox/matroxfb_crtc2.h similarity index 100% rename from drivers/video/matrox/matroxfb_crtc2.h rename to drivers/video/fbdev/matrox/matroxfb_crtc2.h diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/fbdev/matrox/matroxfb_g450.c similarity index 100% rename from drivers/video/matrox/matroxfb_g450.c rename to drivers/video/fbdev/matrox/matroxfb_g450.c diff --git a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/fbdev/matrox/matroxfb_g450.h similarity index 100% rename from drivers/video/matrox/matroxfb_g450.h rename to drivers/video/fbdev/matrox/matroxfb_g450.h diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c similarity index 100% rename from drivers/video/matrox/matroxfb_maven.c rename to drivers/video/fbdev/matrox/matroxfb_maven.c diff --git a/drivers/video/matrox/matroxfb_maven.h b/drivers/video/fbdev/matrox/matroxfb_maven.h similarity index 100% rename from drivers/video/matrox/matroxfb_maven.h rename to drivers/video/fbdev/matrox/matroxfb_maven.h diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/fbdev/matrox/matroxfb_misc.c similarity index 100% rename from drivers/video/matrox/matroxfb_misc.c rename to drivers/video/fbdev/matrox/matroxfb_misc.c diff --git a/drivers/video/matrox/matroxfb_misc.h b/drivers/video/fbdev/matrox/matroxfb_misc.h similarity index 100% rename from drivers/video/matrox/matroxfb_misc.h rename to drivers/video/fbdev/matrox/matroxfb_misc.h diff --git a/drivers/video/maxinefb.c b/drivers/video/fbdev/maxinefb.c similarity index 100% rename from drivers/video/maxinefb.c rename to drivers/video/fbdev/maxinefb.c diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/fbdev/mb862xx/Makefile similarity index 100% rename from drivers/video/mb862xx/Makefile rename to drivers/video/fbdev/mb862xx/Makefile diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c similarity index 100% rename from drivers/video/mb862xx/mb862xx-i2c.c rename to drivers/video/fbdev/mb862xx/mb862xx-i2c.c diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/fbdev/mb862xx/mb862xx_reg.h similarity index 100% rename from drivers/video/mb862xx/mb862xx_reg.h rename to drivers/video/fbdev/mb862xx/mb862xx_reg.h diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/fbdev/mb862xx/mb862xxfb.h similarity index 100% rename from drivers/video/mb862xx/mb862xxfb.h rename to drivers/video/fbdev/mb862xx/mb862xxfb.h diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c similarity index 100% rename from drivers/video/mb862xx/mb862xxfb_accel.c rename to drivers/video/fbdev/mb862xx/mb862xxfb_accel.c diff --git a/drivers/video/mb862xx/mb862xxfb_accel.h b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h similarity index 100% rename from drivers/video/mb862xx/mb862xxfb_accel.h rename to drivers/video/fbdev/mb862xx/mb862xxfb_accel.h diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c similarity index 100% rename from drivers/video/mb862xx/mb862xxfbdrv.c rename to drivers/video/fbdev/mb862xx/mb862xxfbdrv.c diff --git a/drivers/video/mbx/Makefile b/drivers/video/fbdev/mbx/Makefile similarity index 100% rename from drivers/video/mbx/Makefile rename to drivers/video/fbdev/mbx/Makefile diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/fbdev/mbx/mbxdebugfs.c similarity index 100% rename from drivers/video/mbx/mbxdebugfs.c rename to drivers/video/fbdev/mbx/mbxdebugfs.c diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c similarity index 100% rename from drivers/video/mbx/mbxfb.c rename to drivers/video/fbdev/mbx/mbxfb.c diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/fbdev/mbx/reg_bits.h similarity index 100% rename from drivers/video/mbx/reg_bits.h rename to drivers/video/fbdev/mbx/reg_bits.h diff --git a/drivers/video/mbx/regs.h b/drivers/video/fbdev/mbx/regs.h similarity index 100% rename from drivers/video/mbx/regs.h rename to drivers/video/fbdev/mbx/regs.h diff --git a/drivers/video/metronomefb.c b/drivers/video/fbdev/metronomefb.c similarity index 100% rename from drivers/video/metronomefb.c rename to drivers/video/fbdev/metronomefb.c diff --git a/drivers/video/mmp/Kconfig b/drivers/video/fbdev/mmp/Kconfig similarity index 61% rename from drivers/video/mmp/Kconfig rename to drivers/video/fbdev/mmp/Kconfig index e9ea39e13722..d4a4ffc24749 100644 --- a/drivers/video/mmp/Kconfig +++ b/drivers/video/fbdev/mmp/Kconfig @@ -5,7 +5,7 @@ menuconfig MMP_DISP Marvell Display Subsystem support. if MMP_DISP -source "drivers/video/mmp/hw/Kconfig" -source "drivers/video/mmp/panel/Kconfig" -source "drivers/video/mmp/fb/Kconfig" +source "drivers/video/fbdev/mmp/hw/Kconfig" +source "drivers/video/fbdev/mmp/panel/Kconfig" +source "drivers/video/fbdev/mmp/fb/Kconfig" endif diff --git a/drivers/video/mmp/Makefile b/drivers/video/fbdev/mmp/Makefile similarity index 100% rename from drivers/video/mmp/Makefile rename to drivers/video/fbdev/mmp/Makefile diff --git a/drivers/video/mmp/core.c b/drivers/video/fbdev/mmp/core.c similarity index 100% rename from drivers/video/mmp/core.c rename to drivers/video/fbdev/mmp/core.c diff --git a/drivers/video/mmp/fb/Kconfig b/drivers/video/fbdev/mmp/fb/Kconfig similarity index 100% rename from drivers/video/mmp/fb/Kconfig rename to drivers/video/fbdev/mmp/fb/Kconfig diff --git a/drivers/video/mmp/fb/Makefile b/drivers/video/fbdev/mmp/fb/Makefile similarity index 100% rename from drivers/video/mmp/fb/Makefile rename to drivers/video/fbdev/mmp/fb/Makefile diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c similarity index 100% rename from drivers/video/mmp/fb/mmpfb.c rename to drivers/video/fbdev/mmp/fb/mmpfb.c diff --git a/drivers/video/mmp/fb/mmpfb.h b/drivers/video/fbdev/mmp/fb/mmpfb.h similarity index 100% rename from drivers/video/mmp/fb/mmpfb.h rename to drivers/video/fbdev/mmp/fb/mmpfb.h diff --git a/drivers/video/mmp/hw/Kconfig b/drivers/video/fbdev/mmp/hw/Kconfig similarity index 100% rename from drivers/video/mmp/hw/Kconfig rename to drivers/video/fbdev/mmp/hw/Kconfig diff --git a/drivers/video/mmp/hw/Makefile b/drivers/video/fbdev/mmp/hw/Makefile similarity index 100% rename from drivers/video/mmp/hw/Makefile rename to drivers/video/fbdev/mmp/hw/Makefile diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c similarity index 100% rename from drivers/video/mmp/hw/mmp_ctrl.c rename to drivers/video/fbdev/mmp/hw/mmp_ctrl.c diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/fbdev/mmp/hw/mmp_ctrl.h similarity index 100% rename from drivers/video/mmp/hw/mmp_ctrl.h rename to drivers/video/fbdev/mmp/hw/mmp_ctrl.h diff --git a/drivers/video/mmp/hw/mmp_spi.c b/drivers/video/fbdev/mmp/hw/mmp_spi.c similarity index 100% rename from drivers/video/mmp/hw/mmp_spi.c rename to drivers/video/fbdev/mmp/hw/mmp_spi.c diff --git a/drivers/video/mmp/panel/Kconfig b/drivers/video/fbdev/mmp/panel/Kconfig similarity index 100% rename from drivers/video/mmp/panel/Kconfig rename to drivers/video/fbdev/mmp/panel/Kconfig diff --git a/drivers/video/mmp/panel/Makefile b/drivers/video/fbdev/mmp/panel/Makefile similarity index 100% rename from drivers/video/mmp/panel/Makefile rename to drivers/video/fbdev/mmp/panel/Makefile diff --git a/drivers/video/mmp/panel/tpo_tj032md01bw.c b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c similarity index 100% rename from drivers/video/mmp/panel/tpo_tj032md01bw.c rename to drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c diff --git a/drivers/video/modedb.c b/drivers/video/fbdev/modedb.c similarity index 100% rename from drivers/video/modedb.c rename to drivers/video/fbdev/modedb.c diff --git a/drivers/video/msm/Makefile b/drivers/video/fbdev/msm/Makefile similarity index 100% rename from drivers/video/msm/Makefile rename to drivers/video/fbdev/msm/Makefile diff --git a/drivers/video/msm/mddi.c b/drivers/video/fbdev/msm/mddi.c similarity index 100% rename from drivers/video/msm/mddi.c rename to drivers/video/fbdev/msm/mddi.c diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c similarity index 100% rename from drivers/video/msm/mddi_client_dummy.c rename to drivers/video/fbdev/msm/mddi_client_dummy.c diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/fbdev/msm/mddi_client_nt35399.c similarity index 100% rename from drivers/video/msm/mddi_client_nt35399.c rename to drivers/video/fbdev/msm/mddi_client_nt35399.c diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/fbdev/msm/mddi_client_toshiba.c similarity index 100% rename from drivers/video/msm/mddi_client_toshiba.c rename to drivers/video/fbdev/msm/mddi_client_toshiba.c diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/fbdev/msm/mddi_hw.h similarity index 100% rename from drivers/video/msm/mddi_hw.h rename to drivers/video/fbdev/msm/mddi_hw.h diff --git a/drivers/video/msm/mdp.c b/drivers/video/fbdev/msm/mdp.c similarity index 100% rename from drivers/video/msm/mdp.c rename to drivers/video/fbdev/msm/mdp.c diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/fbdev/msm/mdp_csc_table.h similarity index 100% rename from drivers/video/msm/mdp_csc_table.h rename to drivers/video/fbdev/msm/mdp_csc_table.h diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/fbdev/msm/mdp_hw.h similarity index 100% rename from drivers/video/msm/mdp_hw.h rename to drivers/video/fbdev/msm/mdp_hw.h diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/fbdev/msm/mdp_ppp.c similarity index 100% rename from drivers/video/msm/mdp_ppp.c rename to drivers/video/fbdev/msm/mdp_ppp.c diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/fbdev/msm/mdp_scale_tables.c similarity index 100% rename from drivers/video/msm/mdp_scale_tables.c rename to drivers/video/fbdev/msm/mdp_scale_tables.c diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/fbdev/msm/mdp_scale_tables.h similarity index 100% rename from drivers/video/msm/mdp_scale_tables.h rename to drivers/video/fbdev/msm/mdp_scale_tables.h diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/fbdev/msm/msm_fb.c similarity index 100% rename from drivers/video/msm/msm_fb.c rename to drivers/video/fbdev/msm/msm_fb.c diff --git a/drivers/video/mx3fb.c b/drivers/video/fbdev/mx3fb.c similarity index 100% rename from drivers/video/mx3fb.c rename to drivers/video/fbdev/mx3fb.c diff --git a/drivers/video/mxsfb.c b/drivers/video/fbdev/mxsfb.c similarity index 100% rename from drivers/video/mxsfb.c rename to drivers/video/fbdev/mxsfb.c diff --git a/drivers/video/n411.c b/drivers/video/fbdev/n411.c similarity index 100% rename from drivers/video/n411.c rename to drivers/video/fbdev/n411.c diff --git a/drivers/video/neofb.c b/drivers/video/fbdev/neofb.c similarity index 100% rename from drivers/video/neofb.c rename to drivers/video/fbdev/neofb.c diff --git a/drivers/video/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c similarity index 100% rename from drivers/video/nuc900fb.c rename to drivers/video/fbdev/nuc900fb.c diff --git a/drivers/video/nuc900fb.h b/drivers/video/fbdev/nuc900fb.h similarity index 100% rename from drivers/video/nuc900fb.h rename to drivers/video/fbdev/nuc900fb.h diff --git a/drivers/video/nvidia/Makefile b/drivers/video/fbdev/nvidia/Makefile similarity index 100% rename from drivers/video/nvidia/Makefile rename to drivers/video/fbdev/nvidia/Makefile diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/fbdev/nvidia/nv_accel.c similarity index 100% rename from drivers/video/nvidia/nv_accel.c rename to drivers/video/fbdev/nvidia/nv_accel.c diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c similarity index 100% rename from drivers/video/nvidia/nv_backlight.c rename to drivers/video/fbdev/nvidia/nv_backlight.c diff --git a/drivers/video/nvidia/nv_dma.h b/drivers/video/fbdev/nvidia/nv_dma.h similarity index 100% rename from drivers/video/nvidia/nv_dma.h rename to drivers/video/fbdev/nvidia/nv_dma.h diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/fbdev/nvidia/nv_hw.c similarity index 100% rename from drivers/video/nvidia/nv_hw.c rename to drivers/video/fbdev/nvidia/nv_hw.c diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/fbdev/nvidia/nv_i2c.c similarity index 100% rename from drivers/video/nvidia/nv_i2c.c rename to drivers/video/fbdev/nvidia/nv_i2c.c diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/fbdev/nvidia/nv_local.h similarity index 100% rename from drivers/video/nvidia/nv_local.h rename to drivers/video/fbdev/nvidia/nv_local.h diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/fbdev/nvidia/nv_of.c similarity index 100% rename from drivers/video/nvidia/nv_of.c rename to drivers/video/fbdev/nvidia/nv_of.c diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/fbdev/nvidia/nv_proto.h similarity index 100% rename from drivers/video/nvidia/nv_proto.h rename to drivers/video/fbdev/nvidia/nv_proto.h diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c similarity index 100% rename from drivers/video/nvidia/nv_setup.c rename to drivers/video/fbdev/nvidia/nv_setup.c diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/fbdev/nvidia/nv_type.h similarity index 100% rename from drivers/video/nvidia/nv_type.h rename to drivers/video/fbdev/nvidia/nv_type.h diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c similarity index 100% rename from drivers/video/nvidia/nvidia.c rename to drivers/video/fbdev/nvidia/nvidia.c diff --git a/drivers/video/ocfb.c b/drivers/video/fbdev/ocfb.c similarity index 100% rename from drivers/video/ocfb.c rename to drivers/video/fbdev/ocfb.c diff --git a/drivers/video/offb.c b/drivers/video/fbdev/offb.c similarity index 100% rename from drivers/video/offb.c rename to drivers/video/fbdev/offb.c diff --git a/drivers/video/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig similarity index 100% rename from drivers/video/omap/Kconfig rename to drivers/video/fbdev/omap/Kconfig diff --git a/drivers/video/omap/Makefile b/drivers/video/fbdev/omap/Makefile similarity index 100% rename from drivers/video/omap/Makefile rename to drivers/video/fbdev/omap/Makefile diff --git a/drivers/video/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c similarity index 100% rename from drivers/video/omap/hwa742.c rename to drivers/video/fbdev/omap/hwa742.c diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/fbdev/omap/lcd_ams_delta.c similarity index 100% rename from drivers/video/omap/lcd_ams_delta.c rename to drivers/video/fbdev/omap/lcd_ams_delta.c diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c similarity index 100% rename from drivers/video/omap/lcd_h3.c rename to drivers/video/fbdev/omap/lcd_h3.c diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/fbdev/omap/lcd_htcherald.c similarity index 100% rename from drivers/video/omap/lcd_htcherald.c rename to drivers/video/fbdev/omap/lcd_htcherald.c diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/fbdev/omap/lcd_inn1510.c similarity index 100% rename from drivers/video/omap/lcd_inn1510.c rename to drivers/video/fbdev/omap/lcd_inn1510.c diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/fbdev/omap/lcd_inn1610.c similarity index 100% rename from drivers/video/omap/lcd_inn1610.c rename to drivers/video/fbdev/omap/lcd_inn1610.c diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c similarity index 100% rename from drivers/video/omap/lcd_mipid.c rename to drivers/video/fbdev/omap/lcd_mipid.c diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/fbdev/omap/lcd_osk.c similarity index 100% rename from drivers/video/omap/lcd_osk.c rename to drivers/video/fbdev/omap/lcd_osk.c diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/fbdev/omap/lcd_palmte.c similarity index 100% rename from drivers/video/omap/lcd_palmte.c rename to drivers/video/fbdev/omap/lcd_palmte.c diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/fbdev/omap/lcd_palmtt.c similarity index 100% rename from drivers/video/omap/lcd_palmtt.c rename to drivers/video/fbdev/omap/lcd_palmtt.c diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/fbdev/omap/lcd_palmz71.c similarity index 100% rename from drivers/video/omap/lcd_palmz71.c rename to drivers/video/fbdev/omap/lcd_palmz71.c diff --git a/drivers/video/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c similarity index 100% rename from drivers/video/omap/lcdc.c rename to drivers/video/fbdev/omap/lcdc.c diff --git a/drivers/video/omap/lcdc.h b/drivers/video/fbdev/omap/lcdc.h similarity index 100% rename from drivers/video/omap/lcdc.h rename to drivers/video/fbdev/omap/lcdc.h diff --git a/drivers/video/omap/omapfb.h b/drivers/video/fbdev/omap/omapfb.h similarity index 100% rename from drivers/video/omap/omapfb.h rename to drivers/video/fbdev/omap/omapfb.h diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c similarity index 100% rename from drivers/video/omap/omapfb_main.c rename to drivers/video/fbdev/omap/omapfb_main.c diff --git a/drivers/video/omap/sossi.c b/drivers/video/fbdev/omap/sossi.c similarity index 100% rename from drivers/video/omap/sossi.c rename to drivers/video/fbdev/omap/sossi.c diff --git a/drivers/video/fbdev/omap2/Kconfig b/drivers/video/fbdev/omap2/Kconfig new file mode 100644 index 000000000000..c22955d2de9a --- /dev/null +++ b/drivers/video/fbdev/omap2/Kconfig @@ -0,0 +1,10 @@ +config OMAP2_VRFB + bool + +if ARCH_OMAP2PLUS + +source "drivers/video/fbdev/omap2/dss/Kconfig" +source "drivers/video/fbdev/omap2/omapfb/Kconfig" +source "drivers/video/fbdev/omap2/displays-new/Kconfig" + +endif diff --git a/drivers/video/omap2/Makefile b/drivers/video/fbdev/omap2/Makefile similarity index 100% rename from drivers/video/omap2/Makefile rename to drivers/video/fbdev/omap2/Makefile diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/fbdev/omap2/displays-new/Kconfig similarity index 100% rename from drivers/video/omap2/displays-new/Kconfig rename to drivers/video/fbdev/omap2/displays-new/Kconfig diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/fbdev/omap2/displays-new/Makefile similarity index 100% rename from drivers/video/omap2/displays-new/Makefile rename to drivers/video/fbdev/omap2/displays-new/Makefile diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c similarity index 100% rename from drivers/video/omap2/displays-new/connector-analog-tv.c rename to drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c similarity index 100% rename from drivers/video/omap2/displays-new/connector-dvi.c rename to drivers/video/fbdev/omap2/displays-new/connector-dvi.c diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c similarity index 100% rename from drivers/video/omap2/displays-new/connector-hdmi.c rename to drivers/video/fbdev/omap2/displays-new/connector-hdmi.c diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c similarity index 100% rename from drivers/video/omap2/displays-new/encoder-tfp410.c rename to drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c similarity index 100% rename from drivers/video/omap2/displays-new/encoder-tpd12s015.c rename to drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c diff --git a/drivers/video/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-dpi.c rename to drivers/video/fbdev/omap2/displays-new/panel-dpi.c diff --git a/drivers/video/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-dsi-cm.c rename to drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c diff --git a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c rename to drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c diff --git a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c rename to drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c rename to drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-sony-acx565akm.c rename to drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c rename to drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c similarity index 100% rename from drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c rename to drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig similarity index 100% rename from drivers/video/omap2/dss/Kconfig rename to drivers/video/fbdev/omap2/dss/Kconfig diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile similarity index 100% rename from drivers/video/omap2/dss/Makefile rename to drivers/video/fbdev/omap2/dss/Makefile diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/fbdev/omap2/dss/apply.c similarity index 100% rename from drivers/video/omap2/dss/apply.c rename to drivers/video/fbdev/omap2/dss/apply.c diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c similarity index 100% rename from drivers/video/omap2/dss/core.c rename to drivers/video/fbdev/omap2/dss/core.c diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/fbdev/omap2/dss/dispc-compat.c similarity index 100% rename from drivers/video/omap2/dss/dispc-compat.c rename to drivers/video/fbdev/omap2/dss/dispc-compat.c diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/fbdev/omap2/dss/dispc-compat.h similarity index 100% rename from drivers/video/omap2/dss/dispc-compat.h rename to drivers/video/fbdev/omap2/dss/dispc-compat.h diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c similarity index 100% rename from drivers/video/omap2/dss/dispc.c rename to drivers/video/fbdev/omap2/dss/dispc.c diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h similarity index 100% rename from drivers/video/omap2/dss/dispc.h rename to drivers/video/fbdev/omap2/dss/dispc.h diff --git a/drivers/video/omap2/dss/dispc_coefs.c b/drivers/video/fbdev/omap2/dss/dispc_coefs.c similarity index 100% rename from drivers/video/omap2/dss/dispc_coefs.c rename to drivers/video/fbdev/omap2/dss/dispc_coefs.c diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/fbdev/omap2/dss/display-sysfs.c similarity index 100% rename from drivers/video/omap2/dss/display-sysfs.c rename to drivers/video/fbdev/omap2/dss/display-sysfs.c diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/fbdev/omap2/dss/display.c similarity index 100% rename from drivers/video/omap2/dss/display.c rename to drivers/video/fbdev/omap2/dss/display.c diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c similarity index 100% rename from drivers/video/omap2/dss/dpi.c rename to drivers/video/fbdev/omap2/dss/dpi.c diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c similarity index 100% rename from drivers/video/omap2/dss/dsi.c rename to drivers/video/fbdev/omap2/dss/dsi.c diff --git a/drivers/video/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c similarity index 100% rename from drivers/video/omap2/dss/dss-of.c rename to drivers/video/fbdev/omap2/dss/dss-of.c diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c similarity index 100% rename from drivers/video/omap2/dss/dss.c rename to drivers/video/fbdev/omap2/dss/dss.c diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h similarity index 100% rename from drivers/video/omap2/dss/dss.h rename to drivers/video/fbdev/omap2/dss/dss.h diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c similarity index 100% rename from drivers/video/omap2/dss/dss_features.c rename to drivers/video/fbdev/omap2/dss/dss_features.c diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h similarity index 100% rename from drivers/video/omap2/dss/dss_features.h rename to drivers/video/fbdev/omap2/dss/dss_features.h diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h similarity index 100% rename from drivers/video/omap2/dss/hdmi.h rename to drivers/video/fbdev/omap2/dss/hdmi.h diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c similarity index 100% rename from drivers/video/omap2/dss/hdmi4.c rename to drivers/video/fbdev/omap2/dss/hdmi4.c diff --git a/drivers/video/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c similarity index 100% rename from drivers/video/omap2/dss/hdmi4_core.c rename to drivers/video/fbdev/omap2/dss/hdmi4_core.c diff --git a/drivers/video/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h similarity index 100% rename from drivers/video/omap2/dss/hdmi4_core.h rename to drivers/video/fbdev/omap2/dss/hdmi4_core.h diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c similarity index 100% rename from drivers/video/omap2/dss/hdmi_common.c rename to drivers/video/fbdev/omap2/dss/hdmi_common.c diff --git a/drivers/video/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c similarity index 100% rename from drivers/video/omap2/dss/hdmi_phy.c rename to drivers/video/fbdev/omap2/dss/hdmi_phy.c diff --git a/drivers/video/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c similarity index 100% rename from drivers/video/omap2/dss/hdmi_pll.c rename to drivers/video/fbdev/omap2/dss/hdmi_pll.c diff --git a/drivers/video/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c similarity index 100% rename from drivers/video/omap2/dss/hdmi_wp.c rename to drivers/video/fbdev/omap2/dss/hdmi_wp.c diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/fbdev/omap2/dss/manager-sysfs.c similarity index 100% rename from drivers/video/omap2/dss/manager-sysfs.c rename to drivers/video/fbdev/omap2/dss/manager-sysfs.c diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/fbdev/omap2/dss/manager.c similarity index 100% rename from drivers/video/omap2/dss/manager.c rename to drivers/video/fbdev/omap2/dss/manager.c diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c similarity index 100% rename from drivers/video/omap2/dss/output.c rename to drivers/video/fbdev/omap2/dss/output.c diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/fbdev/omap2/dss/overlay-sysfs.c similarity index 100% rename from drivers/video/omap2/dss/overlay-sysfs.c rename to drivers/video/fbdev/omap2/dss/overlay-sysfs.c diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/fbdev/omap2/dss/overlay.c similarity index 100% rename from drivers/video/omap2/dss/overlay.c rename to drivers/video/fbdev/omap2/dss/overlay.c diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c similarity index 100% rename from drivers/video/omap2/dss/rfbi.c rename to drivers/video/fbdev/omap2/dss/rfbi.c diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c similarity index 100% rename from drivers/video/omap2/dss/sdi.c rename to drivers/video/fbdev/omap2/dss/sdi.c diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c similarity index 100% rename from drivers/video/omap2/dss/venc.c rename to drivers/video/fbdev/omap2/dss/venc.c diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/fbdev/omap2/dss/venc_panel.c similarity index 100% rename from drivers/video/omap2/dss/venc_panel.c rename to drivers/video/fbdev/omap2/dss/venc_panel.c diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig similarity index 100% rename from drivers/video/omap2/omapfb/Kconfig rename to drivers/video/fbdev/omap2/omapfb/Kconfig diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/fbdev/omap2/omapfb/Makefile similarity index 100% rename from drivers/video/omap2/omapfb/Makefile rename to drivers/video/fbdev/omap2/omapfb/Makefile diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c similarity index 100% rename from drivers/video/omap2/omapfb/omapfb-ioctl.c rename to drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c similarity index 100% rename from drivers/video/omap2/omapfb/omapfb-main.c rename to drivers/video/fbdev/omap2/omapfb/omapfb-main.c diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c similarity index 100% rename from drivers/video/omap2/omapfb/omapfb-sysfs.c rename to drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/fbdev/omap2/omapfb/omapfb.h similarity index 100% rename from drivers/video/omap2/omapfb/omapfb.h rename to drivers/video/fbdev/omap2/omapfb/omapfb.h diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/fbdev/omap2/vrfb.c similarity index 100% rename from drivers/video/omap2/vrfb.c rename to drivers/video/fbdev/omap2/vrfb.c diff --git a/drivers/video/p9100.c b/drivers/video/fbdev/p9100.c similarity index 100% rename from drivers/video/p9100.c rename to drivers/video/fbdev/p9100.c diff --git a/drivers/video/platinumfb.c b/drivers/video/fbdev/platinumfb.c similarity index 100% rename from drivers/video/platinumfb.c rename to drivers/video/fbdev/platinumfb.c diff --git a/drivers/video/platinumfb.h b/drivers/video/fbdev/platinumfb.h similarity index 100% rename from drivers/video/platinumfb.h rename to drivers/video/fbdev/platinumfb.h diff --git a/drivers/video/pm2fb.c b/drivers/video/fbdev/pm2fb.c similarity index 100% rename from drivers/video/pm2fb.c rename to drivers/video/fbdev/pm2fb.c diff --git a/drivers/video/pm3fb.c b/drivers/video/fbdev/pm3fb.c similarity index 100% rename from drivers/video/pm3fb.c rename to drivers/video/fbdev/pm3fb.c diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c similarity index 100% rename from drivers/video/pmag-aa-fb.c rename to drivers/video/fbdev/pmag-aa-fb.c diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/fbdev/pmag-ba-fb.c similarity index 100% rename from drivers/video/pmag-ba-fb.c rename to drivers/video/fbdev/pmag-ba-fb.c diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/fbdev/pmagb-b-fb.c similarity index 100% rename from drivers/video/pmagb-b-fb.c rename to drivers/video/fbdev/pmagb-b-fb.c diff --git a/drivers/video/ps3fb.c b/drivers/video/fbdev/ps3fb.c similarity index 100% rename from drivers/video/ps3fb.c rename to drivers/video/fbdev/ps3fb.c diff --git a/drivers/video/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c similarity index 100% rename from drivers/video/pvr2fb.c rename to drivers/video/fbdev/pvr2fb.c diff --git a/drivers/video/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c similarity index 100% rename from drivers/video/pxa168fb.c rename to drivers/video/fbdev/pxa168fb.c diff --git a/drivers/video/pxa168fb.h b/drivers/video/fbdev/pxa168fb.h similarity index 100% rename from drivers/video/pxa168fb.h rename to drivers/video/fbdev/pxa168fb.h diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c similarity index 100% rename from drivers/video/pxa3xx-gcu.c rename to drivers/video/fbdev/pxa3xx-gcu.c diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/fbdev/pxa3xx-gcu.h similarity index 100% rename from drivers/video/pxa3xx-gcu.h rename to drivers/video/fbdev/pxa3xx-gcu.h diff --git a/drivers/video/pxafb.c b/drivers/video/fbdev/pxafb.c similarity index 100% rename from drivers/video/pxafb.c rename to drivers/video/fbdev/pxafb.c diff --git a/drivers/video/pxafb.h b/drivers/video/fbdev/pxafb.h similarity index 100% rename from drivers/video/pxafb.h rename to drivers/video/fbdev/pxafb.h diff --git a/drivers/video/q40fb.c b/drivers/video/fbdev/q40fb.c similarity index 100% rename from drivers/video/q40fb.c rename to drivers/video/fbdev/q40fb.c diff --git a/drivers/video/riva/Makefile b/drivers/video/fbdev/riva/Makefile similarity index 100% rename from drivers/video/riva/Makefile rename to drivers/video/fbdev/riva/Makefile diff --git a/drivers/video/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c similarity index 100% rename from drivers/video/riva/fbdev.c rename to drivers/video/fbdev/riva/fbdev.c diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/fbdev/riva/nv_driver.c similarity index 100% rename from drivers/video/riva/nv_driver.c rename to drivers/video/fbdev/riva/nv_driver.c diff --git a/drivers/video/riva/nv_type.h b/drivers/video/fbdev/riva/nv_type.h similarity index 100% rename from drivers/video/riva/nv_type.h rename to drivers/video/fbdev/riva/nv_type.h diff --git a/drivers/video/riva/nvreg.h b/drivers/video/fbdev/riva/nvreg.h similarity index 100% rename from drivers/video/riva/nvreg.h rename to drivers/video/fbdev/riva/nvreg.h diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c similarity index 100% rename from drivers/video/riva/riva_hw.c rename to drivers/video/fbdev/riva/riva_hw.c diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/fbdev/riva/riva_hw.h similarity index 100% rename from drivers/video/riva/riva_hw.h rename to drivers/video/fbdev/riva/riva_hw.h diff --git a/drivers/video/riva/riva_tbl.h b/drivers/video/fbdev/riva/riva_tbl.h similarity index 100% rename from drivers/video/riva/riva_tbl.h rename to drivers/video/fbdev/riva/riva_tbl.h diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/fbdev/riva/rivafb-i2c.c similarity index 100% rename from drivers/video/riva/rivafb-i2c.c rename to drivers/video/fbdev/riva/rivafb-i2c.c diff --git a/drivers/video/riva/rivafb.h b/drivers/video/fbdev/riva/rivafb.h similarity index 100% rename from drivers/video/riva/rivafb.h rename to drivers/video/fbdev/riva/rivafb.h diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c similarity index 100% rename from drivers/video/s1d13xxxfb.c rename to drivers/video/fbdev/s1d13xxxfb.c diff --git a/drivers/video/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c similarity index 100% rename from drivers/video/s3c-fb.c rename to drivers/video/fbdev/s3c-fb.c diff --git a/drivers/video/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c similarity index 100% rename from drivers/video/s3c2410fb.c rename to drivers/video/fbdev/s3c2410fb.c diff --git a/drivers/video/s3c2410fb.h b/drivers/video/fbdev/s3c2410fb.h similarity index 100% rename from drivers/video/s3c2410fb.h rename to drivers/video/fbdev/s3c2410fb.h diff --git a/drivers/video/s3fb.c b/drivers/video/fbdev/s3fb.c similarity index 100% rename from drivers/video/s3fb.c rename to drivers/video/fbdev/s3fb.c diff --git a/drivers/video/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c similarity index 100% rename from drivers/video/sa1100fb.c rename to drivers/video/fbdev/sa1100fb.c diff --git a/drivers/video/sa1100fb.h b/drivers/video/fbdev/sa1100fb.h similarity index 100% rename from drivers/video/sa1100fb.h rename to drivers/video/fbdev/sa1100fb.h diff --git a/drivers/video/savage/Makefile b/drivers/video/fbdev/savage/Makefile similarity index 100% rename from drivers/video/savage/Makefile rename to drivers/video/fbdev/savage/Makefile diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/fbdev/savage/savagefb-i2c.c similarity index 100% rename from drivers/video/savage/savagefb-i2c.c rename to drivers/video/fbdev/savage/savagefb-i2c.c diff --git a/drivers/video/savage/savagefb.h b/drivers/video/fbdev/savage/savagefb.h similarity index 100% rename from drivers/video/savage/savagefb.h rename to drivers/video/fbdev/savage/savagefb.h diff --git a/drivers/video/savage/savagefb_accel.c b/drivers/video/fbdev/savage/savagefb_accel.c similarity index 100% rename from drivers/video/savage/savagefb_accel.c rename to drivers/video/fbdev/savage/savagefb_accel.c diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c similarity index 100% rename from drivers/video/savage/savagefb_driver.c rename to drivers/video/fbdev/savage/savagefb_driver.c diff --git a/drivers/video/sbuslib.c b/drivers/video/fbdev/sbuslib.c similarity index 100% rename from drivers/video/sbuslib.c rename to drivers/video/fbdev/sbuslib.c diff --git a/drivers/video/sbuslib.h b/drivers/video/fbdev/sbuslib.h similarity index 100% rename from drivers/video/sbuslib.h rename to drivers/video/fbdev/sbuslib.h diff --git a/drivers/video/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c similarity index 100% rename from drivers/video/sh7760fb.c rename to drivers/video/fbdev/sh7760fb.c diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/fbdev/sh_mipi_dsi.c similarity index 100% rename from drivers/video/sh_mipi_dsi.c rename to drivers/video/fbdev/sh_mipi_dsi.c diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/fbdev/sh_mobile_hdmi.c similarity index 100% rename from drivers/video/sh_mobile_hdmi.c rename to drivers/video/fbdev/sh_mobile_hdmi.c diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c similarity index 100% rename from drivers/video/sh_mobile_lcdcfb.c rename to drivers/video/fbdev/sh_mobile_lcdcfb.c diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/fbdev/sh_mobile_lcdcfb.h similarity index 100% rename from drivers/video/sh_mobile_lcdcfb.h rename to drivers/video/fbdev/sh_mobile_lcdcfb.h diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/fbdev/sh_mobile_meram.c similarity index 100% rename from drivers/video/sh_mobile_meram.c rename to drivers/video/fbdev/sh_mobile_meram.c diff --git a/drivers/video/simplefb.c b/drivers/video/fbdev/simplefb.c similarity index 100% rename from drivers/video/simplefb.c rename to drivers/video/fbdev/simplefb.c diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/fbdev/sis/300vtbl.h similarity index 100% rename from drivers/video/sis/300vtbl.h rename to drivers/video/fbdev/sis/300vtbl.h diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/fbdev/sis/310vtbl.h similarity index 100% rename from drivers/video/sis/310vtbl.h rename to drivers/video/fbdev/sis/310vtbl.h diff --git a/drivers/video/sis/Makefile b/drivers/video/fbdev/sis/Makefile similarity index 100% rename from drivers/video/sis/Makefile rename to drivers/video/fbdev/sis/Makefile diff --git a/drivers/video/sis/init.c b/drivers/video/fbdev/sis/init.c similarity index 100% rename from drivers/video/sis/init.c rename to drivers/video/fbdev/sis/init.c diff --git a/drivers/video/sis/init.h b/drivers/video/fbdev/sis/init.h similarity index 100% rename from drivers/video/sis/init.h rename to drivers/video/fbdev/sis/init.h diff --git a/drivers/video/sis/init301.c b/drivers/video/fbdev/sis/init301.c similarity index 100% rename from drivers/video/sis/init301.c rename to drivers/video/fbdev/sis/init301.c diff --git a/drivers/video/sis/init301.h b/drivers/video/fbdev/sis/init301.h similarity index 100% rename from drivers/video/sis/init301.h rename to drivers/video/fbdev/sis/init301.h diff --git a/drivers/video/sis/initdef.h b/drivers/video/fbdev/sis/initdef.h similarity index 100% rename from drivers/video/sis/initdef.h rename to drivers/video/fbdev/sis/initdef.h diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/fbdev/sis/initextlfb.c similarity index 100% rename from drivers/video/sis/initextlfb.c rename to drivers/video/fbdev/sis/initextlfb.c diff --git a/drivers/video/sis/oem300.h b/drivers/video/fbdev/sis/oem300.h similarity index 100% rename from drivers/video/sis/oem300.h rename to drivers/video/fbdev/sis/oem300.h diff --git a/drivers/video/sis/oem310.h b/drivers/video/fbdev/sis/oem310.h similarity index 100% rename from drivers/video/sis/oem310.h rename to drivers/video/fbdev/sis/oem310.h diff --git a/drivers/video/sis/sis.h b/drivers/video/fbdev/sis/sis.h similarity index 100% rename from drivers/video/sis/sis.h rename to drivers/video/fbdev/sis/sis.h diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/fbdev/sis/sis_accel.c similarity index 100% rename from drivers/video/sis/sis_accel.c rename to drivers/video/fbdev/sis/sis_accel.c diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/fbdev/sis/sis_accel.h similarity index 100% rename from drivers/video/sis/sis_accel.h rename to drivers/video/fbdev/sis/sis_accel.h diff --git a/drivers/video/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c similarity index 100% rename from drivers/video/sis/sis_main.c rename to drivers/video/fbdev/sis/sis_main.c diff --git a/drivers/video/sis/sis_main.h b/drivers/video/fbdev/sis/sis_main.h similarity index 100% rename from drivers/video/sis/sis_main.h rename to drivers/video/fbdev/sis/sis_main.h diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/fbdev/sis/vgatypes.h similarity index 100% rename from drivers/video/sis/vgatypes.h rename to drivers/video/fbdev/sis/vgatypes.h diff --git a/drivers/video/sis/vstruct.h b/drivers/video/fbdev/sis/vstruct.h similarity index 100% rename from drivers/video/sis/vstruct.h rename to drivers/video/fbdev/sis/vstruct.h diff --git a/drivers/video/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c similarity index 100% rename from drivers/video/skeletonfb.c rename to drivers/video/fbdev/skeletonfb.c diff --git a/drivers/video/sm501fb.c b/drivers/video/fbdev/sm501fb.c similarity index 100% rename from drivers/video/sm501fb.c rename to drivers/video/fbdev/sm501fb.c diff --git a/drivers/video/smscufx.c b/drivers/video/fbdev/smscufx.c similarity index 100% rename from drivers/video/smscufx.c rename to drivers/video/fbdev/smscufx.c diff --git a/drivers/video/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c similarity index 100% rename from drivers/video/ssd1307fb.c rename to drivers/video/fbdev/ssd1307fb.c diff --git a/drivers/video/sstfb.c b/drivers/video/fbdev/sstfb.c similarity index 100% rename from drivers/video/sstfb.c rename to drivers/video/fbdev/sstfb.c diff --git a/drivers/video/sticore.h b/drivers/video/fbdev/sticore.h similarity index 100% rename from drivers/video/sticore.h rename to drivers/video/fbdev/sticore.h diff --git a/drivers/video/stifb.c b/drivers/video/fbdev/stifb.c similarity index 100% rename from drivers/video/stifb.c rename to drivers/video/fbdev/stifb.c diff --git a/drivers/video/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c similarity index 100% rename from drivers/video/sunxvr1000.c rename to drivers/video/fbdev/sunxvr1000.c diff --git a/drivers/video/sunxvr2500.c b/drivers/video/fbdev/sunxvr2500.c similarity index 100% rename from drivers/video/sunxvr2500.c rename to drivers/video/fbdev/sunxvr2500.c diff --git a/drivers/video/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c similarity index 100% rename from drivers/video/sunxvr500.c rename to drivers/video/fbdev/sunxvr500.c diff --git a/drivers/video/svgalib.c b/drivers/video/fbdev/svgalib.c similarity index 100% rename from drivers/video/svgalib.c rename to drivers/video/fbdev/svgalib.c diff --git a/drivers/video/syscopyarea.c b/drivers/video/fbdev/syscopyarea.c similarity index 100% rename from drivers/video/syscopyarea.c rename to drivers/video/fbdev/syscopyarea.c diff --git a/drivers/video/sysfillrect.c b/drivers/video/fbdev/sysfillrect.c similarity index 100% rename from drivers/video/sysfillrect.c rename to drivers/video/fbdev/sysfillrect.c diff --git a/drivers/video/sysimgblt.c b/drivers/video/fbdev/sysimgblt.c similarity index 100% rename from drivers/video/sysimgblt.c rename to drivers/video/fbdev/sysimgblt.c diff --git a/drivers/video/tcx.c b/drivers/video/fbdev/tcx.c similarity index 100% rename from drivers/video/tcx.c rename to drivers/video/fbdev/tcx.c diff --git a/drivers/video/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c similarity index 100% rename from drivers/video/tdfxfb.c rename to drivers/video/fbdev/tdfxfb.c diff --git a/drivers/video/tgafb.c b/drivers/video/fbdev/tgafb.c similarity index 100% rename from drivers/video/tgafb.c rename to drivers/video/fbdev/tgafb.c diff --git a/drivers/video/tmiofb.c b/drivers/video/fbdev/tmiofb.c similarity index 100% rename from drivers/video/tmiofb.c rename to drivers/video/fbdev/tmiofb.c diff --git a/drivers/video/tridentfb.c b/drivers/video/fbdev/tridentfb.c similarity index 100% rename from drivers/video/tridentfb.c rename to drivers/video/fbdev/tridentfb.c diff --git a/drivers/video/udlfb.c b/drivers/video/fbdev/udlfb.c similarity index 100% rename from drivers/video/udlfb.c rename to drivers/video/fbdev/udlfb.c diff --git a/drivers/video/uvesafb.c b/drivers/video/fbdev/uvesafb.c similarity index 100% rename from drivers/video/uvesafb.c rename to drivers/video/fbdev/uvesafb.c diff --git a/drivers/video/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c similarity index 100% rename from drivers/video/valkyriefb.c rename to drivers/video/fbdev/valkyriefb.c diff --git a/drivers/video/valkyriefb.h b/drivers/video/fbdev/valkyriefb.h similarity index 100% rename from drivers/video/valkyriefb.h rename to drivers/video/fbdev/valkyriefb.h diff --git a/drivers/video/vermilion/Makefile b/drivers/video/fbdev/vermilion/Makefile similarity index 100% rename from drivers/video/vermilion/Makefile rename to drivers/video/fbdev/vermilion/Makefile diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/fbdev/vermilion/cr_pll.c similarity index 100% rename from drivers/video/vermilion/cr_pll.c rename to drivers/video/fbdev/vermilion/cr_pll.c diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c similarity index 100% rename from drivers/video/vermilion/vermilion.c rename to drivers/video/fbdev/vermilion/vermilion.c diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/fbdev/vermilion/vermilion.h similarity index 100% rename from drivers/video/vermilion/vermilion.h rename to drivers/video/fbdev/vermilion/vermilion.h diff --git a/drivers/video/vesafb.c b/drivers/video/fbdev/vesafb.c similarity index 100% rename from drivers/video/vesafb.c rename to drivers/video/fbdev/vesafb.c diff --git a/drivers/video/vfb.c b/drivers/video/fbdev/vfb.c similarity index 100% rename from drivers/video/vfb.c rename to drivers/video/fbdev/vfb.c diff --git a/drivers/video/vga16fb.c b/drivers/video/fbdev/vga16fb.c similarity index 100% rename from drivers/video/vga16fb.c rename to drivers/video/fbdev/vga16fb.c diff --git a/drivers/video/via/Makefile b/drivers/video/fbdev/via/Makefile similarity index 100% rename from drivers/video/via/Makefile rename to drivers/video/fbdev/via/Makefile diff --git a/drivers/video/via/accel.c b/drivers/video/fbdev/via/accel.c similarity index 100% rename from drivers/video/via/accel.c rename to drivers/video/fbdev/via/accel.c diff --git a/drivers/video/via/accel.h b/drivers/video/fbdev/via/accel.h similarity index 100% rename from drivers/video/via/accel.h rename to drivers/video/fbdev/via/accel.h diff --git a/drivers/video/via/chip.h b/drivers/video/fbdev/via/chip.h similarity index 100% rename from drivers/video/via/chip.h rename to drivers/video/fbdev/via/chip.h diff --git a/drivers/video/via/debug.h b/drivers/video/fbdev/via/debug.h similarity index 100% rename from drivers/video/via/debug.h rename to drivers/video/fbdev/via/debug.h diff --git a/drivers/video/via/dvi.c b/drivers/video/fbdev/via/dvi.c similarity index 100% rename from drivers/video/via/dvi.c rename to drivers/video/fbdev/via/dvi.c diff --git a/drivers/video/via/dvi.h b/drivers/video/fbdev/via/dvi.h similarity index 100% rename from drivers/video/via/dvi.h rename to drivers/video/fbdev/via/dvi.h diff --git a/drivers/video/via/global.c b/drivers/video/fbdev/via/global.c similarity index 100% rename from drivers/video/via/global.c rename to drivers/video/fbdev/via/global.c diff --git a/drivers/video/via/global.h b/drivers/video/fbdev/via/global.h similarity index 100% rename from drivers/video/via/global.h rename to drivers/video/fbdev/via/global.h diff --git a/drivers/video/via/hw.c b/drivers/video/fbdev/via/hw.c similarity index 100% rename from drivers/video/via/hw.c rename to drivers/video/fbdev/via/hw.c diff --git a/drivers/video/via/hw.h b/drivers/video/fbdev/via/hw.h similarity index 100% rename from drivers/video/via/hw.h rename to drivers/video/fbdev/via/hw.h diff --git a/drivers/video/via/ioctl.c b/drivers/video/fbdev/via/ioctl.c similarity index 100% rename from drivers/video/via/ioctl.c rename to drivers/video/fbdev/via/ioctl.c diff --git a/drivers/video/via/ioctl.h b/drivers/video/fbdev/via/ioctl.h similarity index 100% rename from drivers/video/via/ioctl.h rename to drivers/video/fbdev/via/ioctl.h diff --git a/drivers/video/via/lcd.c b/drivers/video/fbdev/via/lcd.c similarity index 100% rename from drivers/video/via/lcd.c rename to drivers/video/fbdev/via/lcd.c diff --git a/drivers/video/via/lcd.h b/drivers/video/fbdev/via/lcd.h similarity index 100% rename from drivers/video/via/lcd.h rename to drivers/video/fbdev/via/lcd.h diff --git a/drivers/video/via/share.h b/drivers/video/fbdev/via/share.h similarity index 100% rename from drivers/video/via/share.h rename to drivers/video/fbdev/via/share.h diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/fbdev/via/tblDPASetting.c similarity index 100% rename from drivers/video/via/tblDPASetting.c rename to drivers/video/fbdev/via/tblDPASetting.c diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/fbdev/via/tblDPASetting.h similarity index 100% rename from drivers/video/via/tblDPASetting.h rename to drivers/video/fbdev/via/tblDPASetting.h diff --git a/drivers/video/via/via-core.c b/drivers/video/fbdev/via/via-core.c similarity index 100% rename from drivers/video/via/via-core.c rename to drivers/video/fbdev/via/via-core.c diff --git a/drivers/video/via/via-gpio.c b/drivers/video/fbdev/via/via-gpio.c similarity index 100% rename from drivers/video/via/via-gpio.c rename to drivers/video/fbdev/via/via-gpio.c diff --git a/drivers/video/via/via_aux.c b/drivers/video/fbdev/via/via_aux.c similarity index 100% rename from drivers/video/via/via_aux.c rename to drivers/video/fbdev/via/via_aux.c diff --git a/drivers/video/via/via_aux.h b/drivers/video/fbdev/via/via_aux.h similarity index 100% rename from drivers/video/via/via_aux.h rename to drivers/video/fbdev/via/via_aux.h diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/fbdev/via/via_aux_ch7301.c similarity index 100% rename from drivers/video/via/via_aux_ch7301.c rename to drivers/video/fbdev/via/via_aux_ch7301.c diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/fbdev/via/via_aux_edid.c similarity index 100% rename from drivers/video/via/via_aux_edid.c rename to drivers/video/fbdev/via/via_aux_edid.c diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/fbdev/via/via_aux_sii164.c similarity index 100% rename from drivers/video/via/via_aux_sii164.c rename to drivers/video/fbdev/via/via_aux_sii164.c diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/fbdev/via/via_aux_vt1621.c similarity index 100% rename from drivers/video/via/via_aux_vt1621.c rename to drivers/video/fbdev/via/via_aux_vt1621.c diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/fbdev/via/via_aux_vt1622.c similarity index 100% rename from drivers/video/via/via_aux_vt1622.c rename to drivers/video/fbdev/via/via_aux_vt1622.c diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/fbdev/via/via_aux_vt1625.c similarity index 100% rename from drivers/video/via/via_aux_vt1625.c rename to drivers/video/fbdev/via/via_aux_vt1625.c diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/fbdev/via/via_aux_vt1631.c similarity index 100% rename from drivers/video/via/via_aux_vt1631.c rename to drivers/video/fbdev/via/via_aux_vt1631.c diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/fbdev/via/via_aux_vt1632.c similarity index 100% rename from drivers/video/via/via_aux_vt1632.c rename to drivers/video/fbdev/via/via_aux_vt1632.c diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/fbdev/via/via_aux_vt1636.c similarity index 100% rename from drivers/video/via/via_aux_vt1636.c rename to drivers/video/fbdev/via/via_aux_vt1636.c diff --git a/drivers/video/via/via_clock.c b/drivers/video/fbdev/via/via_clock.c similarity index 100% rename from drivers/video/via/via_clock.c rename to drivers/video/fbdev/via/via_clock.c diff --git a/drivers/video/via/via_clock.h b/drivers/video/fbdev/via/via_clock.h similarity index 100% rename from drivers/video/via/via_clock.h rename to drivers/video/fbdev/via/via_clock.h diff --git a/drivers/video/via/via_i2c.c b/drivers/video/fbdev/via/via_i2c.c similarity index 100% rename from drivers/video/via/via_i2c.c rename to drivers/video/fbdev/via/via_i2c.c diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/fbdev/via/via_modesetting.c similarity index 100% rename from drivers/video/via/via_modesetting.c rename to drivers/video/fbdev/via/via_modesetting.c diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/fbdev/via/via_modesetting.h similarity index 100% rename from drivers/video/via/via_modesetting.h rename to drivers/video/fbdev/via/via_modesetting.h diff --git a/drivers/video/via/via_utility.c b/drivers/video/fbdev/via/via_utility.c similarity index 100% rename from drivers/video/via/via_utility.c rename to drivers/video/fbdev/via/via_utility.c diff --git a/drivers/video/via/via_utility.h b/drivers/video/fbdev/via/via_utility.h similarity index 100% rename from drivers/video/via/via_utility.h rename to drivers/video/fbdev/via/via_utility.h diff --git a/drivers/video/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c similarity index 100% rename from drivers/video/via/viafbdev.c rename to drivers/video/fbdev/via/viafbdev.c diff --git a/drivers/video/via/viafbdev.h b/drivers/video/fbdev/via/viafbdev.h similarity index 100% rename from drivers/video/via/viafbdev.h rename to drivers/video/fbdev/via/viafbdev.h diff --git a/drivers/video/via/viamode.c b/drivers/video/fbdev/via/viamode.c similarity index 100% rename from drivers/video/via/viamode.c rename to drivers/video/fbdev/via/viamode.c diff --git a/drivers/video/via/viamode.h b/drivers/video/fbdev/via/viamode.h similarity index 100% rename from drivers/video/via/viamode.h rename to drivers/video/fbdev/via/viamode.h diff --git a/drivers/video/via/vt1636.c b/drivers/video/fbdev/via/vt1636.c similarity index 100% rename from drivers/video/via/vt1636.c rename to drivers/video/fbdev/via/vt1636.c diff --git a/drivers/video/via/vt1636.h b/drivers/video/fbdev/via/vt1636.h similarity index 100% rename from drivers/video/via/vt1636.h rename to drivers/video/fbdev/via/vt1636.h diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c similarity index 100% rename from drivers/video/vt8500lcdfb.c rename to drivers/video/fbdev/vt8500lcdfb.c diff --git a/drivers/video/vt8500lcdfb.h b/drivers/video/fbdev/vt8500lcdfb.h similarity index 100% rename from drivers/video/vt8500lcdfb.h rename to drivers/video/fbdev/vt8500lcdfb.h diff --git a/drivers/video/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c similarity index 100% rename from drivers/video/vt8623fb.c rename to drivers/video/fbdev/vt8623fb.c diff --git a/drivers/video/w100fb.c b/drivers/video/fbdev/w100fb.c similarity index 100% rename from drivers/video/w100fb.c rename to drivers/video/fbdev/w100fb.c diff --git a/drivers/video/w100fb.h b/drivers/video/fbdev/w100fb.h similarity index 100% rename from drivers/video/w100fb.h rename to drivers/video/fbdev/w100fb.h diff --git a/drivers/video/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c similarity index 100% rename from drivers/video/wm8505fb.c rename to drivers/video/fbdev/wm8505fb.c diff --git a/drivers/video/wm8505fb_regs.h b/drivers/video/fbdev/wm8505fb_regs.h similarity index 100% rename from drivers/video/wm8505fb_regs.h rename to drivers/video/fbdev/wm8505fb_regs.h diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c similarity index 100% rename from drivers/video/wmt_ge_rops.c rename to drivers/video/fbdev/wmt_ge_rops.c diff --git a/drivers/video/wmt_ge_rops.h b/drivers/video/fbdev/wmt_ge_rops.h similarity index 100% rename from drivers/video/wmt_ge_rops.h rename to drivers/video/fbdev/wmt_ge_rops.h diff --git a/drivers/video/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c similarity index 100% rename from drivers/video/xen-fbfront.c rename to drivers/video/fbdev/xen-fbfront.c diff --git a/drivers/video/xilinxfb.c b/drivers/video/fbdev/xilinxfb.c similarity index 100% rename from drivers/video/xilinxfb.c rename to drivers/video/fbdev/xilinxfb.c diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig deleted file mode 100644 index 63b23f87081d..000000000000 --- a/drivers/video/omap2/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config OMAP2_VRFB - bool - -if ARCH_OMAP2PLUS - -source "drivers/video/omap2/dss/Kconfig" -source "drivers/video/omap2/omapfb/Kconfig" -source "drivers/video/omap2/displays-new/Kconfig" - -endif -- GitLab From 19757fc8432ac97a07a890d6310cccc1896a1b36 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Feb 2014 16:24:55 +0200 Subject: [PATCH 434/797] fbdev: move fbdev core files to separate directory Instead of having fbdev framework core files at the root fbdev directory, mixed with random fbdev device drivers, move the fbdev core files to a separate core directory. This makes it much clearer which of the files are actually part of the fbdev framework, and which are part of device drivers. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart Acked-by: Geert Uytterhoeven Acked-by: Rob Clark Acked-by: Jingoo Han Acked-by: Daniel Vetter --- Documentation/DocBook/device-drivers.tmpl | 8 ++++---- drivers/video/fbdev/Makefile | 16 +--------------- drivers/video/fbdev/aty/mach64_cursor.c | 2 +- drivers/video/fbdev/core/Makefile | 16 ++++++++++++++++ drivers/video/fbdev/{ => core}/cfbcopyarea.c | 0 drivers/video/fbdev/{ => core}/cfbfillrect.c | 0 drivers/video/fbdev/{ => core}/cfbimgblt.c | 0 drivers/video/fbdev/{ => core}/fb_ddc.c | 2 +- drivers/video/fbdev/{ => core}/fb_defio.c | 0 drivers/video/fbdev/{ => core}/fb_draw.h | 0 drivers/video/fbdev/{ => core}/fb_notify.c | 0 drivers/video/fbdev/{ => core}/fb_sys_fops.c | 0 drivers/video/fbdev/{ => core}/fbcmap.c | 0 drivers/video/fbdev/{ => core}/fbcvt.c | 0 drivers/video/fbdev/{ => core}/fbmem.c | 0 drivers/video/fbdev/{ => core}/fbmon.c | 2 +- drivers/video/fbdev/{ => core}/fbsysfs.c | 0 drivers/video/fbdev/{ => core}/modedb.c | 0 drivers/video/fbdev/{ => core}/svgalib.c | 0 drivers/video/fbdev/{ => core}/syscopyarea.c | 0 drivers/video/fbdev/{ => core}/sysfillrect.c | 0 drivers/video/fbdev/{ => core}/sysimgblt.c | 0 drivers/video/fbdev/wmt_ge_rops.c | 2 +- 23 files changed, 25 insertions(+), 23 deletions(-) create mode 100644 drivers/video/fbdev/core/Makefile rename drivers/video/fbdev/{ => core}/cfbcopyarea.c (100%) rename drivers/video/fbdev/{ => core}/cfbfillrect.c (100%) rename drivers/video/fbdev/{ => core}/cfbimgblt.c (100%) rename drivers/video/fbdev/{ => core}/fb_ddc.c (99%) rename drivers/video/fbdev/{ => core}/fb_defio.c (100%) rename drivers/video/fbdev/{ => core}/fb_draw.h (100%) rename drivers/video/fbdev/{ => core}/fb_notify.c (100%) rename drivers/video/fbdev/{ => core}/fb_sys_fops.c (100%) rename drivers/video/fbdev/{ => core}/fbcmap.c (100%) rename drivers/video/fbdev/{ => core}/fbcvt.c (100%) rename drivers/video/fbdev/{ => core}/fbmem.c (100%) rename drivers/video/fbdev/{ => core}/fbmon.c (99%) rename drivers/video/fbdev/{ => core}/fbsysfs.c (100%) rename drivers/video/fbdev/{ => core}/modedb.c (100%) rename drivers/video/fbdev/{ => core}/svgalib.c (100%) rename drivers/video/fbdev/{ => core}/syscopyarea.c (100%) rename drivers/video/fbdev/{ => core}/sysfillrect.c (100%) rename drivers/video/fbdev/{ => core}/sysimgblt.c (100%) diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl index 4d1aa8b44be7..cc63f30de166 100644 --- a/Documentation/DocBook/device-drivers.tmpl +++ b/Documentation/DocBook/device-drivers.tmpl @@ -276,7 +276,7 @@ X!Isound/sound_firmware.c Frame Buffer Memory -!Edrivers/video/fbdev/fbmem.c +!Edrivers/video/fbdev/core/fbmem.c Frame Buffer Colormap -!Edrivers/video/fbdev/fbcmap.c +!Edrivers/video/fbdev/core/fbcmap.c Frame Buffer Video Mode Database -!Idrivers/video/fbdev/modedb.c -!Edrivers/video/fbdev/modedb.c +!Idrivers/video/fbdev/core/modedb.c +!Edrivers/video/fbdev/core/modedb.c Frame Buffer Macintosh Video Mode Database !Edrivers/video/fbdev/macmodes.c diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index 8a79eec2113b..0284f2a12538 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -4,25 +4,11 @@ # Each configuration option enables a list of files. -obj-y += fb_notify.o -obj-$(CONFIG_FB) += fb.o -fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ - modedb.o fbcvt.o -fb-objs := $(fb-y) +obj-y += core/ obj-$(CONFIG_EXYNOS_VIDEO) += exynos/ -obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o -obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o -obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o -obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o -obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o -obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o -obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o -obj-$(CONFIG_FB_SVGALIB) += svgalib.o obj-$(CONFIG_FB_MACMODES) += macmodes.o -obj-$(CONFIG_FB_DDC) += fb_ddc.o -obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o # Hardware specific drivers go first diff --git a/drivers/video/fbdev/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c index 0fe02e22d9a4..2fa0317ab3c7 100644 --- a/drivers/video/fbdev/aty/mach64_cursor.c +++ b/drivers/video/fbdev/aty/mach64_cursor.c @@ -5,7 +5,7 @@ #include #include #include -#include "../fb_draw.h" +#include "../core/fb_draw.h" #include diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile new file mode 100644 index 000000000000..fa306538dac2 --- /dev/null +++ b/drivers/video/fbdev/core/Makefile @@ -0,0 +1,16 @@ +obj-y += fb_notify.o +obj-$(CONFIG_FB) += fb.o +fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ + modedb.o fbcvt.o +fb-objs := $(fb-y) + +obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o +obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o +obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o +obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o +obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o +obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o +obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o +obj-$(CONFIG_FB_SVGALIB) += svgalib.o +obj-$(CONFIG_FB_DDC) += fb_ddc.o +obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o diff --git a/drivers/video/fbdev/cfbcopyarea.c b/drivers/video/fbdev/core/cfbcopyarea.c similarity index 100% rename from drivers/video/fbdev/cfbcopyarea.c rename to drivers/video/fbdev/core/cfbcopyarea.c diff --git a/drivers/video/fbdev/cfbfillrect.c b/drivers/video/fbdev/core/cfbfillrect.c similarity index 100% rename from drivers/video/fbdev/cfbfillrect.c rename to drivers/video/fbdev/core/cfbfillrect.c diff --git a/drivers/video/fbdev/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c similarity index 100% rename from drivers/video/fbdev/cfbimgblt.c rename to drivers/video/fbdev/core/cfbimgblt.c diff --git a/drivers/video/fbdev/fb_ddc.c b/drivers/video/fbdev/core/fb_ddc.c similarity index 99% rename from drivers/video/fbdev/fb_ddc.c rename to drivers/video/fbdev/core/fb_ddc.c index 2b106f046fde..94322ccfedde 100644 --- a/drivers/video/fbdev/fb_ddc.c +++ b/drivers/video/fbdev/core/fb_ddc.c @@ -15,7 +15,7 @@ #include #include -#include "edid.h" +#include "../edid.h" #define DDC_ADDR 0x50 diff --git a/drivers/video/fbdev/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c similarity index 100% rename from drivers/video/fbdev/fb_defio.c rename to drivers/video/fbdev/core/fb_defio.c diff --git a/drivers/video/fbdev/fb_draw.h b/drivers/video/fbdev/core/fb_draw.h similarity index 100% rename from drivers/video/fbdev/fb_draw.h rename to drivers/video/fbdev/core/fb_draw.h diff --git a/drivers/video/fbdev/fb_notify.c b/drivers/video/fbdev/core/fb_notify.c similarity index 100% rename from drivers/video/fbdev/fb_notify.c rename to drivers/video/fbdev/core/fb_notify.c diff --git a/drivers/video/fbdev/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c similarity index 100% rename from drivers/video/fbdev/fb_sys_fops.c rename to drivers/video/fbdev/core/fb_sys_fops.c diff --git a/drivers/video/fbdev/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c similarity index 100% rename from drivers/video/fbdev/fbcmap.c rename to drivers/video/fbdev/core/fbcmap.c diff --git a/drivers/video/fbdev/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c similarity index 100% rename from drivers/video/fbdev/fbcvt.c rename to drivers/video/fbdev/core/fbcvt.c diff --git a/drivers/video/fbdev/fbmem.c b/drivers/video/fbdev/core/fbmem.c similarity index 100% rename from drivers/video/fbdev/fbmem.c rename to drivers/video/fbdev/core/fbmem.c diff --git a/drivers/video/fbdev/fbmon.c b/drivers/video/fbdev/core/fbmon.c similarity index 99% rename from drivers/video/fbdev/fbmon.c rename to drivers/video/fbdev/core/fbmon.c index 6103fa6fb54f..c204ebe6187e 100644 --- a/drivers/video/fbdev/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -37,7 +37,7 @@ #include #include #endif -#include "edid.h" +#include "../edid.h" /* * EDID parser diff --git a/drivers/video/fbdev/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c similarity index 100% rename from drivers/video/fbdev/fbsysfs.c rename to drivers/video/fbdev/core/fbsysfs.c diff --git a/drivers/video/fbdev/modedb.c b/drivers/video/fbdev/core/modedb.c similarity index 100% rename from drivers/video/fbdev/modedb.c rename to drivers/video/fbdev/core/modedb.c diff --git a/drivers/video/fbdev/svgalib.c b/drivers/video/fbdev/core/svgalib.c similarity index 100% rename from drivers/video/fbdev/svgalib.c rename to drivers/video/fbdev/core/svgalib.c diff --git a/drivers/video/fbdev/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c similarity index 100% rename from drivers/video/fbdev/syscopyarea.c rename to drivers/video/fbdev/core/syscopyarea.c diff --git a/drivers/video/fbdev/sysfillrect.c b/drivers/video/fbdev/core/sysfillrect.c similarity index 100% rename from drivers/video/fbdev/sysfillrect.c rename to drivers/video/fbdev/core/sysfillrect.c diff --git a/drivers/video/fbdev/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c similarity index 100% rename from drivers/video/fbdev/sysimgblt.c rename to drivers/video/fbdev/core/sysimgblt.c diff --git a/drivers/video/fbdev/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c index b0a9f34b2e01..9df6fe78a44b 100644 --- a/drivers/video/fbdev/wmt_ge_rops.c +++ b/drivers/video/fbdev/wmt_ge_rops.c @@ -18,7 +18,7 @@ #include #include #include -#include "fb_draw.h" +#include "core/fb_draw.h" #define GE_COMMAND_OFF 0x00 #define GE_DEPTH_OFF 0x04 -- GitLab From 776bbb97e0a37fe67bd0870e5aa4845af856b872 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 13 Feb 2014 16:32:13 +0200 Subject: [PATCH 435/797] video: Kconfig: move drm and fb into separate menus At the moment the "Device Drivers / Graphics support" kernel config page looks rather messy, with DRM and fbdev driver selections on the same page, some on the top level Graphics support page, some under their respective subsystems. If I'm not mistaken, this is caused by the drivers depending on other things than DRM or FB, which causes Kconfig to arrange the options in not-so-neat manner. Both DRM and FB have a main menuconfig option for the whole DRM or FB subsystem. Optimally, this would be enough to arrange all DRM and FB options under the respective subsystem, but for whatever reason this doesn't work reliably. This patch adds an explicit submenu for DRM and FB, making it much clearer which options are related to FB, and which to DRM. Signed-off-by: Tomi Valkeinen Acked-by: Laurent Pinchart Acked-by: Geert Uytterhoeven Acked-by: Rob Clark Reviewed-by: Jingoo Han Acked-by: Daniel Vetter --- drivers/video/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index ab05d6cb0796..c7b4f0f927b1 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -21,9 +21,13 @@ source "drivers/gpu/vga/Kconfig" source "drivers/gpu/host1x/Kconfig" +menu "Direct Rendering Manager" source "drivers/gpu/drm/Kconfig" +endmenu +menu "Frame buffer Devices" source "drivers/video/fbdev/Kconfig" +endmenu source "drivers/video/backlight/Kconfig" -- GitLab From c7a6d35e463caacab08ca0333bdec5b8bdce8bbb Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 15 Apr 2014 09:12:54 +0800 Subject: [PATCH 436/797] raid5: fix a race of stripe count check I hit another BUG_ON with e240c1839d11152b0355442. In __get_priority_stripe(), stripe count equals to 0 initially. Between atomic_inc and BUG_ON, get_active_stripe() finds the stripe. So the stripe count isn't 1 any more. V2: keeps the BUG_ON suggested by Neil. Signed-off-by: Shaohua Li Signed-off-by: NeilBrown --- drivers/md/raid5.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 25247a852912..ad1b9bea446e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -4370,8 +4370,7 @@ static struct stripe_head *__get_priority_stripe(struct r5conf *conf, int group) sh->group = NULL; } list_del_init(&sh->lru); - atomic_inc(&sh->count); - BUG_ON(atomic_read(&sh->count) != 1); + BUG_ON(atomic_inc_return(&sh->count) != 1); return sh; } -- GitLab From ea431643d6c38728195e2c456801c3ef66bb9991 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 17 Apr 2014 10:25:53 +0200 Subject: [PATCH 437/797] x86/mce: Fix CMCI preemption bugs The following commit: 27f6c573e0f7 ("x86, CMCI: Add proper detection of end of CMCI storms") Added two preemption bugs: - machine_check_poll() does a get_cpu_var() without a matching put_cpu_var(), which causes preemption imbalance and crashes upon bootup. - it does percpu ops without disabling preemption. Preemption is not disabled due to the mistaken use of a raw spinlock. To fix these bugs fix the imbalance and change cmci_discover_lock to a regular spinlock. Reported-by: Owen Kibel Reported-by: Linus Torvalds Signed-off-by: Ingo Molnar Cc: Chen, Gong Cc: Josh Boyer Cc: Tony Luck Cc: Peter Zijlstra Cc: Alexander Todorov Cc: Borislav Petkov Link: http://lkml.kernel.org/n/tip-jtjptvgigpfkpvtQxpEk1at2@git.kernel.org Signed-off-by: Ingo Molnar -- arch/x86/kernel/cpu/mcheck/mce.c | 4 +--- arch/x86/kernel/cpu/mcheck/mce_intel.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) --- arch/x86/kernel/cpu/mcheck/mce.c | 4 +--- arch/x86/kernel/cpu/mcheck/mce_intel.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index eeee23ff75ef..68317c80de7f 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -598,7 +598,6 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) { struct mce m; int i; - unsigned long *v; this_cpu_inc(mce_poll_count); @@ -618,8 +617,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b) if (!(m.status & MCI_STATUS_VAL)) continue; - v = &get_cpu_var(mce_polled_error); - set_bit(0, v); + this_cpu_write(mce_polled_error, 1); /* * Uncorrected or signalled events are handled by the exception * handler when it is enabled, so don't process those here. diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c index 3bdb95ae8c43..9a316b21df8b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce_intel.c +++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c @@ -42,7 +42,7 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned); * cmci_discover_lock protects against parallel discovery attempts * which could race against each other. */ -static DEFINE_RAW_SPINLOCK(cmci_discover_lock); +static DEFINE_SPINLOCK(cmci_discover_lock); #define CMCI_THRESHOLD 1 #define CMCI_POLL_INTERVAL (30 * HZ) @@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void) int bank; u64 val; - raw_spin_lock_irqsave(&cmci_discover_lock, flags); + spin_lock_irqsave(&cmci_discover_lock, flags); owned = __get_cpu_var(mce_banks_owned); for_each_set_bit(bank, owned, MAX_NR_BANKS) { rdmsrl(MSR_IA32_MCx_CTL2(bank), val); val &= ~MCI_CTL2_CMCI_EN; wrmsrl(MSR_IA32_MCx_CTL2(bank), val); } - raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); + spin_unlock_irqrestore(&cmci_discover_lock, flags); } static bool cmci_storm_detect(void) @@ -211,7 +211,7 @@ static void cmci_discover(int banks) int i; int bios_wrong_thresh = 0; - raw_spin_lock_irqsave(&cmci_discover_lock, flags); + spin_lock_irqsave(&cmci_discover_lock, flags); for (i = 0; i < banks; i++) { u64 val; int bios_zero_thresh = 0; @@ -266,7 +266,7 @@ static void cmci_discover(int banks) WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks))); } } - raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); + spin_unlock_irqrestore(&cmci_discover_lock, flags); if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) { pr_info_once( "bios_cmci_threshold: Some banks do not have valid thresholds set\n"); @@ -316,10 +316,10 @@ void cmci_clear(void) if (!cmci_supported(&banks)) return; - raw_spin_lock_irqsave(&cmci_discover_lock, flags); + spin_lock_irqsave(&cmci_discover_lock, flags); for (i = 0; i < banks; i++) __cmci_disable_bank(i); - raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); + spin_unlock_irqrestore(&cmci_discover_lock, flags); } static void cmci_rediscover_work_func(void *arg) @@ -360,9 +360,9 @@ void cmci_disable_bank(int bank) if (!cmci_supported(&banks)) return; - raw_spin_lock_irqsave(&cmci_discover_lock, flags); + spin_lock_irqsave(&cmci_discover_lock, flags); __cmci_disable_bank(bank); - raw_spin_unlock_irqrestore(&cmci_discover_lock, flags); + spin_unlock_irqrestore(&cmci_discover_lock, flags); } static void intel_init_cmci(void) -- GitLab From 6381c24cd6d5d6373620426ab0a96c80ed953e20 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 17 Apr 2014 17:16:44 +0900 Subject: [PATCH 438/797] kprobes/x86: Fix page-fault handling logic Current kprobes in-kernel page fault handler doesn't expect that its single-stepping can be interrupted by an NMI handler which may cause a page fault(e.g. perf with callback tracing). In that case, the page-fault handled by kprobes and it misunderstands the page-fault has been caused by the single-stepping code and tries to recover IP address to probed address. But the truth is the page-fault has been caused by the NMI handler, and do_page_fault failes to handle real page fault because the IP address is modified and causes Kernel BUGs like below. ---- [ 2264.726905] BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 [ 2264.727190] IP: [] copy_user_generic_string+0x0/0x40 To handle this correctly, I fixed the kprobes fault handler to ensure the faulted ip address is its own single-step buffer instead of checking current kprobe state. Signed-off-by: Masami Hiramatsu Cc: Andi Kleen Cc: Ananth N Mavinakayanahalli Cc: Sandeepa Prabhu Cc: Frederic Weisbecker Cc: Steven Rostedt Cc: fche@redhat.com Cc: systemtap@sourceware.org Link: http://lkml.kernel.org/r/20140417081644.26341.52351.stgit@ltc230.yrl.intra.hitachi.co.jp Signed-off-by: Ingo Molnar --- arch/x86/kernel/kprobes/core.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 79a3f9682871..61b17dc2c277 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -897,9 +897,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); - switch (kcb->kprobe_status) { - case KPROBE_HIT_SS: - case KPROBE_REENTER: + if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) { + /* This must happen on single-stepping */ + WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS && + kcb->kprobe_status != KPROBE_REENTER); /* * We are here because the instruction being single * stepped caused a page fault. We reset the current @@ -914,9 +915,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) else reset_current_kprobe(); preempt_enable_no_resched(); - break; - case KPROBE_HIT_ACTIVE: - case KPROBE_HIT_SSDONE: + } else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE || + kcb->kprobe_status == KPROBE_HIT_SSDONE) { /* * We increment the nmissed count for accounting, * we can also use npre/npostfault count for accounting @@ -945,10 +945,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) * fixup routine could not handle it, * Let do_page_fault() fix it. */ - break; - default: - break; } + return 0; } -- GitLab From 06cd7a874ec6e09d151aeb1fa8600e14f1ff89f6 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 15 Apr 2014 20:08:01 +0200 Subject: [PATCH 439/797] s390/chsc: fix SEI usage on old FW levels Using a notification type mask for the store event information chsc is unsupported on some firmware levels. Retry SEI with that mask set to zero (which is the old way of requesting only channel subsystem related events). Cc: Reported-and-tested-by: Stefan Haberland Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/chsc.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 9f0ea6cb6922..e3bf885f4a6c 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -541,18 +541,27 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm) { - do { + static int ntsm_unsupported; + + while (true) { memset(sei, 0, sizeof(*sei)); sei->request.length = 0x0010; sei->request.code = 0x000e; - sei->ntsm = ntsm; + if (!ntsm_unsupported) + sei->ntsm = ntsm; if (chsc(sei)) break; if (sei->response.code != 0x0001) { - CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", - sei->response.code); + CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x, ntsm=%llx)\n", + sei->response.code, sei->ntsm); + + if (sei->response.code == 3 && sei->ntsm) { + /* Fallback for old firmware. */ + ntsm_unsupported = 1; + continue; + } break; } @@ -568,7 +577,10 @@ static void chsc_process_event_information(struct chsc_sei *sei, u64 ntsm) CIO_CRW_EVENT(2, "chsc: unhandled nt: %d\n", sei->nt); break; } - } while (sei->u.nt0_area.flags & 0x80); + + if (!(sei->u.nt0_area.flags & 0x80)) + break; + } } /* -- GitLab From a1d9a3231eac4117cadaf4b6bba5b2902c15a33e Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Thu, 10 Apr 2014 17:38:36 +0400 Subject: [PATCH 440/797] sched: Check for stop task appearance when balancing happens We need to do it like we do for the other higher priority classes.. Signed-off-by: Kirill Tkhai Cc: Michael wang Cc: Sasha Levin Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/336561397137116@web27h.yandex.ru Signed-off-by: Ingo Molnar --- kernel/sched/deadline.c | 11 ++++++++++- kernel/sched/fair.c | 3 ++- kernel/sched/rt.c | 7 ++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 27ef40925525..b08095786cb8 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -1021,8 +1021,17 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev) dl_rq = &rq->dl; - if (need_pull_dl_task(rq, prev)) + if (need_pull_dl_task(rq, prev)) { pull_dl_task(rq); + /* + * pull_rt_task() can drop (and re-acquire) rq->lock; this + * means a stop task can slip in, in which case we need to + * re-start task selection. + */ + if (rq->stop && rq->stop->on_rq) + return RETRY_TASK; + } + /* * When prev is DL, we may throttle it in put_prev_task(). * So, we update time before we check for dl_nr_running. diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 4f14a656a720..7570dd969c28 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6728,7 +6728,8 @@ static int idle_balance(struct rq *this_rq) out: /* Is there a task of a high priority class? */ if (this_rq->nr_running != this_rq->cfs.h_nr_running && - (this_rq->dl.dl_nr_running || + ((this_rq->stop && this_rq->stop->on_rq) || + this_rq->dl.dl_nr_running || (this_rq->rt.rt_nr_running && !rt_rq_throttled(&this_rq->rt)))) pulled_task = -1; diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index d8cdf1618551..bd2267ad404f 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1362,10 +1362,11 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev) pull_rt_task(rq); /* * pull_rt_task() can drop (and re-acquire) rq->lock; this - * means a dl task can slip in, in which case we need to - * re-start task selection. + * means a dl or stop task can slip in, in which case we need + * to re-start task selection. */ - if (unlikely(rq->dl.dl_nr_running)) + if (unlikely((rq->stop && rq->stop->on_rq) || + rq->dl.dl_nr_running)) return RETRY_TASK; } -- GitLab From 57700ad1f2f21d5d7ab7ee0e58d11b5954852434 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 10 Apr 2014 22:29:03 -0400 Subject: [PATCH 441/797] drm/radeon: disable mclk dpm on R7 260X Setting higher mclks seems to cause stability issues on some R7 260X boards. Disable it for now for stability until we find a proper fix. bug: https://bugs.freedesktop.org/show_bug.cgi?id=75992 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ci_dpm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index cad89a977527..6d395ec25c13 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -5146,6 +5146,10 @@ int ci_dpm_init(struct radeon_device *rdev) pi->mclk_dpm_key_disabled = 0; pi->pcie_dpm_key_disabled = 0; + /* mclk dpm is unstable on some R7 260X cards */ + if (rdev->pdev->device == 0x6658) + pi->mclk_dpm_key_disabled = 1; + pi->caps_sclk_ds = true; pi->mclk_strobe_mode_threshold = 40000; -- GitLab From 90c4cde9d5a2bb6239cb3e253bb3832ed89dc75c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 10 Apr 2014 22:29:01 -0400 Subject: [PATCH 442/797] drm/radeon: fix runpm handling on APUs (v4) Don't try and runtime suspend the APU in PX systems. We only want to power down the dGPU. v2: fix harder v3: fix stupid typo v4: consolidate runpm enablement to a single flag bugs: https://bugs.freedesktop.org/show_bug.cgi?id=75127 https://bugzilla.kernel.org/show_bug.cgi?id=72701 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_atpx_handler.c | 2 +- drivers/gpu/drm/radeon/radeon_device.c | 19 ++++++++-------- drivers/gpu/drm/radeon/radeon_drv.c | 24 ++++---------------- drivers/gpu/drm/radeon/radeon_family.h | 1 + drivers/gpu/drm/radeon/radeon_kms.c | 14 ++++++++---- 6 files changed, 27 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f21db7a0b34d..7014bdd688ce 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2321,6 +2321,7 @@ struct radeon_device { bool have_disp_power_ref; }; +bool radeon_is_px(struct drm_device *dev); int radeon_device_init(struct radeon_device *rdev, struct drm_device *ddev, struct pci_dev *pdev, diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index fa9a9c02751e..dedea72f48c4 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -59,7 +59,7 @@ struct atpx_mux { u16 mux; } __packed; -bool radeon_is_px(void) { +bool radeon_has_atpx(void) { return radeon_atpx_priv.atpx_detected; } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 835516d2d257..511fe26198e4 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -102,11 +102,14 @@ static const char radeon_family_name[][16] = { "LAST", }; -#if defined(CONFIG_VGA_SWITCHEROO) -bool radeon_is_px(void); -#else -static inline bool radeon_is_px(void) { return false; } -#endif +bool radeon_is_px(struct drm_device *dev) +{ + struct radeon_device *rdev = dev->dev_private; + + if (rdev->flags & RADEON_IS_PX) + return true; + return false; +} /** * radeon_program_register_sequence - program an array of registers. @@ -1082,7 +1085,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero { struct drm_device *dev = pci_get_drvdata(pdev); - if (radeon_is_px() && state == VGA_SWITCHEROO_OFF) + if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF) return; if (state == VGA_SWITCHEROO_ON) { @@ -1301,9 +1304,7 @@ int radeon_device_init(struct radeon_device *rdev, * ignore it */ vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); - if (radeon_runtime_pm == 1) - runtime = true; - if ((radeon_runtime_pm == -1) && radeon_is_px()) + if (rdev->flags & RADEON_IS_PX) runtime = true; vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime); if (runtime) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index d0eba48dd74e..25127ba44ed9 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -115,6 +115,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, ktime_t *etime); +extern bool radeon_is_px(struct drm_device *dev); extern const struct drm_ioctl_desc radeon_ioctls_kms[]; extern int radeon_max_kms_ioctl; int radeon_mmap(struct file *filp, struct vm_area_struct *vma); @@ -144,11 +145,9 @@ void radeon_debugfs_cleanup(struct drm_minor *minor); #if defined(CONFIG_VGA_SWITCHEROO) void radeon_register_atpx_handler(void); void radeon_unregister_atpx_handler(void); -bool radeon_is_px(void); #else static inline void radeon_register_atpx_handler(void) {} static inline void radeon_unregister_atpx_handler(void) {} -static inline bool radeon_is_px(void) { return false; } #endif int radeon_no_wb; @@ -405,12 +404,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; - if (radeon_runtime_pm == 0) { - pm_runtime_forbid(dev); - return -EBUSY; - } - - if (radeon_runtime_pm == -1 && !radeon_is_px()) { + if (!radeon_is_px(drm_dev)) { pm_runtime_forbid(dev); return -EBUSY; } @@ -434,10 +428,7 @@ static int radeon_pmops_runtime_resume(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; - if (radeon_runtime_pm == 0) - return -EINVAL; - - if (radeon_runtime_pm == -1 && !radeon_is_px()) + if (!radeon_is_px(drm_dev)) return -EINVAL; drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; @@ -462,14 +453,7 @@ static int radeon_pmops_runtime_idle(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); struct drm_crtc *crtc; - if (radeon_runtime_pm == 0) { - pm_runtime_forbid(dev); - return -EBUSY; - } - - /* are we PX enabled? */ - if (radeon_runtime_pm == -1 && !radeon_is_px()) { - DRM_DEBUG_DRIVER("failing to power off - not px\n"); + if (!radeon_is_px(drm_dev)) { pm_runtime_forbid(dev); return -EBUSY; } diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 614ad549297f..9da5da4ffd17 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h @@ -115,6 +115,7 @@ enum radeon_chip_flags { RADEON_NEW_MEMMAP = 0x00400000UL, RADEON_IS_PCI = 0x00800000UL, RADEON_IS_IGPGART = 0x01000000UL, + RADEON_IS_PX = 0x02000000UL, }; #endif diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 3e49342a20e6..9337820e4d37 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -35,9 +35,9 @@ #include #if defined(CONFIG_VGA_SWITCHEROO) -bool radeon_is_px(void); +bool radeon_has_atpx(void); #else -static inline bool radeon_is_px(void) { return false; } +static inline bool radeon_has_atpx(void) { return false; } #endif /** @@ -107,6 +107,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) flags |= RADEON_IS_PCI; } + if (radeon_runtime_pm == 1) + flags |= RADEON_IS_PX; + else if ((radeon_runtime_pm == -1) && + radeon_has_atpx() && + ((flags & RADEON_IS_IGP) == 0)) + flags |= RADEON_IS_PX; + /* radeon_device_init should report only fatal error * like memory allocation failure or iomapping failure, * or memory manager initialization failure, it must @@ -137,8 +144,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) "Error during ACPI methods call\n"); } - if ((radeon_runtime_pm == 1) || - ((radeon_runtime_pm == -1) && radeon_is_px())) { + if (radeon_is_px(dev)) { pm_runtime_use_autosuspend(dev->dev); pm_runtime_set_autosuspend_delay(dev->dev, 5000); pm_runtime_set_active(dev->dev); -- GitLab From 6abc6d5c73b22ccf2e5688df6a2eb02ee8dfdf59 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 10 Apr 2014 22:29:02 -0400 Subject: [PATCH 443/797] drm/radeon: update CI DPM powertune settings As per internal recommendations. Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/ci_dpm.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 6d395ec25c13..18e91ee2c8b7 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -202,24 +202,29 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev) struct ci_power_info *pi = ci_get_pi(rdev); switch (rdev->pdev->device) { + case 0x6649: case 0x6650: + case 0x6651: case 0x6658: case 0x665C: + case 0x665D: default: pi->powertune_defaults = &defaults_bonaire_xt; break; - case 0x6651: - case 0x665D: - pi->powertune_defaults = &defaults_bonaire_pro; - break; case 0x6640: - pi->powertune_defaults = &defaults_saturn_xt; - break; case 0x6641: - pi->powertune_defaults = &defaults_saturn_pro; + case 0x6646: + case 0x6647: + pi->powertune_defaults = &defaults_saturn_xt; break; case 0x67B8: case 0x67B0: + pi->powertune_defaults = &defaults_hawaii_xt; + break; + case 0x67BA: + case 0x67B1: + pi->powertune_defaults = &defaults_hawaii_pro; + break; case 0x67A0: case 0x67A1: case 0x67A2: @@ -228,11 +233,7 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev) case 0x67AA: case 0x67B9: case 0x67BE: - pi->powertune_defaults = &defaults_hawaii_xt; - break; - case 0x67BA: - case 0x67B1: - pi->powertune_defaults = &defaults_hawaii_pro; + pi->powertune_defaults = &defaults_bonaire_xt; break; } -- GitLab From 5fb9cc4d8b1639b9a7487c1ee7b2b0c52877327d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 4 Apr 2014 13:45:42 +0200 Subject: [PATCH 444/797] drm/radeon: apply more strict limits for PLL params v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Letting post and refernce divider get to big is bad for signal stability. v2: increase the limit to 210 Signed-off-by: Christian König --- drivers/gpu/drm/radeon/radeon_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 386cfa4c194d..2f42912031ac 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -937,6 +937,9 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, } post_div = post_div_best; + /* limit reference * post divider to a maximum */ + ref_div_max = min(210 / post_div, ref_div_max); + /* get matching reference and feedback divider */ ref_div = max(den / post_div, 1u); fb_div = nom; -- GitLab From 1ebe92802eaf0569784dce843bc28a78842d236c Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 11 Apr 2014 11:21:49 -0400 Subject: [PATCH 445/797] drm/radeon: add support for newer mc ucode on SI (v2) May fix stability issues with some newer cards. v2: print out mc firmware version used and size Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_ucode.h | 3 +++ drivers/gpu/drm/radeon/si.c | 35 +++++++++++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index a77cd274dfc3..f4155484b395 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h @@ -57,6 +57,9 @@ #define BTC_MC_UCODE_SIZE 6024 #define CAYMAN_MC_UCODE_SIZE 6037 #define SI_MC_UCODE_SIZE 7769 +#define TAHITI_MC_UCODE_SIZE 7808 +#define PITCAIRN_MC_UCODE_SIZE 7775 +#define VERDE_MC_UCODE_SIZE 7875 #define OLAND_MC_UCODE_SIZE 7863 #define CIK_MC_UCODE_SIZE 7866 #define HAWAII_MC_UCODE_SIZE 7933 diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index d589475fe9e6..86f8c9c87f5c 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -39,30 +39,35 @@ MODULE_FIRMWARE("radeon/TAHITI_pfp.bin"); MODULE_FIRMWARE("radeon/TAHITI_me.bin"); MODULE_FIRMWARE("radeon/TAHITI_ce.bin"); MODULE_FIRMWARE("radeon/TAHITI_mc.bin"); +MODULE_FIRMWARE("radeon/TAHITI_mc2.bin"); MODULE_FIRMWARE("radeon/TAHITI_rlc.bin"); MODULE_FIRMWARE("radeon/TAHITI_smc.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_me.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin"); +MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin"); MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin"); MODULE_FIRMWARE("radeon/VERDE_pfp.bin"); MODULE_FIRMWARE("radeon/VERDE_me.bin"); MODULE_FIRMWARE("radeon/VERDE_ce.bin"); MODULE_FIRMWARE("radeon/VERDE_mc.bin"); +MODULE_FIRMWARE("radeon/VERDE_mc2.bin"); MODULE_FIRMWARE("radeon/VERDE_rlc.bin"); MODULE_FIRMWARE("radeon/VERDE_smc.bin"); MODULE_FIRMWARE("radeon/OLAND_pfp.bin"); MODULE_FIRMWARE("radeon/OLAND_me.bin"); MODULE_FIRMWARE("radeon/OLAND_ce.bin"); MODULE_FIRMWARE("radeon/OLAND_mc.bin"); +MODULE_FIRMWARE("radeon/OLAND_mc2.bin"); MODULE_FIRMWARE("radeon/OLAND_rlc.bin"); MODULE_FIRMWARE("radeon/OLAND_smc.bin"); MODULE_FIRMWARE("radeon/HAINAN_pfp.bin"); MODULE_FIRMWARE("radeon/HAINAN_me.bin"); MODULE_FIRMWARE("radeon/HAINAN_ce.bin"); MODULE_FIRMWARE("radeon/HAINAN_mc.bin"); +MODULE_FIRMWARE("radeon/HAINAN_mc2.bin"); MODULE_FIRMWARE("radeon/HAINAN_rlc.bin"); MODULE_FIRMWARE("radeon/HAINAN_smc.bin"); @@ -1467,7 +1472,7 @@ int si_mc_load_microcode(struct radeon_device *rdev) const __be32 *fw_data; u32 running, blackout = 0; u32 *io_mc_regs; - int i, ucode_size, regs_size; + int i, regs_size, ucode_size = rdev->mc_fw->size / 4; if (!rdev->mc_fw) return -EINVAL; @@ -1475,28 +1480,23 @@ int si_mc_load_microcode(struct radeon_device *rdev) switch (rdev->family) { case CHIP_TAHITI: io_mc_regs = (u32 *)&tahiti_io_mc_regs; - ucode_size = SI_MC_UCODE_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE; break; case CHIP_PITCAIRN: io_mc_regs = (u32 *)&pitcairn_io_mc_regs; - ucode_size = SI_MC_UCODE_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE; break; case CHIP_VERDE: default: io_mc_regs = (u32 *)&verde_io_mc_regs; - ucode_size = SI_MC_UCODE_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE; break; case CHIP_OLAND: io_mc_regs = (u32 *)&oland_io_mc_regs; - ucode_size = OLAND_MC_UCODE_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE; break; case CHIP_HAINAN: io_mc_regs = (u32 *)&hainan_io_mc_regs; - ucode_size = OLAND_MC_UCODE_SIZE; regs_size = TAHITI_IO_MC_REGS_SIZE; break; } @@ -1552,7 +1552,7 @@ static int si_init_microcode(struct radeon_device *rdev) const char *chip_name; const char *rlc_chip_name; size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size; - size_t smc_req_size; + size_t smc_req_size, mc2_req_size; char fw_name[30]; int err; @@ -1567,6 +1567,7 @@ static int si_init_microcode(struct radeon_device *rdev) ce_req_size = SI_CE_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4; mc_req_size = SI_MC_UCODE_SIZE * 4; + mc2_req_size = TAHITI_MC_UCODE_SIZE * 4; smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4); break; case CHIP_PITCAIRN: @@ -1577,6 +1578,7 @@ static int si_init_microcode(struct radeon_device *rdev) ce_req_size = SI_CE_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4; mc_req_size = SI_MC_UCODE_SIZE * 4; + mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4; smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4); break; case CHIP_VERDE: @@ -1587,6 +1589,7 @@ static int si_init_microcode(struct radeon_device *rdev) ce_req_size = SI_CE_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4; mc_req_size = SI_MC_UCODE_SIZE * 4; + mc2_req_size = VERDE_MC_UCODE_SIZE * 4; smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4); break; case CHIP_OLAND: @@ -1596,7 +1599,7 @@ static int si_init_microcode(struct radeon_device *rdev) me_req_size = SI_PM4_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4; - mc_req_size = OLAND_MC_UCODE_SIZE * 4; + mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4; smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4); break; case CHIP_HAINAN: @@ -1606,7 +1609,7 @@ static int si_init_microcode(struct radeon_device *rdev) me_req_size = SI_PM4_UCODE_SIZE * 4; ce_req_size = SI_CE_UCODE_SIZE * 4; rlc_req_size = SI_RLC_UCODE_SIZE * 4; - mc_req_size = OLAND_MC_UCODE_SIZE * 4; + mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4; smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4); break; default: BUG(); @@ -1659,16 +1662,22 @@ static int si_init_microcode(struct radeon_device *rdev) err = -EINVAL; } - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name); err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); - if (err) - goto out; - if (rdev->mc_fw->size != mc_req_size) { + if (err) { + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); + if (err) + goto out; + } + if ((rdev->mc_fw->size != mc_req_size) && + (rdev->mc_fw->size != mc2_req_size)) { printk(KERN_ERR "si_mc: Bogus length %zu in firmware \"%s\"\n", rdev->mc_fw->size, fw_name); err = -EINVAL; } + DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size); snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); -- GitLab From 277babc374f6ecab6af182554f5d9f35a7768755 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 11 Apr 2014 11:21:50 -0400 Subject: [PATCH 446/797] drm/radeon: add support for newer mc ucode on CI (v2) Fixes mclk stability on certain asics. v2: print out mc firmware version used and size bug: https://bugs.freedesktop.org/show_bug.cgi?id=75992 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/cik.c | 26 +++++++++++++++++--------- drivers/gpu/drm/radeon/radeon_ucode.h | 4 +++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 745143c2358f..7e430450bac0 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -38,6 +38,7 @@ MODULE_FIRMWARE("radeon/BONAIRE_me.bin"); MODULE_FIRMWARE("radeon/BONAIRE_ce.bin"); MODULE_FIRMWARE("radeon/BONAIRE_mec.bin"); MODULE_FIRMWARE("radeon/BONAIRE_mc.bin"); +MODULE_FIRMWARE("radeon/BONAIRE_mc2.bin"); MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin"); MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin"); MODULE_FIRMWARE("radeon/BONAIRE_smc.bin"); @@ -46,6 +47,7 @@ MODULE_FIRMWARE("radeon/HAWAII_me.bin"); MODULE_FIRMWARE("radeon/HAWAII_ce.bin"); MODULE_FIRMWARE("radeon/HAWAII_mec.bin"); MODULE_FIRMWARE("radeon/HAWAII_mc.bin"); +MODULE_FIRMWARE("radeon/HAWAII_mc2.bin"); MODULE_FIRMWARE("radeon/HAWAII_rlc.bin"); MODULE_FIRMWARE("radeon/HAWAII_sdma.bin"); MODULE_FIRMWARE("radeon/HAWAII_smc.bin"); @@ -1703,7 +1705,7 @@ int ci_mc_load_microcode(struct radeon_device *rdev) const __be32 *fw_data; u32 running, blackout = 0; u32 *io_mc_regs; - int i, ucode_size, regs_size; + int i, regs_size, ucode_size = rdev->mc_fw->size / 4; if (!rdev->mc_fw) return -EINVAL; @@ -1711,12 +1713,10 @@ int ci_mc_load_microcode(struct radeon_device *rdev) switch (rdev->family) { case CHIP_BONAIRE: io_mc_regs = (u32 *)&bonaire_io_mc_regs; - ucode_size = CIK_MC_UCODE_SIZE; regs_size = BONAIRE_IO_MC_REGS_SIZE; break; case CHIP_HAWAII: io_mc_regs = (u32 *)&hawaii_io_mc_regs; - ucode_size = HAWAII_MC_UCODE_SIZE; regs_size = HAWAII_IO_MC_REGS_SIZE; break; default: @@ -1783,7 +1783,7 @@ static int cik_init_microcode(struct radeon_device *rdev) const char *chip_name; size_t pfp_req_size, me_req_size, ce_req_size, mec_req_size, rlc_req_size, mc_req_size = 0, - sdma_req_size, smc_req_size = 0; + sdma_req_size, smc_req_size = 0, mc2_req_size = 0; char fw_name[30]; int err; @@ -1797,7 +1797,8 @@ static int cik_init_microcode(struct radeon_device *rdev) ce_req_size = CIK_CE_UCODE_SIZE * 4; mec_req_size = CIK_MEC_UCODE_SIZE * 4; rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4; - mc_req_size = CIK_MC_UCODE_SIZE * 4; + mc_req_size = BONAIRE_MC_UCODE_SIZE * 4; + mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4); break; @@ -1809,6 +1810,7 @@ static int cik_init_microcode(struct radeon_device *rdev) mec_req_size = CIK_MEC_UCODE_SIZE * 4; rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4; mc_req_size = HAWAII_MC_UCODE_SIZE * 4; + mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4; sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4); break; @@ -1904,16 +1906,22 @@ static int cik_init_microcode(struct radeon_device *rdev) /* No SMC, MC ucode on APUs */ if (!(rdev->flags & RADEON_IS_IGP)) { - snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name); err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); - if (err) - goto out; - if (rdev->mc_fw->size != mc_req_size) { + if (err) { + snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); + err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); + if (err) + goto out; + } + if ((rdev->mc_fw->size != mc_req_size) && + (rdev->mc_fw->size != mc2_req_size)){ printk(KERN_ERR "cik_mc: Bogus length %zu in firmware \"%s\"\n", rdev->mc_fw->size, fw_name); err = -EINVAL; } + DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size); snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index f4155484b395..58d12938c0b8 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h @@ -61,8 +61,10 @@ #define PITCAIRN_MC_UCODE_SIZE 7775 #define VERDE_MC_UCODE_SIZE 7875 #define OLAND_MC_UCODE_SIZE 7863 -#define CIK_MC_UCODE_SIZE 7866 +#define BONAIRE_MC_UCODE_SIZE 7866 +#define BONAIRE_MC2_UCODE_SIZE 7948 #define HAWAII_MC_UCODE_SIZE 7933 +#define HAWAII_MC2_UCODE_SIZE 8091 /* SDMA */ #define CIK_SDMA_UCODE_SIZE 1050 -- GitLab From 7e1858f9aff7d608b3d0abad4bda0130de887b89 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 11 Apr 2014 11:21:51 -0400 Subject: [PATCH 447/797] drm/radeon: re-enable mclk dpm on R7 260X asics If the new mc ucode is available. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ci_dpm.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index 18e91ee2c8b7..10dae4106c08 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -21,8 +21,10 @@ * */ +#include #include "drmP.h" #include "radeon.h" +#include "radeon_ucode.h" #include "cikd.h" #include "r600_dpm.h" #include "ci_dpm.h" @@ -5147,9 +5149,11 @@ int ci_dpm_init(struct radeon_device *rdev) pi->mclk_dpm_key_disabled = 0; pi->pcie_dpm_key_disabled = 0; - /* mclk dpm is unstable on some R7 260X cards */ - if (rdev->pdev->device == 0x6658) + /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */ + if ((rdev->pdev->device == 0x6658) && + (rdev->mc_fw->size == (BONAIRE_MC_UCODE_SIZE * 4))) { pi->mclk_dpm_key_disabled = 1; + } pi->caps_sclk_ds = true; -- GitLab From 681941c1790b92207334d08ee017007685f35438 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Tue, 15 Apr 2014 00:10:22 +0200 Subject: [PATCH 448/797] drm/radeon: fix VCE fence command Due to a type mismatch that causes an implicit type conversion, the upper 32 bits of the GPU address have been zeroed out when adding to the command buffer. Picked up by Coverity - CID 1198624. Signed-off-by: Christoph Jaeger --- drivers/gpu/drm/radeon/radeon_vce.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index 76e9904bc537..ced53dd03e7c 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c @@ -613,7 +613,7 @@ void radeon_vce_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) { struct radeon_ring *ring = &rdev->ring[fence->ring]; - uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr; + uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr; radeon_ring_write(ring, VCE_CMD_FENCE); radeon_ring_write(ring, addr); -- GitLab From 74073c9dd29905645feb6dee03c144657a9844cd Mon Sep 17 00:00:00 2001 From: Quentin Casasnovas Date: Tue, 18 Mar 2014 17:16:52 +0100 Subject: [PATCH 449/797] drm/radeon: memory leak on bo reservation failure. v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On bo reservation failure, we end up leaking fpriv. v2 (chk): rebased and added missing free on vm failure as well Fixes: 5e386b574cf7e1 ("drm/radeon: fix missing bo reservation") Cc: stable@vger.kernel.org Cc: Christian König Cc: Alex Deucher Signed-off-by: Quentin Casasnovas Signed-off-by: Christian König --- drivers/gpu/drm/radeon/radeon_kms.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 9337820e4d37..fb3d13f693dd 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -574,12 +574,17 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) } r = radeon_vm_init(rdev, &fpriv->vm); - if (r) + if (r) { + kfree(fpriv); return r; + } r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); - if (r) + if (r) { + radeon_vm_fini(rdev, &fpriv->vm); + kfree(fpriv); return r; + } /* map the ib pool buffer read only into * virtual address space */ -- GitLab From f8a2645ecede4eaf90b3d785f2805c8ecb76d43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Wed, 16 Apr 2014 11:54:21 +0200 Subject: [PATCH 450/797] drm/radeon: improve PLL params if we don't match exactly v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise we might be quite off on older chipsets. v2: keep ref_div minimum Signed-off-by: Christian König --- drivers/gpu/drm/radeon/radeon_display.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 2f42912031ac..063d4255137f 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -865,7 +865,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, unsigned post_div_min, post_div_max, post_div; unsigned ref_div_min, ref_div_max, ref_div; unsigned post_div_best, diff_best; - unsigned nom, den, tmp; + unsigned nom, den; /* determine allowed feedback divider range */ fb_div_min = pll->min_feedback_div; @@ -941,22 +941,23 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, ref_div_max = min(210 / post_div, ref_div_max); /* get matching reference and feedback divider */ - ref_div = max(den / post_div, 1u); - fb_div = nom; + ref_div = max(DIV_ROUND_CLOSEST(den, post_div), 1u); + fb_div = DIV_ROUND_CLOSEST(nom * ref_div * post_div, den); /* we're almost done, but reference and feedback divider might be to large now */ - tmp = ref_div; + nom = fb_div; + den = ref_div; if (fb_div > fb_div_max) { - ref_div = ref_div * fb_div_max / fb_div; + ref_div = DIV_ROUND_CLOSEST(den * fb_div_max, nom); fb_div = fb_div_max; } if (ref_div > ref_div_max) { ref_div = ref_div_max; - fb_div = nom * ref_div_max / tmp; + fb_div = DIV_ROUND_CLOSEST(nom * ref_div_max, den); } /* reduce the numbers to a simpler ratio once more */ -- GitLab From 8c79bae6a30f606b7a4e17c994bc5f72f8fdaf11 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 16 Apr 2014 09:42:22 -0400 Subject: [PATCH 451/797] drm/radeon/si: make sure mc ucode is loaded before checking the size Avoid a possible segfault. Noticed-by: Dan Carpenter Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/si.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 86f8c9c87f5c..ac708e006180 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -1472,11 +1472,13 @@ int si_mc_load_microcode(struct radeon_device *rdev) const __be32 *fw_data; u32 running, blackout = 0; u32 *io_mc_regs; - int i, regs_size, ucode_size = rdev->mc_fw->size / 4; + int i, regs_size, ucode_size; if (!rdev->mc_fw) return -EINVAL; + ucode_size = rdev->mc_fw->size / 4; + switch (rdev->family) { case CHIP_TAHITI: io_mc_regs = (u32 *)&tahiti_io_mc_regs; -- GitLab From bcddee29b0b87af3aeda953840f97b356b24dc5e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 16 Apr 2014 09:42:23 -0400 Subject: [PATCH 452/797] drm/radeon/ci: make sure mc ucode is loaded before checking the size Avoid a possible segfault. Noticed-by: Dan Carpenter Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/cik.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 7e430450bac0..199eb194716f 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c @@ -1705,11 +1705,13 @@ int ci_mc_load_microcode(struct radeon_device *rdev) const __be32 *fw_data; u32 running, blackout = 0; u32 *io_mc_regs; - int i, regs_size, ucode_size = rdev->mc_fw->size / 4; + int i, regs_size, ucode_size; if (!rdev->mc_fw) return -EINVAL; + ucode_size = rdev->mc_fw->size / 4; + switch (rdev->family) { case CHIP_BONAIRE: io_mc_regs = (u32 *)&bonaire_io_mc_regs; -- GitLab From ab0f9e78b97f5193dd38b3757b42b6fbded05fb7 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 17 Apr 2014 14:13:49 +0200 Subject: [PATCH 453/797] ahci: Ensure "MSI Revert to Single Message" mode is not enforced The AHCI specification allows hardware to choose to revert to single MSI mode when fewer messages are allocated than requested. Yet, at least ICH10 chipset reverts to single MSI mode even when enough messages are allocated in some cases (see below). This update forces the driver to not rely on initialization of multiple MSIs mode alone and always check if "MSI Revert to Single Message" (MRSM) mode was enforced by the controller and fallback to the single MSI mode in case it did. That prevents a situation when the driver configured multiple per-port IRQ handlers, but the controller sends all port's interrupts to a single IRQ, which could easily screw up the interrupt handling and lead to delays and possibly crashes. The fix was tested on a 6-port controller that successfully reverted to the single MSI mode: 00:1f.2 SATA controller: Intel Corporation 82801JI (ICH10 Family) SATA AHCI Controller (prog-if 01 [AHCI 1.0]) Subsystem: Super Micro Computer Inc Device 10a7 Flags: bus master, 66MHz, medium devsel, latency 0, IRQ 101 I/O ports at f110 [size=8] I/O ports at f100 [size=4] I/O ports at f0f0 [size=8] I/O ports at f0e0 [size=4] I/O ports at f020 [size=32] Memory at fbf00000 (32-bit, non-prefetchable) [size=2K] Capabilities: [80] MSI: Enable+ Count=1/16 Maskable- 64bit- Capabilities: [70] Power Management version 3 Capabilities: [a8] SATA HBA v1.0 Capabilities: [b0] PCI Advanced Features Kernel driver in use: ahci With 6 ports just 8 MSI vectors should be enough, but the adapter enforces the MRSM mode when less than 16 vectors are written to the Multiple Messages Enable PCI register. I instigated MRSM mode by forcing @nvec to 8 in ahci_init_interrupts(). Signed-off-by: Alexander Gordeev Cc: linux-ide@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/ahci.c | 9 ++++++++- drivers/ata/ahci.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e45b18ee04c3..f6b3e31f63cd 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1164,7 +1164,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) #endif static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, - struct ahci_host_priv *hpriv) + struct ahci_host_priv *hpriv) { int nvec; @@ -1189,6 +1189,13 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, else if (nvec < 0) goto intx; + /* fallback to single MSI mode if the controller enforced MRSM mode */ + if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) { + pci_disable_msi(pdev); + printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n"); + goto single_msi; + } + return nvec; single_msi: diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 51af275b3388..b5eb886da226 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -94,6 +94,7 @@ enum { /* HOST_CTL bits */ HOST_RESET = (1 << 0), /* reset controller; self-clear */ HOST_IRQ_EN = (1 << 1), /* global IRQ enable */ + HOST_MRSM = (1 << 2), /* MSI Revert to Single Message */ HOST_AHCI_EN = (1 << 31), /* AHCI enabled */ /* HOST_CAP bits */ -- GitLab From ccf8f53cac7d9321c9af2b14af41e703f44ac198 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 17 Apr 2014 14:13:50 +0200 Subject: [PATCH 454/797] ahci: Use pci_enable_msi_exact() instead of pci_enable_msi_range() The driver calls pci_enable_msi_range() function with the range of [nvec..nvec] which is what pci_enable_msi_exact() function is for. Signed-off-by: Alexander Gordeev Cc: linux-ide@vger.kernel.org Signed-off-by: Tejun Heo --- drivers/ata/ahci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index f6b3e31f63cd..44d40c746982 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1166,7 +1166,7 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, struct ahci_host_priv *hpriv) { - int nvec; + int rc, nvec; if (hpriv->flags & AHCI_HFLAG_NO_MSI) goto intx; @@ -1183,10 +1183,10 @@ static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, if (nvec < n_ports) goto single_msi; - nvec = pci_enable_msi_range(pdev, nvec, nvec); - if (nvec == -ENOSPC) + rc = pci_enable_msi_exact(pdev, nvec); + if (rc == -ENOSPC) goto single_msi; - else if (nvec < 0) + else if (rc < 0) goto intx; /* fallback to single MSI mode if the controller enforced MRSM mode */ -- GitLab From 6ea6215fe394e320468589d9bba464a48f6d823a Mon Sep 17 00:00:00 2001 From: "zhangwei(Jovi)" Date: Thu, 17 Apr 2014 16:05:19 +0800 Subject: [PATCH 455/797] tracing/uprobes: Fix uprobe_cpu_buffer memory leak Forgot to free uprobe_cpu_buffer percpu page in uprobe_buffer_disable(). Link: http://lkml.kernel.org/p/534F8B3F.1090407@huawei.com Cc: stable@vger.kernel.org # v3.14+ Acked-by: Namhyung Kim Signed-off-by: zhangwei(Jovi) Signed-off-by: Steven Rostedt --- kernel/trace/trace_uprobe.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 930e51462dc8..c082a7441345 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -732,9 +732,15 @@ static int uprobe_buffer_enable(void) static void uprobe_buffer_disable(void) { + int cpu; + BUG_ON(!mutex_is_locked(&event_mutex)); if (--uprobe_buffer_refcnt == 0) { + for_each_possible_cpu(cpu) + free_page((unsigned long)per_cpu_ptr(uprobe_cpu_buffer, + cpu)->buf); + free_percpu(uprobe_cpu_buffer); uprobe_cpu_buffer = NULL; } -- GitLab From 252455c40316009cc791f00338ee2e367d2d2739 Mon Sep 17 00:00:00 2001 From: Suresh Gupta Date: Fri, 21 Mar 2014 16:38:12 +0530 Subject: [PATCH 456/797] usb: gadget: fsl driver pullup fix This fix the fsl usb gadget driver in a way that the usb device will be only "pulled up" on requests only when vbus is powered Signed-off-by: Suresh Gupta Signed-off-by: Felipe Balbi --- drivers/usb/gadget/fsl_udc_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index dcd0b07ae3a0..a2f26cdb56fe 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c @@ -1219,6 +1219,10 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) struct fsl_udc *udc; udc = container_of(gadget, struct fsl_udc, gadget); + + if (!udc->vbus_active) + return -EOPNOTSUPP; + udc->softconnect = (is_on != 0); if (can_pullup(udc)) fsl_writel((fsl_readl(&dr_regs->usbcmd) | USB_CMD_RUN_STOP), -- GitLab From 12de375ec493ab1767d4a07dde823e63ae5edc21 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 17 Apr 2014 09:33:19 -0700 Subject: [PATCH 457/797] Revert "serial: 8250, disable "too much work" messages" This reverts commit f4f653e9875e573860e783fecbebde284a8626f5. Jiri writes: No, please drop this one. We need a better solution as it turned out that some boxes need 16k loops and it will increase with new processors :(. Cc: Jiri Slaby Cc: Martin Pluskal Cc: Takashi Iwai Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 139ab1997e06..81f909c2101f 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1601,7 +1601,8 @@ static irqreturn_t serial8250_interrupt(int irq, void *dev_id) l = l->next; if (l == i->head && pass_counter++ > PASS_LIMIT) { - pr_debug_ratelimited( + /* If we hit this, we're dead. */ + printk_ratelimited(KERN_ERR "serial8250: too much work for irq%d\n", irq); break; } -- GitLab From a94cdd1f4d30f12904ab528152731fb13a812a16 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 14 Apr 2014 09:46:50 -0500 Subject: [PATCH 458/797] Char: ipmi_bt_sm, fix infinite loop In read_all_bytes, we do unsigned char i; ... bt->read_data[0] = BMC2HOST; bt->read_count = bt->read_data[0]; ... for (i = 1; i <= bt->read_count; i++) bt->read_data[i] = BMC2HOST; If bt->read_data[0] == bt->read_count == 255, we loop infinitely in the 'for' loop. Make 'i' an 'int' instead of 'char' to get rid of the overflow and finish the loop after 255 iterations every time. Signed-off-by: Jiri Slaby Reported-and-debugged-by: Rui Hui Dian Cc: Tomas Cech Cc: Corey Minyard Cc: Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_bt_sm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index f5e4cd7617f6..61e71616689b 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c @@ -352,7 +352,7 @@ static inline void write_all_bytes(struct si_sm_data *bt) static inline int read_all_bytes(struct si_sm_data *bt) { - unsigned char i; + unsigned int i; /* * length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode. -- GitLab From 48e8ac2979920ffa39117e2d725afa3a749bfe8d Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Mon, 14 Apr 2014 09:46:51 -0500 Subject: [PATCH 459/797] ipmi: Fix a race restarting the timer With recent changes it is possible for the timer handler to detect an idle interface and not start the timer, but the thread to start an operation at the same time. The thread will not start the timer in that instance, resulting in the timer not running. Instead, move all timer operations under the lock and start the timer in the thread if it detect non-idle and the timer is not already running. Moving under locks allows the last timeout to be set in both the thread and the timer. 'Timer is not running' means that the timer is not pending and smi_timeout() is not running. So we need a flag to detect this correctly. Also fix a few other timeout bugs: setting the last timeout when the interrupt has to be disabled and the timer started, and setting the last timeout in check_start_timer_thread possibly racing with the timer Signed-off-by: Corey Minyard Signed-off-by: Bodo Stroesser Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 46 +++++++++++++++++++------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index b7efd3c1a882..9c4069151955 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -248,6 +248,9 @@ struct smi_info { /* The timer for this si. */ struct timer_list si_timer; + /* This flag is set, if the timer is running (timer_pending() isn't enough) */ + bool timer_running; + /* The time (in jiffies) the last timeout occurred at. */ unsigned long last_timeout_jiffies; @@ -434,6 +437,13 @@ static void start_clear_flags(struct smi_info *smi_info) smi_info->si_state = SI_CLEARING_FLAGS; } +static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val) +{ + smi_info->last_timeout_jiffies = jiffies; + mod_timer(&smi_info->si_timer, new_val); + smi_info->timer_running = true; +} + /* * When we have a situtaion where we run out of memory and cannot * allocate messages, we just leave them in the BMC and run the system @@ -446,8 +456,7 @@ static inline void disable_si_irq(struct smi_info *smi_info) start_disable_irq(smi_info); smi_info->interrupt_disabled = 1; if (!atomic_read(&smi_info->stop_operation)) - mod_timer(&smi_info->si_timer, - jiffies + SI_TIMEOUT_JIFFIES); + smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); } } @@ -907,15 +916,7 @@ static void sender(void *send_info, list_add_tail(&msg->link, &smi_info->xmit_msgs); if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) { - /* - * last_timeout_jiffies is updated here to avoid - * smi_timeout() handler passing very large time_diff - * value to smi_event_handler() that causes - * the send command to abort. - */ - smi_info->last_timeout_jiffies = jiffies; - - mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES); + smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); if (smi_info->thread) wake_up_process(smi_info->thread); @@ -1004,6 +1005,17 @@ static int ipmi_thread(void *data) spin_lock_irqsave(&(smi_info->si_lock), flags); smi_result = smi_event_handler(smi_info, 0); + + /* + * If the driver is doing something, there is a possible + * race with the timer. If the timer handler see idle, + * and the thread here sees something else, the timer + * handler won't restart the timer even though it is + * required. So start it here if necessary. + */ + if (smi_result != SI_SM_IDLE && !smi_info->timer_running) + smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); + spin_unlock_irqrestore(&(smi_info->si_lock), flags); busy_wait = ipmi_thread_busy_wait(smi_result, smi_info, &busy_until); @@ -1073,10 +1085,6 @@ static void smi_timeout(unsigned long data) * SI_USEC_PER_JIFFY); smi_result = smi_event_handler(smi_info, time_diff); - spin_unlock_irqrestore(&(smi_info->si_lock), flags); - - smi_info->last_timeout_jiffies = jiffies_now; - if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { /* Running with interrupts, only do long timeouts. */ timeout = jiffies + SI_TIMEOUT_JIFFIES; @@ -1098,7 +1106,10 @@ static void smi_timeout(unsigned long data) do_mod_timer: if (smi_result != SI_SM_IDLE) - mod_timer(&(smi_info->si_timer), timeout); + smi_mod_timer(smi_info, timeout); + else + smi_info->timer_running = false; + spin_unlock_irqrestore(&(smi_info->si_lock), flags); } static irqreturn_t si_irq_handler(int irq, void *data) @@ -1146,8 +1157,7 @@ static int smi_start_processing(void *send_info, /* Set up the timer that drives the interface. */ setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); - new_smi->last_timeout_jiffies = jiffies; - mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES); + smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES); /* * Check if the user forcefully enabled the daemon. -- GitLab From eb6d78ec213e6938559b801421d64714dafcf4b2 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 14 Apr 2014 09:46:52 -0500 Subject: [PATCH 460/797] ipmi: Reset the KCS timeout when starting error recovery The OBF timer in KCS was not reset in one situation when error recovery was started, resulting in an immediate timeout. Reported-by: Bodo Stroesser Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_kcs_sm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index 6a4bdc18955a..8c25f596808a 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c @@ -251,8 +251,9 @@ static inline int check_obf(struct si_sm_data *kcs, unsigned char status, if (!GET_STATUS_OBF(status)) { kcs->obf_timeout -= time; if (kcs->obf_timeout < 0) { - start_error_recovery(kcs, "OBF not ready in time"); - return 1; + kcs->obf_timeout = OBF_RETRY_TIMEOUT; + start_error_recovery(kcs, "OBF not ready in time"); + return 1; } return 0; } -- GitLab From 0dfe6e7ed47feeb22f3cf8c7d8ac7e65bd4e87f5 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 14 Apr 2014 09:46:53 -0500 Subject: [PATCH 461/797] ipmi: Turn off default probing of interfaces The default probing can cause problems with some system, slow booting, extra CPU usages, etc. Turn it off by default and give a config option to enable it. From: Matthew Garrett Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/Kconfig | 12 ++++++++++++ drivers/char/ipmi/ipmi_si_intf.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 0baa8fab4ea7..db1c9b7adaa6 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -50,6 +50,18 @@ config IPMI_SI Currently, only KCS and SMIC are supported. If you are using IPMI, you should probably say "y" here. +config IPMI_SI_PROBE_DEFAULTS + bool 'Probe for all possible IPMI system interfaces by default' + default n + depends on IPMI_SI + help + Modern systems will usually expose IPMI interfaces via a discoverable + firmware mechanism such as ACPI or DMI. Older systems do not, and so + the driver is forced to probe hardware manually. This may cause boot + delays. Say "n" here to disable this manual probing. IPMI will then + only be available on older systems if the "ipmi_si_intf.trydefaults=1" + boot argument is passed. + config IPMI_WATCHDOG tristate 'IPMI Watchdog Timer' help diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 9c4069151955..25a1436a4291 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1239,7 +1239,7 @@ static bool si_tryplatform = 1; #ifdef CONFIG_PCI static bool si_trypci = 1; #endif -static bool si_trydefaults = 1; +static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS); static char *si_type[SI_MAX_PARMS]; #define MAX_SI_TYPE_STR 30 static char si_type_str[MAX_SI_TYPE_STR]; -- GitLab From 89986496de141213206d49450ffdd36098d41209 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 14 Apr 2014 09:46:54 -0500 Subject: [PATCH 462/797] ipmi: Turn off all activity on an idle ipmi interface The IPMI driver would wake up periodically looking for events and watchdog pretimeouts. If there is nothing waiting for these events, it's really kind of pointless to be checking for them. So modify the driver so the message handler can pass down if it needs the lower layer to be waiting for these. Modify the system interface lower layer to turn off all timer and thread activity if the upper layer doesn't need anything and it is not currently handling messages. And modify the message handler to not restart the timer if its timer is not needed. The timers and kthread will still be enabled if: - the SI interface is handling a message. - a user has enabled watching for events. - the IPMI watchdog timer is in use (since it uses pretimeouts). - the message handler is waiting on a remote response. - a user has registered to receive commands. This mostly affects interfaces without interrupts. Interfaces with interrupts already don't use CPU in the system interface when the interface is idle. Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 219 +++++++++++++++++----------- drivers/char/ipmi/ipmi_si_intf.c | 51 +++++-- include/linux/ipmi.h | 2 +- include/linux/ipmi_smi.h | 7 + 4 files changed, 182 insertions(+), 97 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index ec4e10fcf1a5..872c4ec79bf4 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -55,6 +55,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); static int ipmi_init_msghandler(void); static void smi_recv_tasklet(unsigned long); static void handle_new_recv_msgs(ipmi_smi_t intf); +static void need_waiter(ipmi_smi_t intf); static int initialized; @@ -73,6 +74,20 @@ static struct proc_dir_entry *proc_ipmi_root; */ #define MAX_MSG_TIMEOUT 60000 +/* Call every ~1000 ms. */ +#define IPMI_TIMEOUT_TIME 1000 + +/* How many jiffies does it take to get to the timeout time. */ +#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000) + +/* + * Request events from the queue every second (this is the number of + * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the + * future, IPMI will add a way to know immediately if an event is in + * the queue and this silliness can go away. + */ +#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) + /* * The main "user" data structure. */ @@ -92,7 +107,7 @@ struct ipmi_user { ipmi_smi_t intf; /* Does this interface receive IPMI events? */ - int gets_events; + bool gets_events; }; struct cmd_rcvr { @@ -383,6 +398,9 @@ struct ipmi_smi { unsigned int waiting_events_count; /* How many events in queue? */ char delivering_events; char event_msg_printed; + atomic_t event_waiters; + unsigned int ticks_to_req_ev; + int last_needs_timer; /* * The event receiver for my BMC, only really used at panic @@ -451,7 +469,6 @@ static DEFINE_MUTEX(ipmi_interfaces_mutex); static LIST_HEAD(smi_watchers); static DEFINE_MUTEX(smi_watchers_mutex); - #define ipmi_inc_stat(intf, stat) \ atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat]) #define ipmi_get_stat(intf, stat) \ @@ -772,6 +789,7 @@ static int intf_next_seq(ipmi_smi_t intf, *seq = i; *seqid = intf->seq_table[i].seqid; intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ; + need_waiter(intf); } else { rv = -EAGAIN; } @@ -941,7 +959,7 @@ int ipmi_create_user(unsigned int if_num, new_user->handler = handler; new_user->handler_data = handler_data; new_user->intf = intf; - new_user->gets_events = 0; + new_user->gets_events = false; if (!try_module_get(intf->handlers->owner)) { rv = -ENODEV; @@ -966,6 +984,11 @@ int ipmi_create_user(unsigned int if_num, spin_lock_irqsave(&intf->seq_lock, flags); list_add_rcu(&new_user->link, &intf->users); spin_unlock_irqrestore(&intf->seq_lock, flags); + if (handler->ipmi_watchdog_pretimeout) { + /* User wants pretimeouts, so make sure to watch for them. */ + if (atomic_inc_return(&intf->event_waiters) == 1) + need_waiter(intf); + } *user = new_user; return 0; @@ -1021,6 +1044,12 @@ int ipmi_destroy_user(ipmi_user_t user) user->valid = 0; + if (user->handler->ipmi_watchdog_pretimeout) + atomic_dec(&intf->event_waiters); + + if (user->gets_events) + atomic_dec(&intf->event_waiters); + /* Remove the user from the interface's sequence table. */ spin_lock_irqsave(&intf->seq_lock, flags); list_del_rcu(&user->link); @@ -1184,7 +1213,7 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode) } EXPORT_SYMBOL(ipmi_set_maintenance_mode); -int ipmi_set_gets_events(ipmi_user_t user, int val) +int ipmi_set_gets_events(ipmi_user_t user, bool val) { unsigned long flags; ipmi_smi_t intf = user->intf; @@ -1194,8 +1223,18 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) INIT_LIST_HEAD(&msgs); spin_lock_irqsave(&intf->events_lock, flags); + if (user->gets_events == val) + goto out; + user->gets_events = val; + if (val) { + if (atomic_inc_return(&intf->event_waiters) == 1) + need_waiter(intf); + } else { + atomic_dec(&intf->event_waiters); + } + if (intf->delivering_events) /* * Another thread is delivering events for this, so @@ -1289,6 +1328,9 @@ int ipmi_register_for_cmd(ipmi_user_t user, goto out_unlock; } + if (atomic_inc_return(&intf->event_waiters) == 1) + need_waiter(intf); + list_add_rcu(&rcvr->link, &intf->cmd_rcvrs); out_unlock: @@ -1330,6 +1372,7 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, mutex_unlock(&intf->cmd_rcvrs_mutex); synchronize_rcu(); while (rcvrs) { + atomic_dec(&intf->event_waiters); rcvr = rcvrs; rcvrs = rcvr->next; kfree(rcvr); @@ -2876,6 +2919,8 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, (unsigned long) intf); atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0); spin_lock_init(&intf->events_lock); + atomic_set(&intf->event_waiters, 0); + intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; INIT_LIST_HEAD(&intf->waiting_events); intf->waiting_events_count = 0; mutex_init(&intf->cmd_rcvrs_mutex); @@ -3965,7 +4010,8 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, struct list_head *timeouts, long timeout_period, - int slot, unsigned long *flags) + int slot, unsigned long *flags, + unsigned int *waiting_msgs) { struct ipmi_recv_msg *msg; struct ipmi_smi_handlers *handlers; @@ -3977,8 +4023,10 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, return; ent->timeout -= timeout_period; - if (ent->timeout > 0) + if (ent->timeout > 0) { + (*waiting_msgs)++; return; + } if (ent->retries_left == 0) { /* The message has used all its retries. */ @@ -3995,6 +4043,8 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, struct ipmi_smi_msg *smi_msg; /* More retries, send again. */ + (*waiting_msgs)++; + /* * Start with the max timer, set to normal timer after * the message is sent. @@ -4040,117 +4090,118 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, } } -static void ipmi_timeout_handler(long timeout_period) +static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period) { - ipmi_smi_t intf; struct list_head timeouts; struct ipmi_recv_msg *msg, *msg2; unsigned long flags; int i; + unsigned int waiting_msgs = 0; - rcu_read_lock(); - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - tasklet_schedule(&intf->recv_tasklet); - - /* - * Go through the seq table and find any messages that - * have timed out, putting them in the timeouts - * list. - */ - INIT_LIST_HEAD(&timeouts); - spin_lock_irqsave(&intf->seq_lock, flags); - for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) - check_msg_timeout(intf, &(intf->seq_table[i]), - &timeouts, timeout_period, i, - &flags); - spin_unlock_irqrestore(&intf->seq_lock, flags); + /* + * Go through the seq table and find any messages that + * have timed out, putting them in the timeouts + * list. + */ + INIT_LIST_HEAD(&timeouts); + spin_lock_irqsave(&intf->seq_lock, flags); + for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) + check_msg_timeout(intf, &(intf->seq_table[i]), + &timeouts, timeout_period, i, + &flags, &waiting_msgs); + spin_unlock_irqrestore(&intf->seq_lock, flags); - list_for_each_entry_safe(msg, msg2, &timeouts, link) - deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE); + list_for_each_entry_safe(msg, msg2, &timeouts, link) + deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE); - /* - * Maintenance mode handling. Check the timeout - * optimistically before we claim the lock. It may - * mean a timeout gets missed occasionally, but that - * only means the timeout gets extended by one period - * in that case. No big deal, and it avoids the lock - * most of the time. - */ + /* + * Maintenance mode handling. Check the timeout + * optimistically before we claim the lock. It may + * mean a timeout gets missed occasionally, but that + * only means the timeout gets extended by one period + * in that case. No big deal, and it avoids the lock + * most of the time. + */ + if (intf->auto_maintenance_timeout > 0) { + spin_lock_irqsave(&intf->maintenance_mode_lock, flags); if (intf->auto_maintenance_timeout > 0) { - spin_lock_irqsave(&intf->maintenance_mode_lock, flags); - if (intf->auto_maintenance_timeout > 0) { - intf->auto_maintenance_timeout - -= timeout_period; - if (!intf->maintenance_mode - && (intf->auto_maintenance_timeout <= 0)) { - intf->maintenance_mode_enable = 0; - maintenance_mode_update(intf); - } + intf->auto_maintenance_timeout + -= timeout_period; + if (!intf->maintenance_mode + && (intf->auto_maintenance_timeout <= 0)) { + intf->maintenance_mode_enable = 0; + maintenance_mode_update(intf); } - spin_unlock_irqrestore(&intf->maintenance_mode_lock, - flags); } + spin_unlock_irqrestore(&intf->maintenance_mode_lock, + flags); } - rcu_read_unlock(); + + tasklet_schedule(&intf->recv_tasklet); + + return waiting_msgs; } -static void ipmi_request_event(void) +static void ipmi_request_event(ipmi_smi_t intf) { - ipmi_smi_t intf; struct ipmi_smi_handlers *handlers; - rcu_read_lock(); - /* - * Called from the timer, no need to check if handlers is - * valid. - */ - list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { - /* No event requests when in maintenance mode. */ - if (intf->maintenance_mode_enable) - continue; + /* No event requests when in maintenance mode. */ + if (intf->maintenance_mode_enable) + return; - handlers = intf->handlers; - if (handlers) - handlers->request_events(intf->send_info); - } - rcu_read_unlock(); + handlers = intf->handlers; + if (handlers) + handlers->request_events(intf->send_info); } static struct timer_list ipmi_timer; -/* Call every ~1000 ms. */ -#define IPMI_TIMEOUT_TIME 1000 - -/* How many jiffies does it take to get to the timeout time. */ -#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000) - -/* - * Request events from the queue every second (this is the number of - * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the - * future, IPMI will add a way to know immediately if an event is in - * the queue and this silliness can go away. - */ -#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME)) - static atomic_t stop_operation; -static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME; static void ipmi_timeout(unsigned long data) { + ipmi_smi_t intf; + int nt = 0; + if (atomic_read(&stop_operation)) return; - ticks_to_req_ev--; - if (ticks_to_req_ev == 0) { - ipmi_request_event(); - ticks_to_req_ev = IPMI_REQUEST_EV_TIME; - } + rcu_read_lock(); + list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { + int lnt = 0; + + if (atomic_read(&intf->event_waiters)) { + intf->ticks_to_req_ev--; + if (intf->ticks_to_req_ev == 0) { + ipmi_request_event(intf); + intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME; + } + lnt++; + } - ipmi_timeout_handler(IPMI_TIMEOUT_TIME); + lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME); - mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); + lnt = !!lnt; + if (lnt != intf->last_needs_timer && + intf->handlers->set_need_watch) + intf->handlers->set_need_watch(intf->send_info, lnt); + intf->last_needs_timer = lnt; + + nt += lnt; + } + rcu_read_unlock(); + + if (nt) + mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); } +static void need_waiter(ipmi_smi_t intf) +{ + /* Racy, but worst case we start the timer twice. */ + if (!timer_pending(&ipmi_timer)) + mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); +} static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0); static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 25a1436a4291..444ea548dfe3 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -257,6 +257,9 @@ struct smi_info { /* Used to gracefully stop the timer without race conditions. */ atomic_t stop_operation; + /* Are we waiting for the events, pretimeouts, received msgs? */ + atomic_t need_watch; + /* * The driver will disable interrupts when it gets into a * situation where it cannot handle messages due to lack of @@ -862,6 +865,19 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, return si_sm_result; } +static void check_start_timer_thread(struct smi_info *smi_info) +{ + if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) { + smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); + + if (smi_info->thread) + wake_up_process(smi_info->thread); + + start_next_msg(smi_info); + smi_event_handler(smi_info, 0); + } +} + static void sender(void *send_info, struct ipmi_smi_msg *msg, int priority) @@ -915,15 +931,7 @@ static void sender(void *send_info, else list_add_tail(&msg->link, &smi_info->xmit_msgs); - if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) { - smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); - - if (smi_info->thread) - wake_up_process(smi_info->thread); - - start_next_msg(smi_info); - smi_event_handler(smi_info, 0); - } + check_start_timer_thread(smi_info); spin_unlock_irqrestore(&smi_info->si_lock, flags); } @@ -1023,9 +1031,15 @@ static int ipmi_thread(void *data) ; /* do nothing */ else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait) schedule(); - else if (smi_result == SI_SM_IDLE) - schedule_timeout_interruptible(100); - else + else if (smi_result == SI_SM_IDLE) { + if (atomic_read(&smi_info->need_watch)) { + schedule_timeout_interruptible(100); + } else { + /* Wait to be woken up when we are needed. */ + __set_current_state(TASK_INTERRUPTIBLE); + schedule(); + } + } else schedule_timeout_interruptible(1); } return 0; @@ -1061,6 +1075,17 @@ static void request_events(void *send_info) atomic_set(&smi_info->req_events, 1); } +static void set_need_watch(void *send_info, int enable) +{ + struct smi_info *smi_info = send_info; + unsigned long flags; + + atomic_set(&smi_info->need_watch, enable); + spin_lock_irqsave(&smi_info->si_lock, flags); + check_start_timer_thread(smi_info); + spin_unlock_irqrestore(&smi_info->si_lock, flags); +} + static int initialized; static void smi_timeout(unsigned long data) @@ -1212,6 +1237,7 @@ static struct ipmi_smi_handlers handlers = { .get_smi_info = get_smi_info, .sender = sender, .request_events = request_events, + .set_need_watch = set_need_watch, .set_maintenance_mode = set_maintenance_mode, .set_run_to_completion = set_run_to_completion, .poll = poll, @@ -3352,6 +3378,7 @@ static int try_smi_init(struct smi_info *new_smi) new_smi->interrupt_disabled = 1; atomic_set(&new_smi->stop_operation, 0); + atomic_set(&new_smi->need_watch, 0); new_smi->intf_num = smi_num; smi_num++; diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h index 1f9f56e28851..76d2acbfa7c6 100644 --- a/include/linux/ipmi.h +++ b/include/linux/ipmi.h @@ -237,7 +237,7 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode); * The first user that sets this to TRUE will receive all events that * have been queued while no one was waiting for events. */ -int ipmi_set_gets_events(ipmi_user_t user, int val); +int ipmi_set_gets_events(ipmi_user_t user, bool val); /* * Called when a new SMI is registered. This will also be called on diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 8ea3fe0b9759..2a7ff302d990 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h @@ -109,6 +109,13 @@ struct ipmi_smi_handlers { events from the BMC we are attached to. */ void (*request_events)(void *send_info); + /* Called by the upper layer when some user requires that the + interface watch for events, received messages, watchdog + pretimeouts, or not. Used by the SMI to know if it should + watch for these. This may be NULL if the SMI does not + implement it. */ + void (*set_need_watch)(void *send_info, int enable); + /* Called when the interface should go into "run to completion" mode. If this call sets the value to true, the interface should make sure that all messages are flushed -- GitLab From 7aefac26fc67158cb8826a5f5bfc2a5086a7d962 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Mon, 14 Apr 2014 09:46:56 -0500 Subject: [PATCH 463/797] ipmi: boolify some things Convert some ints to bools. Signed-off-by: Corey Minyard Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 22 ++++++------- drivers/char/ipmi/ipmi_si_intf.c | 50 ++++++++++++++--------------- include/linux/ipmi_smi.h | 6 ++-- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 872c4ec79bf4..e6db9381b2c7 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -94,8 +94,8 @@ static struct proc_dir_entry *proc_ipmi_root; struct ipmi_user { struct list_head link; - /* Set to "0" when the user is destroyed. */ - int valid; + /* Set to false when the user is destroyed. */ + bool valid; struct kref refcount; @@ -413,7 +413,7 @@ struct ipmi_smi { /* For handling of maintenance mode. */ int maintenance_mode; - int maintenance_mode_enable; + bool maintenance_mode_enable; int auto_maintenance_timeout; spinlock_t maintenance_mode_lock; /* Used in a timer... */ @@ -980,7 +980,7 @@ int ipmi_create_user(unsigned int if_num, */ mutex_unlock(&ipmi_interfaces_mutex); - new_user->valid = 1; + new_user->valid = true; spin_lock_irqsave(&intf->seq_lock, flags); list_add_rcu(&new_user->link, &intf->users); spin_unlock_irqrestore(&intf->seq_lock, flags); @@ -1042,7 +1042,7 @@ int ipmi_destroy_user(ipmi_user_t user) struct cmd_rcvr *rcvr; struct cmd_rcvr *rcvrs = NULL; - user->valid = 0; + user->valid = false; if (user->handler->ipmi_watchdog_pretimeout) atomic_dec(&intf->event_waiters); @@ -1184,25 +1184,23 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode) if (intf->maintenance_mode != mode) { switch (mode) { case IPMI_MAINTENANCE_MODE_AUTO: - intf->maintenance_mode = mode; intf->maintenance_mode_enable = (intf->auto_maintenance_timeout > 0); break; case IPMI_MAINTENANCE_MODE_OFF: - intf->maintenance_mode = mode; - intf->maintenance_mode_enable = 0; + intf->maintenance_mode_enable = false; break; case IPMI_MAINTENANCE_MODE_ON: - intf->maintenance_mode = mode; - intf->maintenance_mode_enable = 1; + intf->maintenance_mode_enable = true; break; default: rv = -EINVAL; goto out_unlock; } + intf->maintenance_mode = mode; maintenance_mode_update(intf); } @@ -1578,7 +1576,7 @@ static int i_ipmi_request(ipmi_user_t user, = IPMI_MAINTENANCE_MODE_TIMEOUT; if (!intf->maintenance_mode && !intf->maintenance_mode_enable) { - intf->maintenance_mode_enable = 1; + intf->maintenance_mode_enable = true; maintenance_mode_update(intf); } spin_unlock_irqrestore(&intf->maintenance_mode_lock, @@ -4129,7 +4127,7 @@ static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period) -= timeout_period; if (!intf->maintenance_mode && (intf->auto_maintenance_timeout <= 0)) { - intf->maintenance_mode_enable = 0; + intf->maintenance_mode_enable = false; maintenance_mode_update(intf); } } diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 444ea548dfe3..1c4bb4f6ce93 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -217,7 +217,7 @@ struct smi_info { unsigned char msg_flags; /* Does the BMC have an event buffer? */ - char has_event_buffer; + bool has_event_buffer; /* * If set to true, this will request events the next time the @@ -230,7 +230,7 @@ struct smi_info { * call. Generally used after a panic to make sure stuff goes * out. */ - int run_to_completion; + bool run_to_completion; /* The I/O port of an SI interface. */ int port; @@ -266,7 +266,7 @@ struct smi_info { * memory. Once that situation clears up, it will re-enable * interrupts. */ - int interrupt_disabled; + bool interrupt_disabled; /* From the get device id response... */ struct ipmi_device_id device_id; @@ -279,7 +279,7 @@ struct smi_info { * True if we allocated the device, false if it came from * someplace else (like PCI). */ - int dev_registered; + bool dev_registered; /* Slave address, could be reported from DMI. */ unsigned char slave_addr; @@ -303,19 +303,19 @@ struct smi_info { static int force_kipmid[SI_MAX_PARMS]; static int num_force_kipmid; #ifdef CONFIG_PCI -static int pci_registered; +static bool pci_registered; #endif #ifdef CONFIG_ACPI -static int pnp_registered; +static bool pnp_registered; #endif #ifdef CONFIG_PARISC -static int parisc_registered; +static bool parisc_registered; #endif static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; static int num_max_busy_us; -static int unload_when_empty = 1; +static bool unload_when_empty = true; static int add_smi(struct smi_info *smi); static int try_smi_init(struct smi_info *smi); @@ -457,7 +457,7 @@ static inline void disable_si_irq(struct smi_info *smi_info) { if ((smi_info->irq) && (!smi_info->interrupt_disabled)) { start_disable_irq(smi_info); - smi_info->interrupt_disabled = 1; + smi_info->interrupt_disabled = true; if (!atomic_read(&smi_info->stop_operation)) smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES); } @@ -467,7 +467,7 @@ static inline void enable_si_irq(struct smi_info *smi_info) { if ((smi_info->irq) && (smi_info->interrupt_disabled)) { start_enable_irq(smi_info); - smi_info->interrupt_disabled = 0; + smi_info->interrupt_disabled = false; } } @@ -712,7 +712,7 @@ static void handle_transaction_done(struct smi_info *smi_info) dev_warn(smi_info->dev, "Maybe ok, but ipmi might run very slowly.\n"); } else - smi_info->interrupt_disabled = 0; + smi_info->interrupt_disabled = false; smi_info->si_state = SI_NORMAL; break; } @@ -935,7 +935,7 @@ static void sender(void *send_info, spin_unlock_irqrestore(&smi_info->si_lock, flags); } -static void set_run_to_completion(void *send_info, int i_run_to_completion) +static void set_run_to_completion(void *send_info, bool i_run_to_completion) { struct smi_info *smi_info = send_info; enum si_sm_result result; @@ -1050,7 +1050,7 @@ static void poll(void *send_info) { struct smi_info *smi_info = send_info; unsigned long flags = 0; - int run_to_completion = smi_info->run_to_completion; + bool run_to_completion = smi_info->run_to_completion; /* * Make sure there is some delay in the poll loop so we can @@ -1075,7 +1075,7 @@ static void request_events(void *send_info) atomic_set(&smi_info->req_events, 1); } -static void set_need_watch(void *send_info, int enable) +static void set_need_watch(void *send_info, bool enable) { struct smi_info *smi_info = send_info; unsigned long flags; @@ -1223,7 +1223,7 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data) return 0; } -static void set_maintenance_mode(void *send_info, int enable) +static void set_maintenance_mode(void *send_info, bool enable) { struct smi_info *smi_info = send_info; @@ -1364,7 +1364,7 @@ module_param_array(force_kipmid, int, &num_force_kipmid, 0); MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or" " disabled(0). Normally the IPMI driver auto-detects" " this, but the value may be overridden by this parm."); -module_param(unload_when_empty, int, 0); +module_param(unload_when_empty, bool, 0); MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are" " specified or found, default is 1. Setting to 0" " is useful for hot add of devices using hotmod."); @@ -3372,11 +3372,11 @@ static int try_smi_init(struct smi_info *new_smi) INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); new_smi->curr_msg = NULL; atomic_set(&new_smi->req_events, 0); - new_smi->run_to_completion = 0; + new_smi->run_to_completion = false; for (i = 0; i < SI_NUM_STATS; i++) atomic_set(&new_smi->stats[i], 0); - new_smi->interrupt_disabled = 1; + new_smi->interrupt_disabled = true; atomic_set(&new_smi->stop_operation, 0); atomic_set(&new_smi->need_watch, 0); new_smi->intf_num = smi_num; @@ -3384,7 +3384,7 @@ static int try_smi_init(struct smi_info *new_smi) rv = try_enable_event_buffer(new_smi); if (rv == 0) - new_smi->has_event_buffer = 1; + new_smi->has_event_buffer = true; /* * Start clearing the flags before we enable interrupts or the @@ -3418,7 +3418,7 @@ static int try_smi_init(struct smi_info *new_smi) rv); goto out_err; } - new_smi->dev_registered = 1; + new_smi->dev_registered = true; } rv = ipmi_register_smi(&handlers, @@ -3467,7 +3467,7 @@ static int try_smi_init(struct smi_info *new_smi) wait_for_timer_and_thread(new_smi); out_err: - new_smi->interrupt_disabled = 1; + new_smi->interrupt_disabled = true; if (new_smi->intf) { ipmi_unregister_smi(new_smi->intf); @@ -3503,7 +3503,7 @@ static int try_smi_init(struct smi_info *new_smi) if (new_smi->dev_registered) { platform_device_unregister(new_smi->pdev); - new_smi->dev_registered = 0; + new_smi->dev_registered = false; } return rv; @@ -3558,14 +3558,14 @@ static int init_ipmi_si(void) printk(KERN_ERR PFX "Unable to register " "PCI driver: %d\n", rv); else - pci_registered = 1; + pci_registered = true; } #endif #ifdef CONFIG_ACPI if (si_tryacpi) { pnp_register_driver(&ipmi_pnp_driver); - pnp_registered = 1; + pnp_registered = true; } #endif @@ -3581,7 +3581,7 @@ static int init_ipmi_si(void) #ifdef CONFIG_PARISC register_parisc_driver(&ipmi_parisc_driver); - parisc_registered = 1; + parisc_registered = true; /* poking PC IO addresses will crash machine, don't do it */ si_trydefaults = 0; #endif diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 2a7ff302d990..bd349240d50e 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h @@ -114,14 +114,14 @@ struct ipmi_smi_handlers { pretimeouts, or not. Used by the SMI to know if it should watch for these. This may be NULL if the SMI does not implement it. */ - void (*set_need_watch)(void *send_info, int enable); + void (*set_need_watch)(void *send_info, bool enable); /* Called when the interface should go into "run to completion" mode. If this call sets the value to true, the interface should make sure that all messages are flushed out and that none are pending, and any new requests are run to completion immediately. */ - void (*set_run_to_completion)(void *send_info, int run_to_completion); + void (*set_run_to_completion)(void *send_info, bool run_to_completion); /* Called to poll for work to do. This is so upper layers can poll for operations during things like crash dumps. */ @@ -132,7 +132,7 @@ struct ipmi_smi_handlers { setting. The message handler does the mode handling. Note that this is called from interrupt context, so it cannot block. */ - void (*set_maintenance_mode)(void *send_info, int enable); + void (*set_maintenance_mode)(void *send_info, bool enable); /* Tell the handler that we are using it/not using it. The message handler get the modules that this handler belongs -- GitLab From 01f8fa4f01d8362358eb90e412bd7ae18a3ec1ad Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Apr 2014 14:36:44 +0000 Subject: [PATCH 464/797] genirq: Allow forcing cpu affinity of interrupts The current implementation of irq_set_affinity() refuses rightfully to route an interrupt to an offline cpu. But there is a special case, where this is actually desired. Some of the ARM SoCs have per cpu timers which require setting the affinity during cpu startup where the cpu is not yet in the online mask. If we can't do that, then the local timer interrupt for the about to become online cpu is routed to some random online cpu. The developers of the affected machines tried to work around that issue, but that results in a massive mess in that timer code. We have a yet unused argument in the set_affinity callbacks of the irq chips, which I added back then for a similar reason. It was never required so it got not used. But I'm happy that I never removed it. That allows us to implement a sane handling of the above scenario. So the affected SoC drivers can add the required force handling to their interrupt chip, switch the timer code to irq_force_affinity() and things just work. This does not affect any existing user of irq_set_affinity(). Tagged for stable to allow a simple fix of the affected SoC clock event drivers. Reported-and-tested-by: Krzysztof Kozlowski Signed-off-by: Thomas Gleixner Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143315.717251504@linutronix.de Signed-off-by: Thomas Gleixner --- arch/mips/cavium-octeon/octeon-irq.c | 2 +- include/linux/interrupt.h | 35 +++++++++++++++++++++++++++- include/linux/irq.h | 3 ++- kernel/irq/manage.c | 17 +++++--------- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index c2bb4f896ce7..3aa5b46b2d40 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -635,7 +635,7 @@ static void octeon_irq_cpu_offline_ciu(struct irq_data *data) cpumask_clear(&new_affinity); cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity); } - __irq_set_affinity_locked(data, &new_affinity); + irq_set_affinity_locked(data, &new_affinity, false); } static int octeon_irq_ciu_set_affinity(struct irq_data *data, diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c7bfac1c4a7b..8834a7e5b944 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -203,7 +203,40 @@ static inline int check_wakeup_irqs(void) { return 0; } extern cpumask_var_t irq_default_affinity; -extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask); +/* Internal implementation. Use the helpers below */ +extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask, + bool force); + +/** + * irq_set_affinity - Set the irq affinity of a given irq + * @irq: Interrupt to set affinity + * @mask: cpumask + * + * Fails if cpumask does not contain an online CPU + */ +static inline int +irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) +{ + return __irq_set_affinity(irq, cpumask, false); +} + +/** + * irq_force_affinity - Force the irq affinity of a given irq + * @irq: Interrupt to set affinity + * @mask: cpumask + * + * Same as irq_set_affinity, but without checking the mask against + * online cpus. + * + * Solely for low level cpu hotplug code, where we need to make per + * cpu interrupts affine before the cpu becomes online. + */ +static inline int +irq_force_affinity(unsigned int irq, const struct cpumask *cpumask) +{ + return __irq_set_affinity(irq, cpumask, true); +} + extern int irq_can_set_affinity(unsigned int irq); extern int irq_select_affinity(unsigned int irq); diff --git a/include/linux/irq.h b/include/linux/irq.h index d278838908cb..10a0b1ac4ea0 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -394,7 +394,8 @@ extern void remove_percpu_irq(unsigned int irq, struct irqaction *act); extern void irq_cpu_online(void); extern void irq_cpu_offline(void); -extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask); +extern int irq_set_affinity_locked(struct irq_data *data, + const struct cpumask *cpumask, bool force); #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ) void irq_move_irq(struct irq_data *data); diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 2486a4c1a710..d34131ca372b 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -180,7 +180,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, struct irq_chip *chip = irq_data_get_irq_chip(data); int ret; - ret = chip->irq_set_affinity(data, mask, false); + ret = chip->irq_set_affinity(data, mask, force); switch (ret) { case IRQ_SET_MASK_OK: cpumask_copy(data->affinity, mask); @@ -192,7 +192,8 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, return ret; } -int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) +int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask, + bool force) { struct irq_chip *chip = irq_data_get_irq_chip(data); struct irq_desc *desc = irq_data_to_desc(data); @@ -202,7 +203,7 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) return -EINVAL; if (irq_can_move_pcntxt(data)) { - ret = irq_do_set_affinity(data, mask, false); + ret = irq_do_set_affinity(data, mask, force); } else { irqd_set_move_pending(data); irq_copy_pending(desc, mask); @@ -217,13 +218,7 @@ int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask) return ret; } -/** - * irq_set_affinity - Set the irq affinity of a given irq - * @irq: Interrupt to set affinity - * @mask: cpumask - * - */ -int irq_set_affinity(unsigned int irq, const struct cpumask *mask) +int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force) { struct irq_desc *desc = irq_to_desc(irq); unsigned long flags; @@ -233,7 +228,7 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *mask) return -EINVAL; raw_spin_lock_irqsave(&desc->lock, flags); - ret = __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask); + ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force); raw_spin_unlock_irqrestore(&desc->lock, flags); return ret; } -- GitLab From ffde1de64012c406dfdda8690918248b472f24e4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Apr 2014 14:36:44 +0000 Subject: [PATCH 465/797] irqchip: Gic: Support forced affinity setting To support the affinity setting of per cpu timers in the early startup of a not yet online cpu, implement the force logic, which disables the cpu online check. Tagged for stable to allow a simple fix of the affected SoC clock event drivers. Signed-off-by: Thomas Gleixner Tested-by: Krzysztof Kozlowski Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143315.916984416@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-gic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4300b6606f5e..57d165e026f4 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -246,10 +246,14 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); - unsigned int shift = (gic_irq(d) % 4) * 8; - unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); + unsigned int cpu, shift = (gic_irq(d) % 4) * 8; u32 val, mask, bit; + if (!force) + cpu = cpumask_any_and(mask_val, cpu_online_mask); + else + cpu = cpumask_first(mask_val); + if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) return -EINVAL; -- GitLab From 30ccf03b4a6a2102a2219058bdc6d779dc637dd7 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 16 Apr 2014 14:36:45 +0000 Subject: [PATCH 466/797] clocksource: Exynos_mct: Use irq_force_affinity() in cpu bringup The starting cpu is not yet in the online mask so irq_set_affinity() fails which results in per cpu timers for this cpu ending up on some other online cpu, ususally cpu 0. Use irq_force_affinity() which disables the online mask check and makes things work. Signed-off-by: Thomas Gleixner Tested-by: Krzysztof Kozlowski Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143316.106665251@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/clocksource/exynos_mct.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index a6ee6d7cd63f..b2d416368711 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -430,6 +430,7 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->irq); return -EIO; } + irq_force_affinity(mct_irqs[MCT_L0_IRQ + cpu], cpumask_of(cpu)); } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } @@ -450,7 +451,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { struct mct_clock_event_device *mevt; - unsigned int cpu; /* * Grab cpu pointer in each case to avoid spurious @@ -461,12 +461,6 @@ static int exynos4_mct_cpu_notify(struct notifier_block *self, mevt = this_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_setup(&mevt->evt); break; - case CPU_ONLINE: - cpu = (unsigned long)hcpu; - if (mct_int_type == MCT_INT_SPI) - irq_set_affinity(mct_irqs[MCT_L0_IRQ + cpu], - cpumask_of(cpu)); - break; case CPU_DYING: mevt = this_cpu_ptr(&percpu_mct_tick); exynos4_local_timer_stop(&mevt->evt); -- GitLab From 8db6e5104b77de5d0b7002b95069da0992a34be9 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 16 Apr 2014 14:36:45 +0000 Subject: [PATCH 467/797] clocksource: Exynos_mct: Register clock event after request_irq() After hotplugging CPU1 the first call of interrupt handler for CPU1 oneshot timer was called on CPU0 because it fired before setting IRQ affinity. Affected are SoCs where Multi Core Timer interrupts are shared (SPI), e.g. Exynos 4210. During setup of the MCT timers the clock event device should be registered after setting the affinity for interrupt. This will prevent starting the timer too early. Signed-off-by: Krzysztof Kozlowski Signed-off-by: Thomas Gleixner Cc: Kyungmin Park Cc: Marek Szyprowski Cc: Bartlomiej Zolnierkiewicz Cc: Tomasz Figa , Cc: Daniel Lezcano , Cc: Kukjin Kim Cc: linux-arm-kernel@lists.infradead.org, Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140416143316.299247848@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/clocksource/exynos_mct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index b2d416368711..acf5a329d538 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c @@ -416,8 +416,6 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) evt->set_mode = exynos4_tick_set_mode; evt->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; evt->rating = 450; - clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), - 0xf, 0x7fffffff); exynos4_mct_write(TICK_BASE_CNT, mevt->base + MCT_L_TCNTB_OFFSET); @@ -434,6 +432,8 @@ static int exynos4_local_timer_setup(struct clock_event_device *evt) } else { enable_percpu_irq(mct_irqs[MCT_L0_IRQ], 0); } + clockevents_config_and_register(evt, clk_rate / (TICK_BASE_CNT + 1), + 0xf, 0x7fffffff); return 0; } -- GitLab From 9a11843987b29b7b7eff650bff7d5731ba5117d5 Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Tue, 15 Apr 2014 23:18:37 +0200 Subject: [PATCH 468/797] drm/nouveau/bios: fix a bit shift error introduced by 457e77b Commit 457e77b26428ab4a24998eecfb99f27fa4195397 added two checks applied to a value received from nv_rd32(bios, 0x619f04). But after this new piece of code is executed, the addr local variable does not hold the same value it used to hold before the commit. Here is what is was assigned in the original code: (u64)(nv_rd32(bios, 0x619f04) & 0xffffff00) << 8 in the committed code it ends up with this value: (u64)(nv_rd32(bios, 0x619f04) >> 8) << 8 These expressions are obviously not equivalent. My Nvidia video card does not show anything on the display when I boot a kernel containing this commit. The patch fixes the code so that the new checks are still done, but the side effect of an incorrect addr value is gone. Cc: Ben Skeggs Cc: Dave Airlie Cc: Andrew Morton Signed-off-by: Sergei Antonov Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/core/subdev/bios/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index e9df94f96d78..fb0b6b2d1427 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c @@ -109,7 +109,7 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios) return; } - addr = (u64)(addr >> 8) << 8; + addr = (addr & 0xffffff00) << 8; if (!addr) { addr = (u64)nv_rd32(bios, 0x001700) << 16; addr += 0xf0000; -- GitLab From a82049b1f1aeb02818092455cd43134ef83d81ea Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 16 Apr 2014 19:42:24 +1000 Subject: [PATCH 469/797] drm/ast: fix value check in cbr_scan2 this is a typo vs the ums driver, fix to check correct value. Found initially by Coverity. Reported-by: Daniel Vetter Signed-off-by: Dave Airlie --- drivers/gpu/drm/ast/ast_post.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 977cfb35837a..635f6ffc27c2 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -572,7 +572,7 @@ static u32 cbr_scan2(struct ast_private *ast) for (loop = 0; loop < CBR_PASSNUM2; loop++) { if ((data = cbr_test2(ast)) != 0) { data2 &= data; - if (!data) + if (!data2) return 0; break; } -- GitLab From b6ccd7b9873dc46becd11838c885d5c783784156 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 15 Apr 2014 10:02:43 +0200 Subject: [PATCH 470/797] drm/plane-helper: Don't fake-implement primary plane disabling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After thinking about this topic a bit more I've reached the conclusion that implementing this doesn't make sense: - The locking is all wrong: set_config(NULL) will also unlink encoders and connectors, but those links are protected with the mode_config mutex. In the ->disable_plane callback we only hold all modeset locks, but eventually we want to switch to just grabbing the per-crtc (and maybe per-plane) locks as needed, maybe based on ww_mutexes. Having a callback which absolutely needs all modeset locks is bad for this conversion. Note that the same isn't true for the provided ->update_plane since we've audited the crtc helpers to make sure that not encoder or connector links are changed. - There's no way to re-enable the plane with an ->update_plane: The connectors/encoder links are lost and so we can't re-enable the CRTC. Even without that issue the driver might have reassigned some shared resources (as opposed to e.g. DPMS off, where drivers are not allowed to do that to make sure the CRTC can be enabled again). - The semantics don't make much sense: Userspace asked to scan out black (or some other color if the driver supports a background color), not that the screen be disabled. - Implementing proper primary plane support (i.e. actually disabling the primary plane without disabling the CRTC) is really simple, at least if all the hw needs is flipping a bit. The big task is auditing all the interactions with other ioctls when the CRTC is on but there's no primary plane (e.g. pageflips). And some of that work still needs to be done. Cc: Matt Roper Signed-off-by: Daniel Vetter Reviewed-by: Ville Syrjälä Reviewed-by: Matt Roper Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_plane_helper.c | 33 +++++------------------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index e768d35ff22e..d2b1c03b3d71 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -203,9 +203,9 @@ EXPORT_SYMBOL(drm_primary_helper_update); * * Provides a default plane disable handler for primary planes. This is handler * is called in response to a userspace SetPlane operation on the plane with a - * NULL framebuffer parameter. We call the driver's modeset handler with a NULL - * framebuffer to disable the CRTC if no other planes are currently enabled. - * If other planes are still enabled on the same CRTC, we return -EBUSY. + * NULL framebuffer parameter. It unconditionally fails the disable call with + * -EINVAL the only way to disable the primary plane without driver support is + * to disable the entier CRTC. Which does not match the plane ->disable hook. * * Note that some hardware may be able to disable the primary plane without * disabling the whole CRTC. Drivers for such hardware should provide their @@ -214,34 +214,11 @@ EXPORT_SYMBOL(drm_primary_helper_update); * disabled primary plane). * * RETURNS: - * Zero on success, error code on failure + * Unconditionally returns -EINVAL. */ int drm_primary_helper_disable(struct drm_plane *plane) { - struct drm_plane *p; - struct drm_mode_set set = { - .crtc = plane->crtc, - .fb = NULL, - }; - - if (plane->crtc == NULL || plane->fb == NULL) - /* Already disabled */ - return 0; - - list_for_each_entry(p, &plane->dev->mode_config.plane_list, head) - if (p != plane && p->fb) { - DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n"); - return -EBUSY; - } - - /* - * N.B. We call set_config() directly here rather than - * drm_mode_set_config_internal() since drm_mode_setplane() already - * handles the basic refcounting and we don't need the special - * cross-CRTC refcounting (no chance of stealing connectors from - * other CRTC's with this update). - */ - return plane->crtc->funcs->set_config(&set); + return -EINVAL; } EXPORT_SYMBOL(drm_primary_helper_disable); -- GitLab From 8d754544202c0e4ef02e9c1abdf379bcf7ef9384 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 10 Apr 2014 10:51:11 +0200 Subject: [PATCH 471/797] drm: Split out drm_probe_helper.c from drm_crtc_helper.c This is leftover stuff from my previous doc round which I kinda wanted to do but didn't yet due to rebase hell. The modeset helpers and the probing helpers a independent and e.g. i915 uses the probing stuff but has its own modeset infrastructure. It hence makes to split this up. While at it add a DOC: comment for the probing libraray. It would be rather neat to pull some of the DocBook documenting these two helpers into in-line DOC: comments. But unfortunately kerneldoc doesn't support markdown or something similar to make nice-looking documentation, so the current state is better. Signed-off-by: Daniel Vetter Signed-off-by: Dave Airlie --- Documentation/DocBook/drm.tmpl | 5 + drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_crtc_helper.c | 370 ------------------------- drivers/gpu/drm/drm_probe_helper.c | 426 +++++++++++++++++++++++++++++ include/drm/drm_crtc_helper.h | 6 +- 5 files changed, 437 insertions(+), 372 deletions(-) create mode 100644 drivers/gpu/drm/drm_probe_helper.c diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 702c4474919c..677a02553ec0 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -2285,6 +2285,11 @@ void intel_crt_init(struct drm_device *dev) Modeset Helper Functions Reference !Edrivers/gpu/drm/drm_crtc_helper.c + + + Output Probing Helper Functions Reference +!Pdrivers/gpu/drm/drm_probe_helper.c output probing helper overview +!Edrivers/gpu/drm/drm_probe_helper.c fbdev Helper Functions Reference diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 9d25dbbe6771..48e38ba22783 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o drm-usb-y := drm_usb.o -drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o +drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index c43825e8f5c1..df281b54db01 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -72,147 +72,6 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev) } EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head); -static bool drm_kms_helper_poll = true; -module_param_named(poll, drm_kms_helper_poll, bool, 0600); - -static void drm_mode_validate_flag(struct drm_connector *connector, - int flags) -{ - struct drm_display_mode *mode; - - if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE | - DRM_MODE_FLAG_3D_MASK)) - return; - - list_for_each_entry(mode, &connector->modes, head) { - if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && - !(flags & DRM_MODE_FLAG_INTERLACE)) - mode->status = MODE_NO_INTERLACE; - if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) && - !(flags & DRM_MODE_FLAG_DBLSCAN)) - mode->status = MODE_NO_DBLESCAN; - if ((mode->flags & DRM_MODE_FLAG_3D_MASK) && - !(flags & DRM_MODE_FLAG_3D_MASK)) - mode->status = MODE_NO_STEREO; - } - - return; -} - -/** - * drm_helper_probe_single_connector_modes - get complete set of display modes - * @connector: connector to probe - * @maxX: max width for modes - * @maxY: max height for modes - * - * Based on the helper callbacks implemented by @connector try to detect all - * valid modes. Modes will first be added to the connector's probed_modes list, - * then culled (based on validity and the @maxX, @maxY parameters) and put into - * the normal modes list. - * - * Intended to be use as a generic implementation of the ->fill_modes() - * @connector vfunc for drivers that use the crtc helpers for output mode - * filtering and detection. - * - * Returns: - * The number of modes found on @connector. - */ -int drm_helper_probe_single_connector_modes(struct drm_connector *connector, - uint32_t maxX, uint32_t maxY) -{ - struct drm_device *dev = connector->dev; - struct drm_display_mode *mode; - struct drm_connector_helper_funcs *connector_funcs = - connector->helper_private; - int count = 0; - int mode_flags = 0; - bool verbose_prune = true; - - WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, - drm_get_connector_name(connector)); - /* set all modes to the unverified state */ - list_for_each_entry(mode, &connector->modes, head) - mode->status = MODE_UNVERIFIED; - - if (connector->force) { - if (connector->force == DRM_FORCE_ON) - connector->status = connector_status_connected; - else - connector->status = connector_status_disconnected; - if (connector->funcs->force) - connector->funcs->force(connector); - } else { - connector->status = connector->funcs->detect(connector, true); - } - - /* Re-enable polling in case the global poll config changed. */ - if (drm_kms_helper_poll != dev->mode_config.poll_running) - drm_kms_helper_poll_enable(dev); - - dev->mode_config.poll_running = drm_kms_helper_poll; - - if (connector->status == connector_status_disconnected) { - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", - connector->base.id, drm_get_connector_name(connector)); - drm_mode_connector_update_edid_property(connector, NULL); - verbose_prune = false; - goto prune; - } - -#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE - count = drm_load_edid_firmware(connector); - if (count == 0) -#endif - count = (*connector_funcs->get_modes)(connector); - - if (count == 0 && connector->status == connector_status_connected) - count = drm_add_modes_noedid(connector, 1024, 768); - if (count == 0) - goto prune; - - drm_mode_connector_list_update(connector); - - if (maxX && maxY) - drm_mode_validate_size(dev, &connector->modes, maxX, maxY); - - if (connector->interlace_allowed) - mode_flags |= DRM_MODE_FLAG_INTERLACE; - if (connector->doublescan_allowed) - mode_flags |= DRM_MODE_FLAG_DBLSCAN; - if (connector->stereo_allowed) - mode_flags |= DRM_MODE_FLAG_3D_MASK; - drm_mode_validate_flag(connector, mode_flags); - - list_for_each_entry(mode, &connector->modes, head) { - if (mode->status == MODE_OK) - mode->status = connector_funcs->mode_valid(connector, - mode); - } - -prune: - drm_mode_prune_invalid(dev, &connector->modes, verbose_prune); - - if (list_empty(&connector->modes)) - return 0; - - list_for_each_entry(mode, &connector->modes, head) - mode->vrefresh = drm_mode_vrefresh(mode); - - drm_mode_sort(&connector->modes); - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, - drm_get_connector_name(connector)); - list_for_each_entry(mode, &connector->modes, head) { - drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); - drm_mode_debug_printmodeline(mode); - } - - return count; -} -EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); - /** * drm_helper_encoder_in_use - check if a given encoder is in use * @encoder: encoder to check @@ -1020,232 +879,3 @@ void drm_helper_resume_force_mode(struct drm_device *dev) drm_modeset_unlock_all(dev); } EXPORT_SYMBOL(drm_helper_resume_force_mode); - -/** - * drm_kms_helper_hotplug_event - fire off KMS hotplug events - * @dev: drm_device whose connector state changed - * - * This function fires off the uevent for userspace and also calls the - * output_poll_changed function, which is most commonly used to inform the fbdev - * emulation code and allow it to update the fbcon output configuration. - * - * Drivers should call this from their hotplug handling code when a change is - * detected. Note that this function does not do any output detection of its - * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the - * driver already. - * - * This function must be called from process context with no mode - * setting locks held. - */ -void drm_kms_helper_hotplug_event(struct drm_device *dev) -{ - /* send a uevent + call fbdev */ - drm_sysfs_hotplug_event(dev); - if (dev->mode_config.funcs->output_poll_changed) - dev->mode_config.funcs->output_poll_changed(dev); -} -EXPORT_SYMBOL(drm_kms_helper_hotplug_event); - -#define DRM_OUTPUT_POLL_PERIOD (10*HZ) -static void output_poll_execute(struct work_struct *work) -{ - struct delayed_work *delayed_work = to_delayed_work(work); - struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); - struct drm_connector *connector; - enum drm_connector_status old_status; - bool repoll = false, changed = false; - - if (!drm_kms_helper_poll) - return; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - - /* Ignore forced connectors. */ - if (connector->force) - continue; - - /* Ignore HPD capable connectors and connectors where we don't - * want any hotplug detection at all for polling. */ - if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD) - continue; - - repoll = true; - - old_status = connector->status; - /* if we are connected and don't want to poll for disconnect - skip it */ - if (old_status == connector_status_connected && - !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT)) - continue; - - connector->status = connector->funcs->detect(connector, false); - if (old_status != connector->status) { - const char *old, *new; - - old = drm_get_connector_status_name(old_status); - new = drm_get_connector_status_name(connector->status); - - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] " - "status updated from %s to %s\n", - connector->base.id, - drm_get_connector_name(connector), - old, new); - - changed = true; - } - } - - mutex_unlock(&dev->mode_config.mutex); - - if (changed) - drm_kms_helper_hotplug_event(dev); - - if (repoll) - schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); -} - -/** - * drm_kms_helper_poll_disable - disable output polling - * @dev: drm_device - * - * This function disables the output polling work. - * - * Drivers can call this helper from their device suspend implementation. It is - * not an error to call this even when output polling isn't enabled or arlready - * disabled. - */ -void drm_kms_helper_poll_disable(struct drm_device *dev) -{ - if (!dev->mode_config.poll_enabled) - return; - cancel_delayed_work_sync(&dev->mode_config.output_poll_work); -} -EXPORT_SYMBOL(drm_kms_helper_poll_disable); - -/** - * drm_kms_helper_poll_enable - re-enable output polling. - * @dev: drm_device - * - * This function re-enables the output polling work. - * - * Drivers can call this helper from their device resume implementation. It is - * an error to call this when the output polling support has not yet been set - * up. - */ -void drm_kms_helper_poll_enable(struct drm_device *dev) -{ - bool poll = false; - struct drm_connector *connector; - - if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) - return; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | - DRM_CONNECTOR_POLL_DISCONNECT)) - poll = true; - } - - if (poll) - schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD); -} -EXPORT_SYMBOL(drm_kms_helper_poll_enable); - -/** - * drm_kms_helper_poll_init - initialize and enable output polling - * @dev: drm_device - * - * This function intializes and then also enables output polling support for - * @dev. Drivers which do not have reliable hotplug support in hardware can use - * this helper infrastructure to regularly poll such connectors for changes in - * their connection state. - * - * Drivers can control which connectors are polled by setting the - * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On - * connectors where probing live outputs can result in visual distortion drivers - * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this. - * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are - * completely ignored by the polling logic. - * - * Note that a connector can be both polled and probed from the hotplug handler, - * in case the hotplug interrupt is known to be unreliable. - */ -void drm_kms_helper_poll_init(struct drm_device *dev) -{ - INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute); - dev->mode_config.poll_enabled = true; - - drm_kms_helper_poll_enable(dev); -} -EXPORT_SYMBOL(drm_kms_helper_poll_init); - -/** - * drm_kms_helper_poll_fini - disable output polling and clean it up - * @dev: drm_device - */ -void drm_kms_helper_poll_fini(struct drm_device *dev) -{ - drm_kms_helper_poll_disable(dev); -} -EXPORT_SYMBOL(drm_kms_helper_poll_fini); - -/** - * drm_helper_hpd_irq_event - hotplug processing - * @dev: drm_device - * - * Drivers can use this helper function to run a detect cycle on all connectors - * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All - * other connectors are ignored, which is useful to avoid reprobing fixed - * panels. - * - * This helper function is useful for drivers which can't or don't track hotplug - * interrupts for each connector. - * - * Drivers which support hotplug interrupts for each connector individually and - * which have a more fine-grained detect logic should bypass this code and - * directly call drm_kms_helper_hotplug_event() in case the connector state - * changed. - * - * This function must be called from process context with no mode - * setting locks held. - * - * Note that a connector can be both polled and probed from the hotplug handler, - * in case the hotplug interrupt is known to be unreliable. - */ -bool drm_helper_hpd_irq_event(struct drm_device *dev) -{ - struct drm_connector *connector; - enum drm_connector_status old_status; - bool changed = false; - - if (!dev->mode_config.poll_enabled) - return false; - - mutex_lock(&dev->mode_config.mutex); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - - /* Only handle HPD capable connectors. */ - if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) - continue; - - old_status = connector->status; - - connector->status = connector->funcs->detect(connector, false); - DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", - connector->base.id, - drm_get_connector_name(connector), - drm_get_connector_status_name(old_status), - drm_get_connector_status_name(connector->status)); - if (old_status != connector->status) - changed = true; - } - - mutex_unlock(&dev->mode_config.mutex); - - if (changed) - drm_kms_helper_hotplug_event(dev); - - return changed; -} -EXPORT_SYMBOL(drm_helper_hpd_irq_event); diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c new file mode 100644 index 000000000000..e70f54d4a581 --- /dev/null +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2006-2008 Intel Corporation + * Copyright (c) 2007 Dave Airlie + * + * DRM core CRTC related functions + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + * + * Authors: + * Keith Packard + * Eric Anholt + * Dave Airlie + * Jesse Barnes + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +/** + * DOC: output probing helper overview + * + * This library provides some helper code for output probing. It provides an + * implementation of the core connector->fill_modes interface with + * drm_helper_probe_single_connector_modes. + * + * It also provides support for polling connectors with a work item and for + * generic hotplug interrupt handling where the driver doesn't or cannot keep + * track of a per-connector hpd interrupt. + * + * This helper library can be used independently of the modeset helper library. + * Drivers can also overwrite different parts e.g. use their own hotplug + * handling code to avoid probing unrelated outputs. + */ + +static bool drm_kms_helper_poll = true; +module_param_named(poll, drm_kms_helper_poll, bool, 0600); + +static void drm_mode_validate_flag(struct drm_connector *connector, + int flags) +{ + struct drm_display_mode *mode; + + if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE | + DRM_MODE_FLAG_3D_MASK)) + return; + + list_for_each_entry(mode, &connector->modes, head) { + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && + !(flags & DRM_MODE_FLAG_INTERLACE)) + mode->status = MODE_NO_INTERLACE; + if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) && + !(flags & DRM_MODE_FLAG_DBLSCAN)) + mode->status = MODE_NO_DBLESCAN; + if ((mode->flags & DRM_MODE_FLAG_3D_MASK) && + !(flags & DRM_MODE_FLAG_3D_MASK)) + mode->status = MODE_NO_STEREO; + } + + return; +} + +/** + * drm_helper_probe_single_connector_modes - get complete set of display modes + * @connector: connector to probe + * @maxX: max width for modes + * @maxY: max height for modes + * + * Based on the helper callbacks implemented by @connector try to detect all + * valid modes. Modes will first be added to the connector's probed_modes list, + * then culled (based on validity and the @maxX, @maxY parameters) and put into + * the normal modes list. + * + * Intended to be use as a generic implementation of the ->fill_modes() + * @connector vfunc for drivers that use the crtc helpers for output mode + * filtering and detection. + * + * Returns: + * The number of modes found on @connector. + */ +int drm_helper_probe_single_connector_modes(struct drm_connector *connector, + uint32_t maxX, uint32_t maxY) +{ + struct drm_device *dev = connector->dev; + struct drm_display_mode *mode; + struct drm_connector_helper_funcs *connector_funcs = + connector->helper_private; + int count = 0; + int mode_flags = 0; + bool verbose_prune = true; + + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, + drm_get_connector_name(connector)); + /* set all modes to the unverified state */ + list_for_each_entry(mode, &connector->modes, head) + mode->status = MODE_UNVERIFIED; + + if (connector->force) { + if (connector->force == DRM_FORCE_ON) + connector->status = connector_status_connected; + else + connector->status = connector_status_disconnected; + if (connector->funcs->force) + connector->funcs->force(connector); + } else { + connector->status = connector->funcs->detect(connector, true); + } + + /* Re-enable polling in case the global poll config changed. */ + if (drm_kms_helper_poll != dev->mode_config.poll_running) + drm_kms_helper_poll_enable(dev); + + dev->mode_config.poll_running = drm_kms_helper_poll; + + if (connector->status == connector_status_disconnected) { + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n", + connector->base.id, drm_get_connector_name(connector)); + drm_mode_connector_update_edid_property(connector, NULL); + verbose_prune = false; + goto prune; + } + +#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE + count = drm_load_edid_firmware(connector); + if (count == 0) +#endif + count = (*connector_funcs->get_modes)(connector); + + if (count == 0 && connector->status == connector_status_connected) + count = drm_add_modes_noedid(connector, 1024, 768); + if (count == 0) + goto prune; + + drm_mode_connector_list_update(connector); + + if (maxX && maxY) + drm_mode_validate_size(dev, &connector->modes, maxX, maxY); + + if (connector->interlace_allowed) + mode_flags |= DRM_MODE_FLAG_INTERLACE; + if (connector->doublescan_allowed) + mode_flags |= DRM_MODE_FLAG_DBLSCAN; + if (connector->stereo_allowed) + mode_flags |= DRM_MODE_FLAG_3D_MASK; + drm_mode_validate_flag(connector, mode_flags); + + list_for_each_entry(mode, &connector->modes, head) { + if (mode->status == MODE_OK) + mode->status = connector_funcs->mode_valid(connector, + mode); + } + +prune: + drm_mode_prune_invalid(dev, &connector->modes, verbose_prune); + + if (list_empty(&connector->modes)) + return 0; + + list_for_each_entry(mode, &connector->modes, head) + mode->vrefresh = drm_mode_vrefresh(mode); + + drm_mode_sort(&connector->modes); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, + drm_get_connector_name(connector)); + list_for_each_entry(mode, &connector->modes, head) { + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); + drm_mode_debug_printmodeline(mode); + } + + return count; +} +EXPORT_SYMBOL(drm_helper_probe_single_connector_modes); + +/** + * drm_kms_helper_hotplug_event - fire off KMS hotplug events + * @dev: drm_device whose connector state changed + * + * This function fires off the uevent for userspace and also calls the + * output_poll_changed function, which is most commonly used to inform the fbdev + * emulation code and allow it to update the fbcon output configuration. + * + * Drivers should call this from their hotplug handling code when a change is + * detected. Note that this function does not do any output detection of its + * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the + * driver already. + * + * This function must be called from process context with no mode + * setting locks held. + */ +void drm_kms_helper_hotplug_event(struct drm_device *dev) +{ + /* send a uevent + call fbdev */ + drm_sysfs_hotplug_event(dev); + if (dev->mode_config.funcs->output_poll_changed) + dev->mode_config.funcs->output_poll_changed(dev); +} +EXPORT_SYMBOL(drm_kms_helper_hotplug_event); + +#define DRM_OUTPUT_POLL_PERIOD (10*HZ) +static void output_poll_execute(struct work_struct *work) +{ + struct delayed_work *delayed_work = to_delayed_work(work); + struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work); + struct drm_connector *connector; + enum drm_connector_status old_status; + bool repoll = false, changed = false; + + if (!drm_kms_helper_poll) + return; + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + + /* Ignore forced connectors. */ + if (connector->force) + continue; + + /* Ignore HPD capable connectors and connectors where we don't + * want any hotplug detection at all for polling. */ + if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD) + continue; + + repoll = true; + + old_status = connector->status; + /* if we are connected and don't want to poll for disconnect + skip it */ + if (old_status == connector_status_connected && + !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT)) + continue; + + connector->status = connector->funcs->detect(connector, false); + if (old_status != connector->status) { + const char *old, *new; + + old = drm_get_connector_status_name(old_status); + new = drm_get_connector_status_name(connector->status); + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] " + "status updated from %s to %s\n", + connector->base.id, + drm_get_connector_name(connector), + old, new); + + changed = true; + } + } + + mutex_unlock(&dev->mode_config.mutex); + + if (changed) + drm_kms_helper_hotplug_event(dev); + + if (repoll) + schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD); +} + +/** + * drm_kms_helper_poll_disable - disable output polling + * @dev: drm_device + * + * This function disables the output polling work. + * + * Drivers can call this helper from their device suspend implementation. It is + * not an error to call this even when output polling isn't enabled or arlready + * disabled. + */ +void drm_kms_helper_poll_disable(struct drm_device *dev) +{ + if (!dev->mode_config.poll_enabled) + return; + cancel_delayed_work_sync(&dev->mode_config.output_poll_work); +} +EXPORT_SYMBOL(drm_kms_helper_poll_disable); + +/** + * drm_kms_helper_poll_enable - re-enable output polling. + * @dev: drm_device + * + * This function re-enables the output polling work. + * + * Drivers can call this helper from their device resume implementation. It is + * an error to call this when the output polling support has not yet been set + * up. + */ +void drm_kms_helper_poll_enable(struct drm_device *dev) +{ + bool poll = false; + struct drm_connector *connector; + + if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll) + return; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT | + DRM_CONNECTOR_POLL_DISCONNECT)) + poll = true; + } + + if (poll) + schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD); +} +EXPORT_SYMBOL(drm_kms_helper_poll_enable); + +/** + * drm_kms_helper_poll_init - initialize and enable output polling + * @dev: drm_device + * + * This function intializes and then also enables output polling support for + * @dev. Drivers which do not have reliable hotplug support in hardware can use + * this helper infrastructure to regularly poll such connectors for changes in + * their connection state. + * + * Drivers can control which connectors are polled by setting the + * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On + * connectors where probing live outputs can result in visual distortion drivers + * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this. + * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are + * completely ignored by the polling logic. + * + * Note that a connector can be both polled and probed from the hotplug handler, + * in case the hotplug interrupt is known to be unreliable. + */ +void drm_kms_helper_poll_init(struct drm_device *dev) +{ + INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute); + dev->mode_config.poll_enabled = true; + + drm_kms_helper_poll_enable(dev); +} +EXPORT_SYMBOL(drm_kms_helper_poll_init); + +/** + * drm_kms_helper_poll_fini - disable output polling and clean it up + * @dev: drm_device + */ +void drm_kms_helper_poll_fini(struct drm_device *dev) +{ + drm_kms_helper_poll_disable(dev); +} +EXPORT_SYMBOL(drm_kms_helper_poll_fini); + +/** + * drm_helper_hpd_irq_event - hotplug processing + * @dev: drm_device + * + * Drivers can use this helper function to run a detect cycle on all connectors + * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All + * other connectors are ignored, which is useful to avoid reprobing fixed + * panels. + * + * This helper function is useful for drivers which can't or don't track hotplug + * interrupts for each connector. + * + * Drivers which support hotplug interrupts for each connector individually and + * which have a more fine-grained detect logic should bypass this code and + * directly call drm_kms_helper_hotplug_event() in case the connector state + * changed. + * + * This function must be called from process context with no mode + * setting locks held. + * + * Note that a connector can be both polled and probed from the hotplug handler, + * in case the hotplug interrupt is known to be unreliable. + */ +bool drm_helper_hpd_irq_event(struct drm_device *dev) +{ + struct drm_connector *connector; + enum drm_connector_status old_status; + bool changed = false; + + if (!dev->mode_config.poll_enabled) + return false; + + mutex_lock(&dev->mode_config.mutex); + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + + /* Only handle HPD capable connectors. */ + if (!(connector->polled & DRM_CONNECTOR_POLL_HPD)) + continue; + + old_status = connector->status; + + connector->status = connector->funcs->detect(connector, false); + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n", + connector->base.id, + drm_get_connector_name(connector), + drm_get_connector_status_name(old_status), + drm_get_connector_status_name(connector->status)); + if (old_status != connector->status) + changed = true; + } + + mutex_unlock(&dev->mode_config.mutex); + + if (changed) + drm_kms_helper_hotplug_event(dev); + + return changed; +} +EXPORT_SYMBOL(drm_helper_hpd_irq_event); diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 0bb34ca2ad2b..36a5febac2a6 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -125,7 +125,6 @@ struct drm_connector_helper_funcs { struct drm_encoder *(*best_encoder)(struct drm_connector *connector); }; -extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern void drm_helper_disable_unused_functions(struct drm_device *dev); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, @@ -161,6 +160,11 @@ static inline void drm_connector_helper_add(struct drm_connector *connector, } extern void drm_helper_resume_force_mode(struct drm_device *dev); + +/* drm_probe_helper.c */ +extern int drm_helper_probe_single_connector_modes(struct drm_connector + *connector, uint32_t maxX, + uint32_t maxY); extern void drm_kms_helper_poll_init(struct drm_device *dev); extern void drm_kms_helper_poll_fini(struct drm_device *dev); extern bool drm_helper_hpd_irq_event(struct drm_device *dev); -- GitLab From 2f1e800799bf478494cec3573cd63eb34ca89c9d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 14 Apr 2014 11:34:48 +0200 Subject: [PATCH 472/797] drm: cirrus: add power management support cirrus kms driver lacks power management support, thus the vga display doesn't work any more after S3 resume. Fix this by adding suspend and resume functions. Also make the mode_set function unblank the screen. Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/cirrus/cirrus_drv.c | 42 ++++++++++++++++++++++++++++ drivers/gpu/drm/cirrus/cirrus_mode.c | 3 ++ 2 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 953fc8aea69c..08ce520f61a5 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "cirrus_drv.h" @@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev) drm_put_dev(dev); } +static int cirrus_pm_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct cirrus_device *cdev = drm_dev->dev_private; + + drm_kms_helper_poll_disable(drm_dev); + + if (cdev->mode_info.gfbdev) { + console_lock(); + fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1); + console_unlock(); + } + + return 0; +} + +static int cirrus_pm_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct cirrus_device *cdev = drm_dev->dev_private; + + drm_helper_resume_force_mode(drm_dev); + + if (cdev->mode_info.gfbdev) { + console_lock(); + fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0); + console_unlock(); + } + + drm_kms_helper_poll_enable(drm_dev); + return 0; +} + static const struct file_operations cirrus_driver_fops = { .owner = THIS_MODULE, .open = drm_open, @@ -103,11 +139,17 @@ static struct drm_driver driver = { .dumb_destroy = drm_gem_dumb_destroy, }; +static const struct dev_pm_ops cirrus_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend, + cirrus_pm_resume) +}; + static struct pci_driver cirrus_pci_driver = { .name = DRIVER_NAME, .id_table = pciidlist, .probe = cirrus_pci_probe, .remove = cirrus_pci_remove, + .driver.pm = &cirrus_pm_ops, }; static int __init cirrus_init(void) diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index 2d64aea83df2..f59433b7610c 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -308,6 +308,9 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc, WREG_HDR(hdr); cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0); + + /* Unblank (needed on S3 resume, vgabios doesn't do it then) */ + outb(0x20, 0x3c0); return 0; } -- GitLab From b8ccd70f1363f7d4e49219dbc46ec973a14f49cd Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 14 Apr 2014 11:34:49 +0200 Subject: [PATCH 473/797] drm: bochs: add power management support bochs kms driver lacks power management support, thus the vga display doesn't work any more after S3 resume. Fix this by adding suspend and resume functions. Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/bochs/bochs.h | 1 + drivers/gpu/drm/bochs/bochs_drv.c | 44 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 741965c001a6..460820551b09 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c index 395bba261c9a..9c13df29fd20 100644 --- a/drivers/gpu/drm/bochs/bochs_drv.c +++ b/drivers/gpu/drm/bochs/bochs_drv.c @@ -94,6 +94,49 @@ static struct drm_driver bochs_driver = { .dumb_destroy = drm_gem_dumb_destroy, }; +/* ---------------------------------------------------------------------- */ +/* pm interface */ + +static int bochs_pm_suspend(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct bochs_device *bochs = drm_dev->dev_private; + + drm_kms_helper_poll_disable(drm_dev); + + if (bochs->fb.initialized) { + console_lock(); + fb_set_suspend(bochs->fb.helper.fbdev, 1); + console_unlock(); + } + + return 0; +} + +static int bochs_pm_resume(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct drm_device *drm_dev = pci_get_drvdata(pdev); + struct bochs_device *bochs = drm_dev->dev_private; + + drm_helper_resume_force_mode(drm_dev); + + if (bochs->fb.initialized) { + console_lock(); + fb_set_suspend(bochs->fb.helper.fbdev, 0); + console_unlock(); + } + + drm_kms_helper_poll_enable(drm_dev); + return 0; +} + +static const struct dev_pm_ops bochs_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend, + bochs_pm_resume) +}; + /* ---------------------------------------------------------------------- */ /* pci interface */ @@ -155,6 +198,7 @@ static struct pci_driver bochs_pci_driver = { .id_table = bochs_pci_tbl, .probe = bochs_pci_probe, .remove = bochs_pci_remove, + .driver.pm = &bochs_pm_ops, }; /* ---------------------------------------------------------------------- */ -- GitLab From c044330baa91b6885597cfaaa58b00b6aa690958 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Mon, 14 Apr 2014 11:34:50 +0200 Subject: [PATCH 474/797] drm: bochs: drop unused struct fields Signed-off-by: Gerd Hoffmann Signed-off-by: Dave Airlie --- drivers/gpu/drm/bochs/bochs.h | 2 -- drivers/gpu/drm/bochs/bochs_fbdev.c | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 460820551b09..7eb52dd44b01 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -88,8 +88,6 @@ struct bochs_device { struct bochs_framebuffer gfb; struct drm_fb_helper helper; int size; - int x1, y1, x2, y2; /* dirty rect */ - spinlock_t dirty_lock; bool initialized; } fb; }; diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c index 4da5206b7cc9..561b84474122 100644 --- a/drivers/gpu/drm/bochs/bochs_fbdev.c +++ b/drivers/gpu/drm/bochs/bochs_fbdev.c @@ -190,7 +190,6 @@ int bochs_fbdev_init(struct bochs_device *bochs) int ret; bochs->fb.helper.funcs = &bochs_fb_helper_funcs; - spin_lock_init(&bochs->fb.dirty_lock); ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper, 1, 1); -- GitLab From 24223657806a0ebd0ae5c9caaf7b021091889cf2 Mon Sep 17 00:00:00 2001 From: Venkatesh Srinivas Date: Thu, 13 Mar 2014 12:36:26 -0700 Subject: [PATCH 475/797] perf/x86/intel: Use rdmsrl_safe() when initializing RAPL PMU CPUs which should support the RAPL counters according to Family/Model/Stepping may still issue #GP when attempting to access the RAPL MSRs. This may happen when Linux is running under KVM and we are passing-through host F/M/S data, for example. Use rdmsrl_safe to first access the RAPL_POWER_UNIT MSR; if this fails, do not attempt to use this PMU. Signed-off-by: Venkatesh Srinivas Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1394739386-22260-1-git-send-email-venkateshs@google.com Cc: zheng.z.yan@intel.com Cc: eranian@google.com Cc: ak@linux.intel.com Cc: linux-kernel@vger.kernel.org [ The patch also silently fixes another bug: rapl_pmu_init() didn't handle the memory alloc failure case previously. ] Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_rapl.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 4b9a9e9466bd..7c87424d4140 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c @@ -535,6 +535,7 @@ static int rapl_cpu_prepare(int cpu) struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu); int phys_id = topology_physical_package_id(cpu); u64 ms; + u64 msr_rapl_power_unit_bits; if (pmu) return 0; @@ -542,6 +543,9 @@ static int rapl_cpu_prepare(int cpu) if (phys_id < 0) return -1; + if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) + return -1; + pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); if (!pmu) return -1; @@ -555,8 +559,7 @@ static int rapl_cpu_prepare(int cpu) * * we cache in local PMU instance */ - rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit); - pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL; + pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL; pmu->pmu = &rapl_pmu_class; /* @@ -677,7 +680,9 @@ static int __init rapl_pmu_init(void) cpu_notifier_register_begin(); for_each_online_cpu(cpu) { - rapl_cpu_prepare(cpu); + ret = rapl_cpu_prepare(cpu); + if (ret) + goto out; rapl_cpu_init(cpu); } @@ -700,6 +705,7 @@ static int __init rapl_pmu_init(void) hweight32(rapl_cntr_mask), ktime_to_ms(pmu->timer_interval)); +out: cpu_notifier_register_done(); return 0; -- GitLab From 4991a628a789dc5954e98e79476d9808812292ec Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 08:44:12 -0400 Subject: [PATCH 476/797] locks: allow __break_lease to sleep even when break_time is 0 A fl->fl_break_time of 0 has a special meaning to the lease break code that basically means "never break the lease". knfsd uses this to ensure that leases don't disappear out from under it. Unfortunately, the code in __break_lease can end up passing this value to wait_event_interruptible as a timeout, which prevents it from going to sleep at all. This causes __break_lease to spin in a tight loop and causes soft lockups. Fix this by ensuring that we pass a minimum value of 1 as a timeout instead. Cc: Cc: J. Bruce Fields Reported-by: Terry Barnaby Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/locks.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 13fc7a6d380a..b380f5543614 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1391,11 +1391,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type) restart: break_time = flock->fl_break_time; - if (break_time != 0) { + if (break_time != 0) break_time -= jiffies; - if (break_time == 0) - break_time++; - } + if (break_time == 0) + break_time++; locks_insert_block(flock, new_fl); spin_unlock(&inode->i_lock); error = wait_event_interruptible_timeout(new_fl->fl_wait, -- GitLab From 3758cf7e14b753838fe754ede3862af10b35fdac Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 15 Apr 2014 08:51:48 -0400 Subject: [PATCH 477/797] nfsd: set timeparms.to_maxval in setup_callback_client ...otherwise the logic in the timeout handling doesn't work correctly. Spotted-by: Trond Myklebust Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4callback.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 39c8ef875f91..2c73cae9899d 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -654,9 +654,11 @@ static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args) static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses) { + int maxtime = max_cb_time(clp->net); struct rpc_timeout timeparms = { - .to_initval = max_cb_time(clp->net), + .to_initval = maxtime, .to_retries = 0, + .to_maxval = maxtime, }; struct rpc_create_args args = { .net = clp->net, -- GitLab From fc208d026be0c7d60db9118583fc62f6ca97743d Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 9 Apr 2014 11:07:01 -0400 Subject: [PATCH 478/797] Revert "nfsd4: fix nfs4err_resource in 4.1 case" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we're still limiting attributes to a page, the result here is that a large getattr result will return NFS4ERR_REP_TOO_BIG/TOO_BIG_TO_CACHE instead of NFS4ERR_RESOURCE. Both error returns are wrong, and the real bug here is the arbitrary limit on getattr results, fixed by as-yet out-of-tree patches. But at a minimum we can make life easier for clients by sticking to one broken behavior in released kernels instead of two.... Trond says: one immediate consequence of this patch will be that NFSv4.1 clients will now report EIO instead of EREMOTEIO if they hit the problem. That may make debugging a little less obvious. Another consequence will be that if we ever do try to add client side handling of NFS4ERR_REP_TOO_BIG, then we now have to deal with the “handle existing buggy server” syndrome. Reported-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2723c1badd01..18881f34737a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3627,14 +3627,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) /* nfsd4_check_resp_size guarantees enough room for error status */ if (!op->status) op->status = nfsd4_check_resp_size(resp, 0); - if (op->status == nfserr_resource && nfsd4_has_session(&resp->cstate)) { - struct nfsd4_slot *slot = resp->cstate.slot; - - if (slot->sl_flags & NFSD4_SLOT_CACHETHIS) - op->status = nfserr_rep_too_big_to_cache; - else - op->status = nfserr_rep_too_big; - } if (so) { so->so_replay.rp_status = op->status; so->so_replay.rp_buflen = (char *)resp->p - (char *)(statp+1); -- GitLab From 20cd477c398decd6a8461ac48609b6c0ab4c7567 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Wed, 16 Apr 2014 10:49:20 +0400 Subject: [PATCH 479/797] of: add empty of_find_node_by_path() for !OF Add an empty version of of_find_node_by_path(). This fixes following build error for asoc tree: sound/soc/fsl/fsl_ssi.c: In function 'fsl_ssi_probe': sound/soc/fsl/fsl_ssi.c:1471:2: error: implicit declaration of function 'of_find_node_by_path' [-Werror=implicit-function-declaration] sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL); Reported-by: Stephen Rothwell Signed-off-by: Alexander Shiyan Signed-off-by: Rob Herring --- include/linux/of.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/of.h b/include/linux/of.h index 919bf211877d..3bad8d106e0e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -374,6 +374,11 @@ static inline struct device_node *of_find_matching_node_and_match( return NULL; } +static inline struct device_node *of_find_node_by_path(const char *path) +{ + return NULL; +} + static inline struct device_node *of_get_parent(const struct device_node *node) { return NULL; -- GitLab From 6ae6698276ca36f37afc2ad38054092021519ad4 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 18 Apr 2014 17:32:08 +0800 Subject: [PATCH 480/797] ASoC: fsl_spdif: Fix wrong OFFSET of STC_SYSCLK_DIV It should use STC_SYSCLK_DIV_OFFSET. Thus fix it. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_spdif.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h index b1266790d117..605a10b2112b 100644 --- a/sound/soc/fsl/fsl_spdif.h +++ b/sound/soc/fsl/fsl_spdif.h @@ -144,8 +144,8 @@ enum spdif_gainsel { /* SPDIF Clock register */ #define STC_SYSCLK_DIV_OFFSET 11 -#define STC_SYSCLK_DIV_MASK (0x1ff << STC_TXCLK_SRC_OFFSET) -#define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK) +#define STC_SYSCLK_DIV_MASK (0x1ff << STC_SYSCLK_DIV_OFFSET) +#define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_SYSCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK) #define STC_TXCLK_SRC_OFFSET 8 #define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET) #define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK) -- GitLab From eb4dd20c2ac9ad394401694d8762e0a13bc469ef Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Fri, 18 Apr 2014 02:06:30 +0200 Subject: [PATCH 481/797] ASoC: tlv320aic31xx: document that the regulators are mandatory The driver will not probe if regulators are not provided. Move the regulator properties to the required section. Signed-off-by: Alexandre Belloni Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/tlv320aic31xx.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt index 74c66dee3e14..eff12be5e789 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt @@ -13,6 +13,9 @@ Required properties: "ti,tlv320aic3111" - TLV320AIC3111 (stereo speaker amp, MiniDSP) - reg - - I2C slave address +- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, + DVDD-supply : power supplies for the device as covered in + Documentation/devicetree/bindings/regulator/regulator.txt Optional properties: @@ -24,9 +27,6 @@ Optional properties: 3 or MICBIAS_AVDD - MICBIAS output is connected to AVDD If this node is not mentioned or if the value is unknown, then micbias is set to 2.0V. -- HPVDD-supply, SPRVDD-supply, SPLVDD-supply, AVDD-supply, IOVDD-supply, - DVDD-supply : power supplies for the device as covered in - Documentation/devicetree/bindings/regulator/regulator.txt CODEC output pins: * HPL -- GitLab From df7926fffa9a4c0bceb0189386b4c5edc012fcbb Mon Sep 17 00:00:00 2001 From: Tim Kryger Date: Thu, 17 Apr 2014 11:55:24 -0700 Subject: [PATCH 482/797] regulator: core: Return error in get optional stub Drivers that call regulator_get_optional are tolerant to the absence of that regulator. By modifying the value returned from the stub function to match that seen when a regulator isn't present, callers can wrap the regulator logic with an IS_ERR based conditional even if they happen to call regulator_is_supported_voltage. This improves efficiency as well as eliminates the possibility for a very subtle bug. Signed-off-by: Tim Kryger Reviewed-by: Alex Elder Signed-off-by: Mark Brown --- include/linux/regulator/consumer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index e530681bea70..1a4a8c157b31 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -258,14 +258,14 @@ regulator_get_exclusive(struct device *dev, const char *id) static inline struct regulator *__must_check regulator_get_optional(struct device *dev, const char *id) { - return NULL; + return ERR_PTR(-ENODEV); } static inline struct regulator *__must_check devm_regulator_get_optional(struct device *dev, const char *id) { - return NULL; + return ERR_PTR(-ENODEV); } static inline void regulator_put(struct regulator *regulator) -- GitLab From 4e17d2d33abe4b523f79fec037ef66ba93643f65 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 8 Apr 2014 22:10:33 +0800 Subject: [PATCH 483/797] ASoC: cs42l52: Convert to use devm_gpio_request_one Current code missed a gpio_free() call in cs42l52_i2c_remove(). Convert to use devm_gpio_request_one() to fix it. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l52.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 460d35547a68..2213a037c893 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c @@ -1229,8 +1229,10 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, } if (cs42l52->pdata.reset_gpio) { - ret = gpio_request_one(cs42l52->pdata.reset_gpio, - GPIOF_OUT_INIT_HIGH, "CS42L52 /RST"); + ret = devm_gpio_request_one(&i2c_client->dev, + cs42l52->pdata.reset_gpio, + GPIOF_OUT_INIT_HIGH, + "CS42L52 /RST"); if (ret < 0) { dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", cs42l52->pdata.reset_gpio, ret); -- GitLab From 2b21694f153a0df88dca7fb4ce04614ea7ff9dc2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 8 Apr 2014 22:11:40 +0800 Subject: [PATCH 484/797] ASoC: cs42l73: Convert to use devm_gpio_request_one Current code missed a gpio_free() call in cs42l73_i2c_remove(). Convert to use devm_gpio_request_one() to fix it. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/codecs/cs42l73.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 0ee60a19a263..ae3717992d56 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c @@ -1443,8 +1443,10 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, i2c_set_clientdata(i2c_client, cs42l73); if (cs42l73->pdata.reset_gpio) { - ret = gpio_request_one(cs42l73->pdata.reset_gpio, - GPIOF_OUT_INIT_HIGH, "CS42L73 /RST"); + ret = devm_gpio_request_one(&i2c_client->dev, + cs42l73->pdata.reset_gpio, + GPIOF_OUT_INIT_HIGH, + "CS42L73 /RST"); if (ret < 0) { dev_err(&i2c_client->dev, "Failed to request /RST %d: %d\n", cs42l73->pdata.reset_gpio, ret); -- GitLab From 694c793fc1ade0946149c5f8d43f71e0728c4e81 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:21:15 -0400 Subject: [PATCH 485/797] ext4: use truncate_pagecache() in collapse range We should be using truncate_pagecache() instead of truncate_pagecache_range() in the collapse range because we're truncating page cache from offset to the end of file. truncate_pagecache() also get rid of the private COWed pages from the range because we're going to shift the end of the file. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 64b400356cad..3de9b2d7028c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5437,7 +5437,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) goto out_mutex; } - truncate_pagecache_range(inode, offset, -1); + truncate_pagecache(inode, offset); /* Wait for existing dio to complete */ ext4_inode_block_unlocked_dio(inode); -- GitLab From 1676014ef974ce71a854e7f415e2bb52feb24868 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Sun, 13 Apr 2014 12:45:10 +0200 Subject: [PATCH 486/797] spi: atmel: Fix scheduling while atomic bug atmel_spi_lock does a spin_lock_irqsave, so we need to renable the interrupts when we want to schedule. Signed-off-by: Alexander Stein Signed-off-by: Mark Brown --- drivers/spi/spi-atmel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 8005f9869481..079e6b1b0cdb 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1115,8 +1115,11 @@ static int atmel_spi_one_transfer(struct spi_master *master, atmel_spi_next_xfer_pio(master, xfer); } + /* interrupts are disabled, so free the lock for schedule */ + atmel_spi_unlock(as); ret = wait_for_completion_timeout(&as->xfer_completion, SPI_DMA_TIMEOUT); + atmel_spi_lock(as); if (WARN_ON(ret == 0)) { dev_err(&spi->dev, "spi trasfer timeout, err %d\n", ret); -- GitLab From 1a66c7c3bea52ba0f7596b8940d74fce75281d16 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:41:52 -0400 Subject: [PATCH 487/797] ext4: use filemap_write_and_wait_range() correctly in collapse range Currently we're passing -1 as lend argumnet for filemap_write_and_wait_range() which is wrong since lend is signed type so it would cause some confusion and we might not write_and_wait for the entire range we're expecting to write. Fix it by using LLONG_MAX instead. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3de9b2d7028c..f4a676908b0b 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5415,7 +5415,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) } /* Write out all dirty pages */ - ret = filemap_write_and_wait_range(inode->i_mapping, offset, -1); + ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); if (ret) return ret; -- GitLab From 2c1d23289bc2f7cfa358bc856b87a992dcb11ad5 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:43:21 -0400 Subject: [PATCH 488/797] ext4: fix removing status extents in ext4_collapse_range() Currently in ext4_collapse_range() when calling ext4_es_remove_extent() to remove status extents we're passing (EXT_MAX_BLOCKS - punch_start - 1) in order to remove all extents from start of the collapse range to the end of the file. However this is wrong because we might miss the possible extent covering the last block of the file. Fix it by removing the -1. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" Reviewed-by: Namjae Jeon --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f4a676908b0b..c6f624582d37 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5454,7 +5454,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) ext4_discard_preallocations(inode); ret = ext4_es_remove_extent(inode, punch_start, - EXT_MAX_BLOCKS - punch_start - 1); + EXT_MAX_BLOCKS - punch_start); if (ret) { up_write(&EXT4_I(inode)->i_data_sem); goto out_stop; -- GitLab From 9337d5d31ab798f0c74150506371551a9195251a Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:48:25 -0400 Subject: [PATCH 489/797] ext4: no need to truncate pagecache twice in collapse range We're already calling truncate_pagecache() before we attempt to do any actual job so there is not need to truncate pagecache once more using truncate_setsize() after we're finished. Remove truncate_setsize() and replace it just with i_size_write() note that we're holding appropriate locks. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index c6f624582d37..3ee60e2e2ac7 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5474,7 +5474,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) } new_size = i_size_read(inode) - len; - truncate_setsize(inode, new_size); + i_size_write(inode, new_size); EXT4_I(inode)->i_disksize = new_size; ext4_discard_preallocations(inode); -- GitLab From ef24f6c234de9a03aed9368163dbaad9a4f6391f Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:50:23 -0400 Subject: [PATCH 490/797] ext4: discard preallocations after removing space Currently in ext4_collapse_range() and ext4_punch_hole() we're discarding preallocation twice. Once before we attempt to do any changes and second time after we're done with the changes. While the second call to ext4_discard_preallocations() in ext4_punch_hole() case is not needed, we need to discard preallocation right after ext4_ext_remove_space() in collapse range case because in the case we had to restart a transaction in the middle of removing space we might have new preallocations created. Remove unneeded ext4_discard_preallocations() ext4_punch_hole() and move it to the better place in ext4_collapse_range() Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- fs/ext4/inode.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3ee60e2e2ac7..eb7be8f08e10 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5465,6 +5465,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) up_write(&EXT4_I(inode)->i_data_sem); goto out_stop; } + ext4_discard_preallocations(inode); ret = ext4_ext_shift_extents(inode, handle, punch_stop, punch_stop - punch_start); @@ -5477,7 +5478,6 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) i_size_write(inode, new_size); EXT4_I(inode)->i_disksize = new_size; - ext4_discard_preallocations(inode); up_write(&EXT4_I(inode)->i_data_sem); if (IS_SYNC(inode)) ext4_handle_sync(handle); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b74cfd2a42ec..d7b7462a0e13 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3621,7 +3621,6 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length) ret = ext4_free_hole_blocks(handle, inode, first_block, stop_block); - ext4_discard_preallocations(inode); up_write(&EXT4_I(inode)->i_data_sem); if (IS_SYNC(inode)) ext4_handle_sync(handle); -- GitLab From 6dd834effc12ba71092d9d1e4944530234b58ab1 Mon Sep 17 00:00:00 2001 From: Lukas Czerner Date: Fri, 18 Apr 2014 10:55:24 -0400 Subject: [PATCH 491/797] ext4: fix extent merging in ext4_ext_shift_path_extents() There is a bug in ext4_ext_shift_path_extents() where if we actually manage to merge a extent we would skip shifting the next extent. This will result in in one extent in the extent tree not being properly shifted. This is causing failure in various xfstests tests using fsx or fsstress with collapse range support. It will also cause file system corruption which looks something like: e2fsck 1.42.9 (4-Feb-2014) Pass 1: Checking inodes, blocks, and sizes Inode 20 has out of order extents (invalid logical block 3, physical block 492938, len 2) Clear? yes ... when running e2fsck. It's also very easily reproducible just by running fsx without any parameters. I can usually hit the problem within a minute. Fix it by increasing ex_start only if we're not merging the extent. Signed-off-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" Reviewed-by: Namjae Jeon --- fs/ext4/extents.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index eb7be8f08e10..d0860f2d36d0 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5245,13 +5245,14 @@ ext4_ext_shift_path_extents(struct ext4_ext_path *path, ext4_lblk_t shift, while (ex_start <= ex_last) { le32_add_cpu(&ex_start->ee_block, -shift); - if (ex_start > - EXT_FIRST_EXTENT(path[depth].p_hdr)) { - if (ext4_ext_try_to_merge_right(inode, - path, ex_start - 1)) - ex_last--; - } - ex_start++; + /* Try to merge to the left. */ + if ((ex_start > + EXT_FIRST_EXTENT(path[depth].p_hdr)) && + ext4_ext_try_to_merge_right(inode, + path, ex_start - 1)) + ex_last--; + else + ex_start++; } err = ext4_ext_dirty(handle, inode, path + depth); if (err) -- GitLab From 6c5e73d3a26b73bfcac0b4a932cb918177d067f2 Mon Sep 17 00:00:00 2001 From: jon ernst Date: Fri, 18 Apr 2014 11:50:35 -0400 Subject: [PATCH 492/797] ext4: enforce we are operating on a regular file in ext4_zero_range() Signed-off-by: Jon Ernst Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index d0860f2d36d0..2f49b12a4c40 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -4741,6 +4741,9 @@ static long ext4_zero_range(struct file *file, loff_t offset, trace_ext4_zero_range(inode, offset, len, mode); + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + /* * Write out all dirty pages to avoid race conditions * Then release them. -- GitLab From 86f1ca3889142d5959362c5694db3f3dc26f377a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 18 Apr 2014 11:52:11 -0400 Subject: [PATCH 493/797] ext4: use EINVAL if not a regular file in ext4_collapse_range() Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 2f49b12a4c40..9b9251adb400 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5404,7 +5404,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) return -EINVAL; if (!S_ISREG(inode->i_mode)) - return -EOPNOTSUPP; + return -EINVAL; trace_ext4_collapse_range(inode, offset, len); -- GitLab From 7897ab78f64008a81344af9fecec6527dbab7a31 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 16 Apr 2014 18:38:11 +0300 Subject: [PATCH 494/797] ASoC: Intel: some incorrect sizeof() usages The intent was to say "sizeof(*pos)" and not "sizeof(pos)". The sizeof(*pos) is 8 bytes so the bug won't show up on 64 bit systems. The sizeof(*dx) is 172 bytes so that will be a bugfix. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index f46bb4ddde6f..4ed2d1706a83 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -617,7 +617,7 @@ static void hsw_notification_work(struct work_struct *work) case IPC_POSITION_CHANGED: trace_ipc_notification("DSP stream position changed for", stream->reply.stream_hw_id); - sst_dsp_inbox_read(hsw->dsp, pos, sizeof(pos)); + sst_dsp_inbox_read(hsw->dsp, pos, sizeof(*pos)); if (stream->notify_position) stream->notify_position(stream, stream->pdata); @@ -1609,7 +1609,7 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw, trace_ipc_request("PM enter Dx state", state); ret = ipc_tx_message_wait(hsw, header, &state_, sizeof(state_), - dx, sizeof(dx)); + dx, sizeof(*dx)); if (ret < 0) { dev_err(hsw->dev, "ipc: error set dx state %d failed\n", state); return ret; -- GitLab From bf657d2479d179a03668cd7ab8aec96415592f02 Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Sun, 13 Apr 2014 19:56:36 +0200 Subject: [PATCH 495/797] ASoC: Intel: Fix incorrect sizeof() in sst_hsw_stream_get_volume() Fix an incorrect sizeof() usage in sst_hsw_stream_get_volume(). sst_dsp_read() is called to read into a variable of type u32, but is passed sizeof(u32 *) for argument 'size_t bytes'. Detected by Coverity: CID 1195260. Signed-off-by: Christian Engelmayer Signed-off-by: Mark Brown --- sound/soc/intel/sst-haswell-ipc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-haswell-ipc.c b/sound/soc/intel/sst-haswell-ipc.c index 4ed2d1706a83..50e4246d4b57 100644 --- a/sound/soc/intel/sst-haswell-ipc.c +++ b/sound/soc/intel/sst-haswell-ipc.c @@ -991,7 +991,8 @@ int sst_hsw_stream_get_volume(struct sst_hsw *hsw, struct sst_hsw_stream *stream return -EINVAL; sst_dsp_read(hsw->dsp, volume, - stream->reply.volume_register_address[channel], sizeof(volume)); + stream->reply.volume_register_address[channel], + sizeof(*volume)); return 0; } -- GitLab From 2cf532f5e67c0cfe38c8c100e49280cdadacd2be Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 17 Apr 2014 18:06:15 +0200 Subject: [PATCH 496/797] ahci: Do not receive interrupts sent by dummy ports In multiple MSI mode all AHCI ports (including dummy) get assigned separate MSI vectors and (as result of execution pci_enable_msi_exact() function) separate IRQ numbers, (mapped to the MSI vectors). Therefore, although interrupts from dummy ports are not desired they are still enabled. We do not request IRQs for dummy ports, but that only means we do not assign AHCI-specific ISRs to corresponding IRQ numbers. As result, dummy port interrupts still could come and traverse all the way from the PCI device to the kernel, causing unnecessary overhead. This update disables IRQs for dummy ports and prevents the described issue. Signed-off-by: Alexander Gordeev Signed-off-by: Tejun Heo Tested-by: David Milburn Cc: linux-ide@vger.kernel.org Cc: stable@vger.kernel.org Fixes: 5ca72c4f7c41 ("AHCI: Support multiple MSIs") --- drivers/ata/ahci.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 44d40c746982..71e15b73513d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1241,12 +1241,16 @@ int ahci_host_activate(struct ata_host *host, int irq, unsigned int n_msis) for (i = 0; i < host->n_ports; i++) { struct ahci_port_priv *pp = host->ports[i]->private_data; - /* pp is NULL for dummy ports */ - if (pp) - rc = devm_request_threaded_irq(host->dev, - irq + i, ahci_hw_interrupt, - ahci_thread_fn, IRQF_SHARED, - pp->irq_desc, host->ports[i]); + /* Do not receive interrupts sent by dummy ports */ + if (!pp) { + disable_irq(irq + i); + continue; + } + + rc = devm_request_threaded_irq(host->dev, irq + i, + ahci_hw_interrupt, + ahci_thread_fn, IRQF_SHARED, + pp->irq_desc, host->ports[i]); if (rc) goto out_free_irqs; } -- GitLab From 8a4aeec8d2d6a3edeffbdfae451cdf05cbf0fefd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 17 Apr 2014 11:48:21 -0700 Subject: [PATCH 497/797] libata/ahci: accommodate tag ordered controllers The AHCI spec allows implementations to issue commands in tag order rather than FIFO order: 5.3.2.12 P:SelectCmd HBA sets pSlotLoc = (pSlotLoc + 1) mod (CAP.NCS + 1) or HBA selects the command to issue that has had the PxCI bit set to '1' longer than any other command pending to be issued. The result is that commands posted sequentially (time-wise) may play out of sequence when issued by hardware. This behavior has likely been hidden by drives that arrange for commands to complete in issue order. However, it appears recent drives (two from different vendors that we have found so far) inflict out-of-order completions as a matter of course. So, we need to take care to maintain ordered submission, otherwise we risk triggering a drive to fall out of sequential-io automation and back to random-io processing, which incurs large latency and degrades throughput. This issue was found in simple benchmarks where QD=2 seq-write performance was 30-50% *greater* than QD=32 seq-write performance. Tagging for -stable and making the change globally since it has a low risk-to-reward ratio. Also, word is that recent versions of an unnamed OS also does it this way now. So, drives in the field are already experienced with this tag ordering scheme. Cc: Cc: Dave Jiang Cc: Ed Ciechanowski Reviewed-by: Matthew Wilcox Signed-off-by: Dan Williams Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 21 +++++++++++++-------- include/linux/libata.h | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index f2a6020366e1..73c5d0410d47 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4794,21 +4794,26 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) { struct ata_queued_cmd *qc = NULL; - unsigned int i; + unsigned int i, tag; /* no command while frozen */ if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) return NULL; - /* the last tag is reserved for internal command. */ - for (i = 0; i < ATA_MAX_QUEUE - 1; i++) - if (!test_and_set_bit(i, &ap->qc_allocated)) { - qc = __ata_qc_from_tag(ap, i); + for (i = 0; i < ATA_MAX_QUEUE; i++) { + tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE; + + /* the last tag is reserved for internal command. */ + if (tag == ATA_TAG_INTERNAL) + continue; + + if (!test_and_set_bit(tag, &ap->qc_allocated)) { + qc = __ata_qc_from_tag(ap, tag); + qc->tag = tag; + ap->last_tag = tag; break; } - - if (qc) - qc->tag = i; + } return qc; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 1de36be64df4..5ab4e3a76721 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -822,6 +822,7 @@ struct ata_port { unsigned long qc_allocated; unsigned int qc_active; int nr_active_links; /* #links with active qcs */ + unsigned int last_tag; /* track next tag hw expects */ struct ata_link link; /* host default link */ struct ata_link *slave_link; /* see ata_slave_link_init() */ -- GitLab From 64ee9f32c33cbd53545284742e73c17fedf9d429 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 18 Apr 2014 13:38:34 +0530 Subject: [PATCH 498/797] ARC: Delete stale barrier.h Commit 93ea02bb8435 ("arch: Clean up asm/barrier.h implementations") wired generic barrier.h for ARC, but failed to delete the existing file. In 3.15, due to rcupdate.h updates, this causes a build breakage on ARC: CC arch/arc/kernel/asm-offsets.s In file included from include/linux/sched.h:45:0, from arch/arc/kernel/asm-offsets.c:9: include/linux/rculist.h: In function __list_add_rcu: include/linux/rculist.h:54:2: error: implicit declaration of function smp_store_release [-Werror=implicit-function-declaration] rcu_assign_pointer(list_next_rcu(prev), new); ^ Cc: Peter Zijlstra Signed-off-by: Vineet Gupta Signed-off-by: Linus Torvalds --- arch/arc/include/asm/barrier.h | 37 ---------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 arch/arc/include/asm/barrier.h diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h deleted file mode 100644 index c32245c3d1e9..000000000000 --- a/arch/arc/include/asm/barrier.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - * - * 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 __ASM_BARRIER_H -#define __ASM_BARRIER_H - -#ifndef __ASSEMBLY__ - -/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */ -#define mb() __asm__ __volatile__ ("" : : : "memory") -#define rmb() mb() -#define wmb() mb() -#define set_mb(var, value) do { var = value; mb(); } while (0) -#define set_wmb(var, value) do { var = value; wmb(); } while (0) -#define read_barrier_depends() mb() - -/* TODO-vineetg verify the correctness of macros here */ -#ifdef CONFIG_SMP -#define smp_mb() mb() -#define smp_rmb() rmb() -#define smp_wmb() wmb() -#else -#define smp_mb() barrier() -#define smp_rmb() barrier() -#define smp_wmb() barrier() -#endif - -#define smp_read_barrier_depends() do { } while (0) - -#endif - -#endif -- GitLab From dc8eaaa006350d24030502a4521542e74b5cb39f Mon Sep 17 00:00:00 2001 From: dingtianhong Date: Thu, 17 Apr 2014 18:40:36 +0800 Subject: [PATCH 499/797] vlan: Fix lockdep warning when vlan dev handle notification When I open the LOCKDEP config and run these steps: modprobe 8021q vconfig add eth2 20 vconfig add eth2.20 30 ifconfig eth2 xx.xx.xx.xx then the Call Trace happened: [32524.386288] ============================================= [32524.386293] [ INFO: possible recursive locking detected ] [32524.386298] 3.14.0-rc2-0.7-default+ #35 Tainted: G O [32524.386302] --------------------------------------------- [32524.386306] ifconfig/3103 is trying to acquire lock: [32524.386310] (&vlan_netdev_addr_lock_key/1){+.....}, at: [] dev_mc_sync+0x64/0xb0 [32524.386326] [32524.386326] but task is already holding lock: [32524.386330] (&vlan_netdev_addr_lock_key/1){+.....}, at: [] dev_set_rx_mode+0x23/0x40 [32524.386341] [32524.386341] other info that might help us debug this: [32524.386345] Possible unsafe locking scenario: [32524.386345] [32524.386350] CPU0 [32524.386352] ---- [32524.386354] lock(&vlan_netdev_addr_lock_key/1); [32524.386359] lock(&vlan_netdev_addr_lock_key/1); [32524.386364] [32524.386364] *** DEADLOCK *** [32524.386364] [32524.386368] May be due to missing lock nesting notation [32524.386368] [32524.386373] 2 locks held by ifconfig/3103: [32524.386376] #0: (rtnl_mutex){+.+.+.}, at: [] rtnl_lock+0x12/0x20 [32524.386387] #1: (&vlan_netdev_addr_lock_key/1){+.....}, at: [] dev_set_rx_mode+0x23/0x40 [32524.386398] [32524.386398] stack backtrace: [32524.386403] CPU: 1 PID: 3103 Comm: ifconfig Tainted: G O 3.14.0-rc2-0.7-default+ #35 [32524.386409] Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007 [32524.386414] ffffffff81ffae40 ffff8800d9625ae8 ffffffff814f68a2 ffff8800d9625bc8 [32524.386421] ffffffff810a35fb ffff8800d8a8d9d0 00000000d9625b28 ffff8800d8a8e5d0 [32524.386428] 000003cc00000000 0000000000000002 ffff8800d8a8e5f8 0000000000000000 [32524.386435] Call Trace: [32524.386441] [] dump_stack+0x6a/0x78 [32524.386448] [] __lock_acquire+0x7ab/0x1940 [32524.386454] [] ? __lock_acquire+0x3ea/0x1940 [32524.386459] [] lock_acquire+0xe4/0x110 [32524.386464] [] ? dev_mc_sync+0x64/0xb0 [32524.386471] [] _raw_spin_lock_nested+0x2a/0x40 [32524.386476] [] ? dev_mc_sync+0x64/0xb0 [32524.386481] [] dev_mc_sync+0x64/0xb0 [32524.386489] [] vlan_dev_set_rx_mode+0x2b/0x50 [8021q] [32524.386495] [] __dev_set_rx_mode+0x5f/0xb0 [32524.386500] [] dev_set_rx_mode+0x2b/0x40 [32524.386506] [] __dev_open+0xef/0x150 [32524.386511] [] __dev_change_flags+0xa7/0x190 [32524.386516] [] dev_change_flags+0x32/0x80 [32524.386524] [] devinet_ioctl+0x7d6/0x830 [32524.386532] [] ? dev_ioctl+0x34b/0x660 [32524.386540] [] inet_ioctl+0x80/0xa0 [32524.386550] [] sock_do_ioctl+0x2d/0x60 [32524.386558] [] sock_ioctl+0x82/0x2a0 [32524.386568] [] do_vfs_ioctl+0x93/0x590 [32524.386578] [] ? rcu_read_lock_held+0x45/0x50 [32524.386586] [] ? __fget_light+0x105/0x110 [32524.386594] [] SyS_ioctl+0x91/0xb0 [32524.386604] [] system_call_fastpath+0x16/0x1b ======================================================================== The reason is that all of the addr_lock_key for vlan dev have the same class, so if we change the status for vlan dev, the vlan dev and its real dev will hold the same class of addr_lock_key together, so the warning happened. we should distinguish the lock depth for vlan dev and its real dev. v1->v2: Convert the vlan_netdev_addr_lock_key to an array of eight elements, which could support to add 8 vlan id on a same vlan dev, I think it is enough for current scene, because a netdev's name is limited to IFNAMSIZ which could not hold 8 vlan id, and the vlan dev would not meet the same class key with its real dev. The new function vlan_dev_get_lockdep_subkey() will return the subkey and make the vlan dev could get a suitable class key. v2->v3: According David's suggestion, I use the subclass to distinguish the lock key for vlan dev and its real dev, but it make no sense, because the difference for subclass in the lock_class_key doesn't mean that the difference class for lock_key, so I use lock_depth to distinguish the different depth for every vlan dev, the same depth of the vlan dev could have the same lock_class_key, I import the MAX_LOCK_DEPTH from the include/linux/sched.h, I think it is enough here, the lockdep should never exceed that value. v3->v4: Add a huge array of locking keys will waste static kernel memory and is not a appropriate method, we could use _nested() variants to fix the problem, calculate the depth for every vlan dev, and use the depth as the subclass for addr_lock_key. Signed-off-by: Ding Tianhong Signed-off-by: David S. Miller --- net/8021q/vlan_dev.c | 46 +++++++++++++++++++++++++++++++++++++++----- net/core/dev.c | 1 + 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 6f142f03716d..733ec283ed1b 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -493,10 +493,48 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) } } +static int vlan_calculate_locking_subclass(struct net_device *real_dev) +{ + int subclass = 0; + + while (is_vlan_dev(real_dev)) { + subclass++; + real_dev = vlan_dev_priv(real_dev)->real_dev; + } + + return subclass; +} + +static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from) +{ + int err = 0, subclass; + + subclass = vlan_calculate_locking_subclass(to); + + spin_lock_nested(&to->addr_list_lock, subclass); + err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); + if (!err) + __dev_set_rx_mode(to); + spin_unlock(&to->addr_list_lock); +} + +static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from) +{ + int err = 0, subclass; + + subclass = vlan_calculate_locking_subclass(to); + + spin_lock_nested(&to->addr_list_lock, subclass); + err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); + if (!err) + __dev_set_rx_mode(to); + spin_unlock(&to->addr_list_lock); +} + static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) { - dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); - dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); + vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); + vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); } /* @@ -608,9 +646,7 @@ static int vlan_dev_init(struct net_device *dev) SET_NETDEV_DEVTYPE(dev, &vlan_type); - if (is_vlan_dev(real_dev)) - subclass = 1; - + subclass = vlan_calculate_locking_subclass(dev); vlan_dev_set_lockdep_class(dev, subclass); vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); diff --git a/net/core/dev.c b/net/core/dev.c index 5b3042e69f85..d2c8a06b3a98 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5238,6 +5238,7 @@ void __dev_set_rx_mode(struct net_device *dev) if (ops->ndo_set_rx_mode) ops->ndo_set_rx_mode(dev); } +EXPORT_SYMBOL(__dev_set_rx_mode); void dev_set_rx_mode(struct net_device *dev) { -- GitLab From ba67b510035141bd89b40bf65efa0a79834311ca Mon Sep 17 00:00:00 2001 From: Ivan Vecera Date: Thu, 17 Apr 2014 14:51:08 +0200 Subject: [PATCH 500/797] tg3: update rx_jumbo_pending ring param only when jumbo frames are enabled The patch fixes a problem with dropped jumbo frames after usage of 'ethtool -G ... rx'. Scenario: 1. ip link set eth0 up 2. ethtool -G eth0 rx N # <- This zeroes rx-jumbo 3. ip link set mtu 9000 dev eth0 The ethtool command set rx_jumbo_pending to zero so any received jumbo packets are dropped and you need to use 'ethtool -G eth0 rx-jumbo N' to workaround the issue. The patch changes the logic so rx_jumbo_pending value is changed only if jumbo frames are enabled (MTU > 1500). Signed-off-by: Ivan Vecera Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index b9f7022f4e81..e5d95c5ce1ad 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -12286,7 +12286,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e if (tg3_flag(tp, MAX_RXPEND_64) && tp->rx_pending > 63) tp->rx_pending = 63; - tp->rx_jumbo_pending = ering->rx_jumbo_pending; + + if (tg3_flag(tp, JUMBO_RING_ENABLE)) + tp->rx_jumbo_pending = ering->rx_jumbo_pending; for (i = 0; i < tp->irq_max; i++) tp->napi[i].tx_pending = ering->tx_pending; -- GitLab From b14878ccb7fac0242db82720b784ab62c467c0dc Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 17 Apr 2014 17:26:50 +0200 Subject: [PATCH 501/797] net: sctp: cache auth_enable per endpoint Currently, it is possible to create an SCTP socket, then switch auth_enable via sysctl setting to 1 and crash the system on connect: Oops[#1]: CPU: 0 PID: 0 Comm: swapper Not tainted 3.14.1-mipsgit-20140415 #1 task: ffffffff8056ce80 ti: ffffffff8055c000 task.ti: ffffffff8055c000 [...] Call Trace: [] sctp_auth_asoc_set_default_hmac+0x68/0x80 [] sctp_process_init+0x5e0/0x8a4 [] sctp_sf_do_5_1B_init+0x234/0x34c [] sctp_do_sm+0xb4/0x1e8 [] sctp_endpoint_bh_rcv+0x1c4/0x214 [] sctp_rcv+0x588/0x630 [] sctp6_rcv+0x10/0x24 [] ip6_input+0x2c0/0x440 [] __netif_receive_skb_core+0x4a8/0x564 [] process_backlog+0xb4/0x18c [] net_rx_action+0x12c/0x210 [] __do_softirq+0x17c/0x2ac [] irq_exit+0x54/0xb0 [] ret_from_irq+0x0/0x4 [] rm7k_wait_irqoff+0x24/0x48 [] cpu_startup_entry+0xc0/0x148 [] start_kernel+0x37c/0x398 Code: dd0900b8 000330f8 0126302d 50c0fff1 0047182a a48306a0 03e00008 00000000 ---[ end trace b530b0551467f2fd ]--- Kernel panic - not syncing: Fatal exception in interrupt What happens while auth_enable=0 in that case is, that ep->auth_hmacs is initialized to NULL in sctp_auth_init_hmacs() when endpoint is being created. After that point, if an admin switches over to auth_enable=1, the machine can crash due to NULL pointer dereference during reception of an INIT chunk. When we enter sctp_process_init() via sctp_sf_do_5_1B_init() in order to respond to an INIT chunk, the INIT verification succeeds and while we walk and process all INIT params via sctp_process_param() we find that net->sctp.auth_enable is set, therefore do not fall through, but invoke sctp_auth_asoc_set_default_hmac() instead, and thus, dereference what we have set to NULL during endpoint initialization phase. The fix is to make auth_enable immutable by caching its value during endpoint initialization, so that its original value is being carried along until destruction. The bug seems to originate from the very first days. Fix in joint work with Daniel Borkmann. Reported-by: Joshua Kinard Signed-off-by: Vlad Yasevich Signed-off-by: Daniel Borkmann Acked-by: Neil Horman Tested-by: Joshua Kinard Signed-off-by: David S. Miller --- include/net/sctp/structs.h | 4 ++- net/sctp/auth.c | 17 +++++------- net/sctp/endpointola.c | 3 ++- net/sctp/sm_make_chunk.c | 32 +++++++++++----------- net/sctp/sm_statefuns.c | 6 ++--- net/sctp/socket.c | 54 ++++++++++++++++++-------------------- net/sctp/sysctl.c | 36 ++++++++++++++++++++++++- 7 files changed, 92 insertions(+), 60 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index d992ca3145fe..0dfcc92600e8 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1241,6 +1241,7 @@ struct sctp_endpoint { /* SCTP-AUTH: endpoint shared keys */ struct list_head endpoint_shared_keys; __u16 active_key_id; + __u8 auth_enable; }; /* Recover the outter endpoint structure. */ @@ -1269,7 +1270,8 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *, int sctp_has_association(struct net *net, const union sctp_addr *laddr, const union sctp_addr *paddr); -int sctp_verify_init(struct net *net, const struct sctp_association *asoc, +int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, + const struct sctp_association *asoc, sctp_cid_t, sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk, struct sctp_chunk **err_chunk); int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk, diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 683c7d1b1306..0e8529113dc5 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -386,14 +386,13 @@ int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep, */ int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) { - struct net *net = sock_net(asoc->base.sk); struct sctp_auth_bytes *secret; struct sctp_shared_key *ep_key; /* If we don't support AUTH, or peer is not capable * we don't need to do anything. */ - if (!net->sctp.auth_enable || !asoc->peer.auth_capable) + if (!asoc->ep->auth_enable || !asoc->peer.auth_capable) return 0; /* If the key_id is non-zero and we couldn't find an @@ -440,16 +439,16 @@ struct sctp_shared_key *sctp_auth_get_shkey( */ int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) { - struct net *net = sock_net(ep->base.sk); struct crypto_hash *tfm = NULL; __u16 id; - /* if the transforms are already allocted, we are done */ - if (!net->sctp.auth_enable) { + /* If AUTH extension is disabled, we are done */ + if (!ep->auth_enable) { ep->auth_hmacs = NULL; return 0; } + /* If the transforms are already allocated, we are done */ if (ep->auth_hmacs) return 0; @@ -665,12 +664,10 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param) /* Check if peer requested that this chunk is authenticated */ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) { - struct net *net; if (!asoc) return 0; - net = sock_net(asoc->base.sk); - if (!net->sctp.auth_enable || !asoc->peer.auth_capable) + if (!asoc->ep->auth_enable || !asoc->peer.auth_capable) return 0; return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); @@ -679,12 +676,10 @@ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) /* Check if we requested that peer authenticate this chunk. */ int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc) { - struct net *net; if (!asoc) return 0; - net = sock_net(asoc->base.sk); - if (!net->sctp.auth_enable) + if (!asoc->ep->auth_enable) return 0; return __sctp_auth_cid(chunk, diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 8e5fdea05216..3d9f429858dc 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -68,7 +68,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, if (!ep->digest) return NULL; - if (net->sctp.auth_enable) { + ep->auth_enable = net->sctp.auth_enable; + if (ep->auth_enable) { /* Allocate space for HMACS and CHUNKS authentication * variables. There are arrays that we encode directly * into parameters to make the rest of the operations easier. diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 3a1767ef3201..fee5552ddf92 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -219,6 +219,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, gfp_t gfp, int vparam_len) { struct net *net = sock_net(asoc->base.sk); + struct sctp_endpoint *ep = asoc->ep; sctp_inithdr_t init; union sctp_params addrs; size_t chunksize; @@ -278,7 +279,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, chunksize += vparam_len; /* Account for AUTH related parameters */ - if (net->sctp.auth_enable) { + if (ep->auth_enable) { /* Add random parameter length*/ chunksize += sizeof(asoc->c.auth_random); @@ -363,7 +364,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, } /* Add SCTP-AUTH chunks to the parameter list */ - if (net->sctp.auth_enable) { + if (ep->auth_enable) { sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), asoc->c.auth_random); if (auth_hmacs) @@ -2010,7 +2011,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc, /* if the peer reports AUTH, assume that he * supports AUTH. */ - if (net->sctp.auth_enable) + if (asoc->ep->auth_enable) asoc->peer.auth_capable = 1; break; case SCTP_CID_ASCONF: @@ -2102,6 +2103,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, * SCTP_IERROR_NO_ERROR - continue with the chunk */ static sctp_ierror_t sctp_verify_param(struct net *net, + const struct sctp_endpoint *ep, const struct sctp_association *asoc, union sctp_params param, sctp_cid_t cid, @@ -2152,7 +2154,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, goto fallthrough; case SCTP_PARAM_RANDOM: - if (!net->sctp.auth_enable) + if (!ep->auth_enable) goto fallthrough; /* SCTP-AUTH: Secion 6.1 @@ -2169,7 +2171,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, break; case SCTP_PARAM_CHUNKS: - if (!net->sctp.auth_enable) + if (!ep->auth_enable) goto fallthrough; /* SCTP-AUTH: Section 3.2 @@ -2185,7 +2187,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, break; case SCTP_PARAM_HMAC_ALGO: - if (!net->sctp.auth_enable) + if (!ep->auth_enable) goto fallthrough; hmacs = (struct sctp_hmac_algo_param *)param.p; @@ -2220,10 +2222,9 @@ static sctp_ierror_t sctp_verify_param(struct net *net, } /* Verify the INIT packet before we process it. */ -int sctp_verify_init(struct net *net, const struct sctp_association *asoc, - sctp_cid_t cid, - sctp_init_chunk_t *peer_init, - struct sctp_chunk *chunk, +int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, + const struct sctp_association *asoc, sctp_cid_t cid, + sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk, struct sctp_chunk **errp) { union sctp_params param; @@ -2264,8 +2265,8 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc, /* Verify all the variable length parameters */ sctp_walk_params(param, peer_init, init_hdr.params) { - - result = sctp_verify_param(net, asoc, param, cid, chunk, errp); + result = sctp_verify_param(net, ep, asoc, param, cid, + chunk, errp); switch (result) { case SCTP_IERROR_ABORT: case SCTP_IERROR_NOMEM: @@ -2497,6 +2498,7 @@ static int sctp_process_param(struct sctp_association *asoc, struct sctp_af *af; union sctp_addr_param *addr_param; struct sctp_transport *t; + struct sctp_endpoint *ep = asoc->ep; /* We maintain all INIT parameters in network byte order all the * time. This allows us to not worry about whether the parameters @@ -2636,7 +2638,7 @@ static int sctp_process_param(struct sctp_association *asoc, goto fall_through; case SCTP_PARAM_RANDOM: - if (!net->sctp.auth_enable) + if (!ep->auth_enable) goto fall_through; /* Save peer's random parameter */ @@ -2649,7 +2651,7 @@ static int sctp_process_param(struct sctp_association *asoc, break; case SCTP_PARAM_HMAC_ALGO: - if (!net->sctp.auth_enable) + if (!ep->auth_enable) goto fall_through; /* Save peer's HMAC list */ @@ -2665,7 +2667,7 @@ static int sctp_process_param(struct sctp_association *asoc, break; case SCTP_PARAM_CHUNKS: - if (!net->sctp.auth_enable) + if (!ep->auth_enable) goto fall_through; asoc->peer.peer_chunks = kmemdup(param.p, diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index ae9fbeba40b0..5170a1ff95a1 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c @@ -357,7 +357,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net, /* Verify the INIT chunk before processing it. */ err_chunk = NULL; - if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, + if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, &err_chunk)) { /* This chunk contains fatal error. It is to be discarded. @@ -524,7 +524,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, /* Verify the INIT chunk before processing it. */ err_chunk = NULL; - if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, + if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, &err_chunk)) { @@ -1430,7 +1430,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( /* Verify the INIT chunk before processing it. */ err_chunk = NULL; - if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, + if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, &err_chunk)) { /* This chunk contains fatal error. It is to be discarded. diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ff20e2dbbbc7..fee06b99a4da 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3321,10 +3321,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, char __user *optval, unsigned int optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authchunk val; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (optlen != sizeof(struct sctp_authchunk)) @@ -3341,7 +3341,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, } /* add this chunk id to the endpoint */ - return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk); + return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk); } /* @@ -3354,12 +3354,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, char __user *optval, unsigned int optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_hmacalgo *hmacs; u32 idents; int err; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (optlen < sizeof(struct sctp_hmacalgo)) @@ -3376,7 +3376,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, goto out; } - err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs); + err = sctp_auth_ep_set_hmacs(ep, hmacs); out: kfree(hmacs); return err; @@ -3392,12 +3392,12 @@ static int sctp_setsockopt_auth_key(struct sock *sk, char __user *optval, unsigned int optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authkey *authkey; struct sctp_association *asoc; int ret; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (optlen <= sizeof(struct sctp_authkey)) @@ -3418,7 +3418,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, goto out; } - ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); + ret = sctp_auth_set_key(ep, asoc, authkey); out: kzfree(authkey); return ret; @@ -3434,11 +3434,11 @@ static int sctp_setsockopt_active_key(struct sock *sk, char __user *optval, unsigned int optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authkeyid val; struct sctp_association *asoc; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (optlen != sizeof(struct sctp_authkeyid)) @@ -3450,8 +3450,7 @@ static int sctp_setsockopt_active_key(struct sock *sk, if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) return -EINVAL; - return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc, - val.scact_keynumber); + return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber); } /* @@ -3463,11 +3462,11 @@ static int sctp_setsockopt_del_key(struct sock *sk, char __user *optval, unsigned int optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authkeyid val; struct sctp_association *asoc; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (optlen != sizeof(struct sctp_authkeyid)) @@ -3479,8 +3478,7 @@ static int sctp_setsockopt_del_key(struct sock *sk, if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) return -EINVAL; - return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc, - val.scact_keynumber); + return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber); } @@ -5387,16 +5385,16 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, char __user *optval, int __user *optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_hmacalgo __user *p = (void __user *)optval; struct sctp_hmac_algo_param *hmacs; __u16 data_len = 0; u32 num_idents; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; - hmacs = sctp_sk(sk)->ep->auth_hmacs_list; + hmacs = ep->auth_hmacs_list; data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); if (len < sizeof(struct sctp_hmacalgo) + data_len) @@ -5417,11 +5415,11 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, static int sctp_getsockopt_active_key(struct sock *sk, int len, char __user *optval, int __user *optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authkeyid val; struct sctp_association *asoc; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (len < sizeof(struct sctp_authkeyid)) @@ -5436,7 +5434,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, if (asoc) val.scact_keynumber = asoc->active_key_id; else - val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; + val.scact_keynumber = ep->active_key_id; len = sizeof(struct sctp_authkeyid); if (put_user(len, optlen)) @@ -5450,7 +5448,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, char __user *optval, int __user *optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authchunks __user *p = (void __user *)optval; struct sctp_authchunks val; struct sctp_association *asoc; @@ -5458,7 +5456,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, u32 num_chunks = 0; char __user *to; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (len < sizeof(struct sctp_authchunks)) @@ -5495,7 +5493,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, char __user *optval, int __user *optlen) { - struct net *net = sock_net(sk); + struct sctp_endpoint *ep = sctp_sk(sk)->ep; struct sctp_authchunks __user *p = (void __user *)optval; struct sctp_authchunks val; struct sctp_association *asoc; @@ -5503,7 +5501,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, u32 num_chunks = 0; char __user *to; - if (!net->sctp.auth_enable) + if (!ep->auth_enable) return -EACCES; if (len < sizeof(struct sctp_authchunks)) @@ -5520,7 +5518,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, if (asoc) ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; else - ch = sctp_sk(sk)->ep->auth_chunk_list; + ch = ep->auth_chunk_list; if (!ch) goto num; diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 35c8923b5554..c82fdc1eab7c 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -64,6 +64,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos); +static int proc_sctp_do_auth(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos); static struct ctl_table sctp_table[] = { { @@ -266,7 +269,7 @@ static struct ctl_table sctp_net_table[] = { .data = &init_net.sctp.auth_enable, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec, + .proc_handler = proc_sctp_do_auth, }, { .procname = "addr_scope_policy", @@ -400,6 +403,37 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, return ret; } +static int proc_sctp_do_auth(struct ctl_table *ctl, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) +{ + struct net *net = current->nsproxy->net_ns; + struct ctl_table tbl; + int new_value, ret; + + memset(&tbl, 0, sizeof(struct ctl_table)); + tbl.maxlen = sizeof(unsigned int); + + if (write) + tbl.data = &new_value; + else + tbl.data = &net->sctp.auth_enable; + + ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); + + if (write) { + struct sock *sk = net->sctp.ctl_sock; + + net->sctp.auth_enable = new_value; + /* Update the value in the control socket */ + lock_sock(sk); + sctp_sk(sk)->ep->auth_enable = new_value; + release_sock(sk); + } + + return ret; +} + int sctp_sysctl_net_register(struct net *net) { struct ctl_table *table = sctp_net_table; -- GitLab From ada76576404330413eaeb864a265ad250af48d8f Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Tue, 1 Apr 2014 13:37:27 +0300 Subject: [PATCH 502/797] ARM: dts: omap5: Add clocks to USB3 PHY node The USB3 PHY driver (ti-pipe3) was updated so that the relevant clock phandles are expected in the DT node. Provide the necessary clocks. Reported-by: Kishon Vijay Abraham I Signed-off-by: Roger Quadros Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap5.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 6f3de22fb266..4db56f3569a4 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -813,6 +813,12 @@ <0x4a084c00 0x40>; reg-names = "phy_rx", "phy_tx", "pll_ctrl"; ctrl-module = <&omap_control_usb3phy>; + clocks = <&usb_phy_cm_clk32k>, + <&sys_clkin>, + <&usb_otg_ss_refclk960m>; + clock-names = "wkupclk", + "sysclk", + "refclk"; #phy-cells = <0>; }; }; -- GitLab From 8c0b4fd89ead67f5aca63abbadc81dd316b6462c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 2 Apr 2014 16:46:25 +0300 Subject: [PATCH 503/797] ARM: dts: dra7xx-clocks: Correct mcasp2_ahclkx_mux bit-shift The correct bit is 24 for AHCLKX. Signed-off-by: Peter Ujfalusi Acked-by: Tero Kristo Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/dra7xx-clocks.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/dra7xx-clocks.dtsi b/arch/arm/boot/dts/dra7xx-clocks.dtsi index e96da9a898ad..cfb8fc753f50 100644 --- a/arch/arm/boot/dts/dra7xx-clocks.dtsi +++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi @@ -1640,7 +1640,7 @@ #clock-cells = <0>; compatible = "ti,mux-clock"; clocks = <&abe_24m_fclk>, <&abe_sys_clk_div>, <&func_24m_clk>, <&atlclkin3_ck>, <&atl_clkin2_ck>, <&atl_clkin1_ck>, <&atl_clkin0_ck>, <&sys_clkin2>, <&ref_clkin0_ck>, <&ref_clkin1_ck>, <&ref_clkin2_ck>, <&ref_clkin3_ck>, <&mlb_clk>, <&mlbp_clk>; - ti,bit-shift = <28>; + ti,bit-shift = <24>; reg = <0x1860>; }; -- GitLab From 3348e28ddc0eb9749365d6e7ff9f1828667622e3 Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Tue, 8 Apr 2014 22:51:18 +0200 Subject: [PATCH 504/797] ARM: OMAP2+: N900: remove omapdss init for DT boot Do not try to initialize display for DT boot, since omapdss is now initialized via Device Tree. Without this patch the display subsystem does not properly come up. Signed-off-by: Sebastian Reichel Acked-by: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-rx51-video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c index 43a90c8d6837..9cfebc5c7455 100644 --- a/arch/arm/mach-omap2/board-rx51-video.c +++ b/arch/arm/mach-omap2/board-rx51-video.c @@ -48,7 +48,7 @@ static struct omap_dss_board_info rx51_dss_board_info = { static int __init rx51_video_init(void) { - if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900")) + if (!machine_is_nokia_rx51()) return 0; if (omap_mux_init_gpio(RX51_LCD_RESET_GPIO, OMAP_PIN_OUTPUT)) { -- GitLab From 365c107dcbd825739b88ef46cf4249a3dcb57fee Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Tue, 1 Apr 2014 18:38:13 +0200 Subject: [PATCH 505/797] ARM: AM335X: EVM: fix pinmux documentation in devicetree Wrong documentation in pinmux description can be especially confusing. Keep it proper. Signed-off-by: Wolfram Sang Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-evm.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 28ae040e7c3d..668b62f025d8 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -301,8 +301,8 @@ am335x_evm_audio_pins: am335x_evm_audio_pins { pinctrl-single,pins = < - 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rx_dv.mcasp1_aclkx */ - 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_txd3.mcasp1_fsx */ + 0x10c (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_crs.mcasp1_aclkx */ + 0x110 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* mii1_rxerr.mcasp1_fsx */ 0x108 (PIN_OUTPUT_PULLDOWN | MUX_MODE4) /* mii1_col.mcasp1_axr2 */ 0x144 (PIN_INPUT_PULLDOWN | MUX_MODE4) /* rmii1_ref_clk.mcasp1_axr3 */ >; -- GitLab From 4b549bf8bba3a65499ef8673cb1955bf4faab0de Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 8 Apr 2014 11:20:17 +0200 Subject: [PATCH 506/797] ARM: dts: OMAP2+: remove uses of obsolete gpmc,device-nand Remove all remaining uses of gpmc,device-nand that have been added since the property was removed by commit f40739faba8e ("ARM: dts: OMAP2+: Simplify NAND support"). Signed-off-by: Johan Hovold Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-igep0033.dtsi | 1 - arch/arm/boot/dts/omap3-devkit8000.dts | 1 - arch/arm/boot/dts/omap3-lilly-a83x.dtsi | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index 7063311a58d9..06c822a48b71 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -118,7 +118,6 @@ reg = <0 0 0>; /* CS0, offset 0 */ nand-bus-width = <8>; ti,nand-ecc-opt = "bch8"; - gpmc,device-nand = "true"; gpmc,device-width = <1>; gpmc,sync-clk-ps = <0>; gpmc,cs-on-ns = <0>; diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts index bf5a515a3247..da402f0fdab4 100644 --- a/arch/arm/boot/dts/omap3-devkit8000.dts +++ b/arch/arm/boot/dts/omap3-devkit8000.dts @@ -112,7 +112,6 @@ reg = <0 0 0>; /* CS0, offset 0 */ nand-bus-width = <16>; - gpmc,device-nand; gpmc,sync-clk-ps = <0>; gpmc,cs-on-ns = <0>; gpmc,cs-rd-off-ns = <44>; diff --git a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi index 6369d9f43ca2..cc1dce6978f5 100644 --- a/arch/arm/boot/dts/omap3-lilly-a83x.dtsi +++ b/arch/arm/boot/dts/omap3-lilly-a83x.dtsi @@ -368,7 +368,6 @@ /* no elm on omap3 */ gpmc,mux-add-data = <0>; - gpmc,device-nand; gpmc,device-width = <2>; gpmc,wait-pin = <0>; gpmc,wait-monitoring-ns = <0>; -- GitLab From a2f8d6b303213a98436455aece7e14cdd1240629 Mon Sep 17 00:00:00 2001 From: Leigh Brown Date: Wed, 16 Apr 2014 12:26:35 +0100 Subject: [PATCH 507/797] ARM: dts: am335x: update USB DT references In "ARM: dts: am33xx: correcting dt node unit address for usb", the usb_ctrl_mod and cppi41dma nodes were updated with the correct register addresses. However, the dts files that reference these nodes were not updated, and those devices are no longer being enabled. This patch corrects the references for the affected dts files. Signed-off-by: Leigh Brown Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am335x-bone-common.dtsi | 4 ++-- arch/arm/boot/dts/am335x-evm.dts | 4 ++-- arch/arm/boot/dts/am335x-evmsk.dts | 4 ++-- arch/arm/boot/dts/am335x-igep0033.dtsi | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi index e3f27ec31718..2e7d932887b5 100644 --- a/arch/arm/boot/dts/am335x-bone-common.dtsi +++ b/arch/arm/boot/dts/am335x-bone-common.dtsi @@ -183,7 +183,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -204,7 +204,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts index 668b62f025d8..6028217ace0f 100644 --- a/arch/arm/boot/dts/am335x-evm.dts +++ b/arch/arm/boot/dts/am335x-evm.dts @@ -331,7 +331,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -352,7 +352,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-evmsk.dts b/arch/arm/boot/dts/am335x-evmsk.dts index ec08f6f677c3..ab238850a7b2 100644 --- a/arch/arm/boot/dts/am335x-evmsk.dts +++ b/arch/arm/boot/dts/am335x-evmsk.dts @@ -364,7 +364,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -385,7 +385,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi b/arch/arm/boot/dts/am335x-igep0033.dtsi index 06c822a48b71..9f22c189f636 100644 --- a/arch/arm/boot/dts/am335x-igep0033.dtsi +++ b/arch/arm/boot/dts/am335x-igep0033.dtsi @@ -201,7 +201,7 @@ &usb { status = "okay"; - control@44e10000 { + control@44e10620 { status = "okay"; }; @@ -222,7 +222,7 @@ dr_mode = "host"; }; - dma-controller@07402000 { + dma-controller@47402000 { status = "okay"; }; }; -- GitLab From 4883fb22796ba6661ca133d389bc14157a05f480 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Tue, 1 Apr 2014 15:44:34 +0530 Subject: [PATCH 508/797] ARM: OMAP2+: Fix config name for USB3 PHY commit a70143 (drivers: phy: usb3/pipe3: Adapt pipe3 driver to Generic PHY Framework) moved phy-omap-usb3 driver in drivers/usb/phy to drivers/phy and also renamed the file to phy-ti-pipe3. It also renamed the config from OMAP_USB3 to TI_PIPE3 in Kconfig. However the config name was not changed in omap2plus_defconfig. Fixed it here. Signed-off-by: Kishon Vijay Abraham I Acked-by: Felipe Balbi Signed-off-by: Tony Lindgren --- arch/arm/configs/omap2plus_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index a9667957b757..a4e8d017f25b 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -226,7 +226,7 @@ CONFIG_USB_DWC3=m CONFIG_USB_TEST=y CONFIG_NOP_USB_XCEIV=y CONFIG_OMAP_USB2=y -CONFIG_OMAP_USB3=y +CONFIG_TI_PIPE3=y CONFIG_AM335X_PHY_USB=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DEBUG=y -- GitLab From 5c5be9db5321a457c8beee019548cb396baf81d4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Mar 2014 11:11:37 +0100 Subject: [PATCH 509/797] ARM: dts: Grammar /is uses/ is used/ Signed-off-by: Geert Uytterhoeven Cc: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am33xx.dtsi | 2 +- arch/arm/boot/dts/dra7.dtsi | 2 +- arch/arm/boot/dts/omap4.dtsi | 2 +- arch/arm/boot/dts/omap5.dtsi | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 9770e35f2536..0c2034f3b123 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -72,7 +72,7 @@ }; /* - * The soc node represents the soc top level view. It is uses for IPs + * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 1c0f8e1893ae..f56c96a2fd68 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -80,7 +80,7 @@ }; /* - * The soc node represents the soc top level view. It is uses for IPs + * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index 27fcac874742..de282e5dec39 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -72,7 +72,7 @@ }; /* - * The soc node represents the soc top level view. It is uses for IPs + * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index 4db56f3569a4..e2526b8cc68c 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -93,7 +93,7 @@ }; /* - * The soc node represents the soc top level view. It is uses for IPs + * The soc node represents the soc top level view. It is used for IPs * that are not memory mapped in the MPU view or for the MPU itself. */ soc { -- GitLab From b7ab524b9340ed3775a53e52987a3d3f1056df7c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Mar 2014 11:11:39 +0100 Subject: [PATCH 510/797] ARM: dts: Grammar /that will/it will/ Signed-off-by: Geert Uytterhoeven Cc: linux-omap@vger.kernel.org Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/am33xx.dtsi | 4 ++-- arch/arm/boot/dts/dra7.dtsi | 2 +- arch/arm/boot/dts/omap3.dtsi | 2 +- arch/arm/boot/dts/omap4.dtsi | 2 +- arch/arm/boot/dts/omap5.dtsi | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 0c2034f3b123..07f283c20eb1 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -94,8 +94,8 @@ /* * XXX: Use a flat representation of the AM33XX interconnect. - * The real AM33XX interconnect network is quite complex.Since - * that will not bring real advantage to represent that in DT + * The real AM33XX interconnect network is quite complex. Since + * it will not bring real advantage to represent that in DT * for the moment, just use a fake OCP bus entry to represent * the whole bus hierarchy. */ diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index f56c96a2fd68..149b55099935 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -94,7 +94,7 @@ /* * XXX: Use a flat representation of the SOC interconnect. * The real OMAP interconnect network is quite complex. - * Since that will not bring real advantage to represent that in DT for + * Since it will not bring real advantage to represent that in DT for * the moment, just use a fake OCP bus entry to represent the whole bus * hierarchy. */ diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi index 5e5790f631eb..acb9019dc437 100644 --- a/arch/arm/boot/dts/omap3.dtsi +++ b/arch/arm/boot/dts/omap3.dtsi @@ -74,7 +74,7 @@ /* * XXX: Use a flat representation of the OMAP3 interconnect. * The real OMAP interconnect network is quite complex. - * Since that will not bring real advantage to represent that in DT for + * Since it will not bring real advantage to represent that in DT for * the moment, just use a fake OCP bus entry to represent the whole bus * hierarchy. */ diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi index de282e5dec39..649b5cd38b40 100644 --- a/arch/arm/boot/dts/omap4.dtsi +++ b/arch/arm/boot/dts/omap4.dtsi @@ -96,7 +96,7 @@ /* * XXX: Use a flat representation of the OMAP4 interconnect. * The real OMAP interconnect network is quite complex. - * Since that will not bring real advantage to represent that in DT for + * Since it will not bring real advantage to represent that in DT for * the moment, just use a fake OCP bus entry to represent the whole bus * hierarchy. */ diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi index e2526b8cc68c..f8c9855ce587 100644 --- a/arch/arm/boot/dts/omap5.dtsi +++ b/arch/arm/boot/dts/omap5.dtsi @@ -107,7 +107,7 @@ /* * XXX: Use a flat representation of the OMAP3 interconnect. * The real OMAP interconnect network is quite complex. - * Since that will not bring real advantage to represent that in DT for + * Since it will not bring real advantage to represent that in DT for * the moment, just use a fake OCP bus entry to represent the whole bus * hierarchy. */ -- GitLab From 83da7510058736c09a14b9c17ec7d851940a4332 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 18 Apr 2014 15:07:10 -0700 Subject: [PATCH 511/797] vmscan: reclaim_clean_pages_from_list() must use mod_zone_page_state() Seems to be called with preemption enabled. Therefore it must use mod_zone_page_state instead. Signed-off-by: Christoph Lameter Reported-by: Grygorii Strashko Tested-by: Grygorii Strashko Cc: Tejun Heo Cc: Santosh Shilimkar Cc: Ingo Molnar Cc: Mel Gorman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 9b6497eda806..3f56c8deb3c0 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1158,7 +1158,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone, TTU_UNMAP|TTU_IGNORE_ACCESS, &dummy1, &dummy2, &dummy3, &dummy4, &dummy5, true); list_splice(&clean_pages, page_list); - __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret); + mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret); return ret; } -- GitLab From 82c04ff89eba09d0e46e3f3649c6d3aa18e764a0 Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Fri, 18 Apr 2014 15:07:11 -0700 Subject: [PATCH 512/797] init/Kconfig: move the trusted keyring config option to general setup The SYSTEM_TRUSTED_KEYRING config option is not in any menu, causing it to show up in the toplevel of the kernel configuration. Fix this by moving it under the General Setup menu. Signed-off-by: Peter Foley Cc: David Howells Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/Kconfig | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index 765018c24cf9..9d3585bb2a7a 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1646,6 +1646,18 @@ config MMAP_ALLOW_UNINITIALIZED See Documentation/nommu-mmap.txt for more information. +config SYSTEM_TRUSTED_KEYRING + bool "Provide system-wide ring of trusted keys" + depends on KEYS + help + Provide a system keyring to which trusted keys can be added. Keys in + the keyring are considered to be trusted. Keys may be added at will + by the kernel from compiled-in data and from hardware key stores, but + userspace may only add extra keys if those keys can be verified by + keys already in the keyring. + + Keys in this keyring are used by module signature checking. + config PROFILING bool "Profiling support" help @@ -1681,18 +1693,6 @@ config BASE_SMALL default 0 if BASE_FULL default 1 if !BASE_FULL -config SYSTEM_TRUSTED_KEYRING - bool "Provide system-wide ring of trusted keys" - depends on KEYS - help - Provide a system keyring to which trusted keys can be added. Keys in - the keyring are considered to be trusted. Keys may be added at will - by the kernel from compiled-in data and from hardware key stores, but - userspace may only add extra keys if those keys can be verified by - keys already in the keyring. - - Keys in this keyring are used by module signature checking. - menuconfig MODULES bool "Enable loadable module support" option modules -- GitLab From 7861144b8cb217634d738e94a748deeae139a1e2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 18 Apr 2014 15:07:12 -0700 Subject: [PATCH 513/797] kernel/watchdog.c:touch_softlockup_watchdog(): use raw_cpu_write() Fix: BUG: using __this_cpu_write() in preemptible [00000000] code: systemd-udevd/497 caller is __this_cpu_preempt_check+0x13/0x20 CPU: 3 PID: 497 Comm: systemd-udevd Tainted: G W 3.15.0-rc1 #9 Hardware name: Hewlett-Packard HP EliteBook 8470p/179B, BIOS 68ICF Ver. F.02 04/27/2012 Call Trace: check_preemption_disabled+0xe1/0xf0 __this_cpu_preempt_check+0x13/0x20 touch_nmi_watchdog+0x28/0x40 Reported-by: Luis Henriques Tested-by: Luis Henriques Cc: Eric Piel Cc: Robert Moore Cc: Lv Zheng Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/watchdog.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index e90089fd78e0..516203e665fc 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -138,7 +138,11 @@ static void __touch_watchdog(void) void touch_softlockup_watchdog(void) { - __this_cpu_write(watchdog_touch_ts, 0); + /* + * Preemption can be enabled. It doesn't matter which CPU's timestamp + * gets zeroed here, so use the raw_ operation. + */ + raw_cpu_write(watchdog_touch_ts, 0); } EXPORT_SYMBOL(touch_softlockup_watchdog); -- GitLab From 12c743eb2289bcaace32859d4919417ff5707768 Mon Sep 17 00:00:00 2001 From: Mike Qiu Date: Fri, 18 Apr 2014 15:07:14 -0700 Subject: [PATCH 514/797] powerpc/mm: fix ".__node_distance" undefined CHK include/config/kernel.release CHK include/generated/uapi/linux/version.h CHK include/generated/utsrelease.h ... Building modules, stage 2. WARNING: 1 bad relocations c0000000013d6a30 R_PPC64_ADDR64 uprobes_fetch_type_table WRAP arch/powerpc/boot/zImage.pseries WRAP arch/powerpc/boot/zImage.epapr MODPOST 1849 modules ERROR: ".__node_distance" [drivers/block/nvme.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 make: *** Waiting for unfinished jobs.... The reason is symbol "__node_distance" not been exported in powerpc. Signed-off-by: Mike Qiu Acked-by: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Nathan Fontenot Cc: Stephen Rothwell Cc: Srivatsa S. Bhat Cc: Jesse Larrew Cc: Robert Jennings Cc: Alistair Popple Cc: Mike Qiu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/mm/numa.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 4ebbb9e99286..3b181b22cd46 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -232,6 +232,7 @@ int __node_distance(int a, int b) return distance; } +EXPORT_SYMBOL(__node_distance); static void initialize_distance_lookup_table(int nid, const __be32 *associativity) -- GitLab From 8f28ed92d9314b98dc2033df770f5e6b85c5ffb7 Mon Sep 17 00:00:00 2001 From: Tang Chen Date: Fri, 18 Apr 2014 15:07:15 -0700 Subject: [PATCH 515/797] Documentation/vm/numa_memory_policy.txt: fix wrong document in numa_memory_policy.txt In document numa_memory_policy.txt, the following examples for flag MPOL_F_RELATIVE_NODES are incorrect. For example, consider a task that is attached to a cpuset with mems 2-5 that sets an Interleave policy over the same set with MPOL_F_RELATIVE_NODES. If the cpuset's mems change to 3-7, the interleave now occurs over nodes 3,5-6. If the cpuset's mems then change to 0,2-3,5, then the interleave occurs over nodes 0,3,5. According to the comment of the patch adding flag MPOL_F_RELATIVE_NODES, the nodemasks the user specifies should be considered relative to the current task's mems_allowed. (https://lkml.org/lkml/2008/2/29/428) And according to numa_memory_policy.txt, if the user's nodemask includes nodes that are outside the range of the new set of allowed nodes, then the remap wraps around to the beginning of the nodemask and, if not already set, sets the node in the mempolicy nodemask. So in the example, if the user specifies 2-5, for a task whose mems_allowed is 3-7, the nodemasks should be remapped the third, fourth, fifth, sixth node in mems_allowed. like the following: mems_allowed: 3 4 5 6 7 relative index: 0 1 2 3 4 5 So the nodemasks should be remapped to 3,5-7, but not 3,5-6. And for a task whose mems_allowed is 0,2-3,5, the nodemasks should be remapped to 0,2-3,5, but not 0,3,5. mems_allowed: 0 2 3 5 relative index: 0 1 2 3 4 5 Signed-off-by: Tang Chen Cc: Randy Dunlap Acked-by: David Rientjes Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/vm/numa_memory_policy.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt index 4e7da6543424..badb0507608f 100644 --- a/Documentation/vm/numa_memory_policy.txt +++ b/Documentation/vm/numa_memory_policy.txt @@ -174,7 +174,6 @@ Components of Memory Policies allocation fails, the kernel will search other nodes, in order of increasing distance from the preferred node based on information provided by the platform firmware. - containing the cpu where the allocation takes place. Internally, the Preferred policy uses a single node--the preferred_node member of struct mempolicy. When the internal @@ -275,9 +274,9 @@ Components of Memory Policies For example, consider a task that is attached to a cpuset with mems 2-5 that sets an Interleave policy over the same set with MPOL_F_RELATIVE_NODES. If the cpuset's mems change to 3-7, the - interleave now occurs over nodes 3,5-6. If the cpuset's mems + interleave now occurs over nodes 3,5-7. If the cpuset's mems then change to 0,2-3,5, then the interleave occurs over nodes - 0,3,5. + 0,2-3,5. Thanks to the consistent remapping, applications preparing nodemasks to specify memory policies using this flag should -- GitLab From 9cc236827fde5e254fd995a0023c05c5ee3a3ba6 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Fri, 18 Apr 2014 15:07:16 -0700 Subject: [PATCH 516/797] Shiraz has moved shiraz.hashim@st.com email-id doesn't exist anymore as he has left the company. Replace ST's id with shiraz.linux.kernel@gmail.com. It also updates .mailmap file to fix address for 'git shortlog'. Signed-off-by: Viresh Kumar Cc: Shiraz Hashim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- .mailmap | 1 + MAINTAINERS | 2 +- arch/arm/boot/dts/spear320-hmi.dts | 2 +- arch/arm/mach-spear/headsmp.S | 2 +- arch/arm/mach-spear/platsmp.c | 2 +- arch/arm/mach-spear/time.c | 2 +- drivers/gpio/gpio-spear-spics.c | 4 ++-- drivers/irqchip/spear-shirq.c | 2 +- drivers/mtd/devices/spear_smi.c | 4 ++-- drivers/pwm/pwm-spear.c | 4 ++-- include/linux/mtd/spear_smi.h | 2 +- 11 files changed, 14 insertions(+), 13 deletions(-) diff --git a/.mailmap b/.mailmap index 658003aa9446..df1baba43a64 100644 --- a/.mailmap +++ b/.mailmap @@ -99,6 +99,7 @@ Sachin P Sant Sam Ravnborg Sascha Hauer S.Çağlar Onur +Shiraz Hashim Simon Kelley Stéphane Witzmann Stephen Hemminger diff --git a/MAINTAINERS b/MAINTAINERS index 80399fff805d..e67ea2442041 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8315,7 +8315,7 @@ F: include/linux/compiler.h SPEAR PLATFORM SUPPORT M: Viresh Kumar -M: Shiraz Hashim +M: Shiraz Hashim L: spear-devel@list.st.com L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://www.st.com/spear diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts index 3075d2d3a8be..0aa6fef5ce22 100644 --- a/arch/arm/boot/dts/spear320-hmi.dts +++ b/arch/arm/boot/dts/spear320-hmi.dts @@ -1,7 +1,7 @@ /* * DTS file for SPEAr320 Evaluation Baord * - * Copyright 2012 Shiraz Hashim + * Copyright 2012 Shiraz Hashim * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License diff --git a/arch/arm/mach-spear/headsmp.S b/arch/arm/mach-spear/headsmp.S index ed85473a047f..c52192dc3d9f 100644 --- a/arch/arm/mach-spear/headsmp.S +++ b/arch/arm/mach-spear/headsmp.S @@ -3,7 +3,7 @@ * * Picked from realview * Copyright (c) 2012 ST Microelectronics Limited - * Shiraz Hashim + * Shiraz Hashim * * 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 diff --git a/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c index 5c4a19887b2b..c19751fff2c6 100644 --- a/arch/arm/mach-spear/platsmp.c +++ b/arch/arm/mach-spear/platsmp.c @@ -4,7 +4,7 @@ * based upon linux/arch/arm/mach-realview/platsmp.c * * Copyright (C) 2012 ST Microelectronics Ltd. - * Shiraz Hashim + * Shiraz Hashim * * 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 diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c index 218ba5b67d92..64790353951f 100644 --- a/arch/arm/mach-spear/time.c +++ b/arch/arm/mach-spear/time.c @@ -2,7 +2,7 @@ * arch/arm/plat-spear/time.c * * Copyright (C) 2010 ST Microelectronics - * Shiraz Hashim + * Shiraz Hashim * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c index e9a0415834ea..30bcc539425d 100644 --- a/drivers/gpio/gpio-spear-spics.c +++ b/drivers/gpio/gpio-spear-spics.c @@ -2,7 +2,7 @@ * SPEAr platform SPI chipselect abstraction over gpiolib * * Copyright (C) 2012 ST Microelectronics - * Shiraz Hashim + * Shiraz Hashim * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -205,6 +205,6 @@ static int __init spics_gpio_init(void) } subsys_initcall(spics_gpio_init); -MODULE_AUTHOR("Shiraz Hashim "); +MODULE_AUTHOR("Shiraz Hashim "); MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction"); MODULE_LICENSE("GPL"); diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c index 8527743b5cef..3fdda3a40269 100644 --- a/drivers/irqchip/spear-shirq.c +++ b/drivers/irqchip/spear-shirq.c @@ -5,7 +5,7 @@ * Viresh Kumar * * Copyright (C) 2012 ST Microelectronics - * Shiraz Hashim + * Shiraz Hashim * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 363da96e6891..c4176b0f382d 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c @@ -6,7 +6,7 @@ * * Copyright © 2010 STMicroelectronics. * Ashish Priyadarshi - * Shiraz Hashim + * Shiraz Hashim * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -1089,5 +1089,5 @@ static struct platform_driver spear_smi_driver = { module_platform_driver(spear_smi_driver); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim "); +MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim "); MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips"); diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c index 8ad26b8bf418..cb2d4f0f9711 100644 --- a/drivers/pwm/pwm-spear.c +++ b/drivers/pwm/pwm-spear.c @@ -2,7 +2,7 @@ * ST Microelectronics SPEAr Pulse Width Modulator driver * * Copyright (C) 2012 ST Microelectronics - * Shiraz Hashim + * Shiraz Hashim * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -264,6 +264,6 @@ static struct platform_driver spear_pwm_driver = { module_platform_driver(spear_pwm_driver); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Shiraz Hashim "); +MODULE_AUTHOR("Shiraz Hashim "); MODULE_AUTHOR("Viresh Kumar "); MODULE_ALIAS("platform:spear-pwm"); diff --git a/include/linux/mtd/spear_smi.h b/include/linux/mtd/spear_smi.h index 8ae1726044c3..581603ac1277 100644 --- a/include/linux/mtd/spear_smi.h +++ b/include/linux/mtd/spear_smi.h @@ -1,6 +1,6 @@ /* * Copyright © 2010 ST Microelectronics - * Shiraz Hashim + * Shiraz Hashim * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any -- GitLab From 8b32201de1f87878ace971bfdc2846a4f3a5bb2b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 18 Apr 2014 15:07:17 -0700 Subject: [PATCH 517/797] wait: explain the shadowing and type inconsistencies Stick in a comment before someone else tries to fix the sparse warning this generates. Suggested-by: Andrew Morton Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-o2ro6f3vkxklni0bc8f7m68s@git.kernel.org Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/wait.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/include/linux/wait.h b/include/linux/wait.h index e7d9d9ed14f5..bd68819f0815 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -191,11 +191,23 @@ wait_queue_head_t *bit_waitqueue(void *, int); (!__builtin_constant_p(state) || \ state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE) \ +/* + * The below macro ___wait_event() has an explicit shadow of the __ret + * variable when used from the wait_event_*() macros. + * + * This is so that both can use the ___wait_cond_timeout() construct + * to wrap the condition. + * + * The type inconsistency of the wait_event_*() __ret variable is also + * on purpose; we use long where we can return timeout values and int + * otherwise. + */ + #define ___wait_event(wq, condition, state, exclusive, ret, cmd) \ ({ \ __label__ __out; \ wait_queue_t __wait; \ - long __ret = ret; \ + long __ret = ret; /* explicit shadow */ \ \ INIT_LIST_HEAD(&__wait.task_list); \ if (exclusive) \ -- GitLab From 7848a4bf51b34f41fcc9bd77e837126d99ae84e3 Mon Sep 17 00:00:00 2001 From: "Mizuma, Masayoshi" Date: Fri, 18 Apr 2014 15:07:18 -0700 Subject: [PATCH 518/797] mm/hugetlb.c: add cond_resched_lock() in return_unused_surplus_pages() soft lockup in freeing gigantic hugepage fixed in commit 55f67141a892 "mm: hugetlb: fix softlockup when a large number of hugepages are freed." can happen in return_unused_surplus_pages(), so let's fix it. Signed-off-by: Masayoshi Mizuma Signed-off-by: Naoya Horiguchi Cc: Joonsoo Kim Cc: Michal Hocko Cc: Aneesh Kumar Cc: KOSAKI Motohiro Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/hugetlb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index dd30f22b35e0..246192929a2d 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1172,6 +1172,7 @@ static void return_unused_surplus_pages(struct hstate *h, while (nr_pages--) { if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1)) break; + cond_resched_lock(&hugetlb_lock); } } -- GitLab From 8229f1a044894f84324292608c149f0b4563532b Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 18 Apr 2014 15:07:19 -0700 Subject: [PATCH 519/797] mips: export flush_icache_range The lkdtm module performs tests against executable memory ranges, so it needs to flush the icache for proper behaviors. Other architectures already export this, so do the same for MIPS. [akpm@linux-foundation.org: relocate export sites] Signed-off-by: Kees Cook Cc: Paul Gortmaker Cc: Ralf Baechle Cc: Sanjay Lal Cc: John Crispin Cc: Sergei Shtylyov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/mips/mm/cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index e422b38d3113..9e67cdea3c74 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -29,15 +29,15 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn); void (*flush_icache_range)(unsigned long start, unsigned long end); +EXPORT_SYMBOL_GPL(flush_icache_range); void (*local_flush_icache_range)(unsigned long start, unsigned long end); void (*__flush_cache_vmap)(void); void (*__flush_cache_vunmap)(void); void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size); -void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); - EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range); +void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size); /* MIPS specific cache operations */ void (*flush_cache_sigtramp)(unsigned long addr); -- GitLab From 29c7787075c92ca8af353acd5301481e6f37082f Mon Sep 17 00:00:00 2001 From: Mel Gorman Date: Fri, 18 Apr 2014 15:07:21 -0700 Subject: [PATCH 520/797] mm: use paravirt friendly ops for NUMA hinting ptes David Vrabel identified a regression when using automatic NUMA balancing under Xen whereby page table entries were getting corrupted due to the use of native PTE operations. Quoting him Xen PV guest page tables require that their entries use machine addresses if the preset bit (_PAGE_PRESENT) is set, and (for successful migration) non-present PTEs must use pseudo-physical addresses. This is because on migration MFNs in present PTEs are translated to PFNs (canonicalised) so they may be translated back to the new MFN in the destination domain (uncanonicalised). pte_mknonnuma(), pmd_mknonnuma(), pte_mknuma() and pmd_mknuma() set and clear the _PAGE_PRESENT bit using pte_set_flags(), pte_clear_flags(), etc. In a Xen PV guest, these functions must translate MFNs to PFNs when clearing _PAGE_PRESENT and translate PFNs to MFNs when setting _PAGE_PRESENT. His suggested fix converted p[te|md]_[set|clear]_flags to using paravirt-friendly ops but this is overkill. He suggested an alternative of using p[te|md]_modify in the NUMA page table operations but this is does more work than necessary and would require looking up a VMA for protections. This patch modifies the NUMA page table operations to use paravirt friendly operations to set/clear the flags of interest. Unfortunately this will take a performance hit when updating the PTEs on CONFIG_PARAVIRT but I do not see a way around it that does not break Xen. Signed-off-by: Mel Gorman Acked-by: David Vrabel Tested-by: David Vrabel Cc: Ingo Molnar Cc: Peter Anvin Cc: Fengguang Wu Cc: Linus Torvalds Cc: Steven Noonan Cc: Rik van Riel Cc: Peter Zijlstra Cc: Andrea Arcangeli Cc: Dave Hansen Cc: Srikar Dronamraju Cc: Cyrill Gorcunov Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-generic/pgtable.h | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 1ec08c198b66..a8015a7a55bb 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -693,24 +693,35 @@ static inline int pmd_numa(pmd_t pmd) #ifndef pte_mknonnuma static inline pte_t pte_mknonnuma(pte_t pte) { - pte = pte_clear_flags(pte, _PAGE_NUMA); - return pte_set_flags(pte, _PAGE_PRESENT|_PAGE_ACCESSED); + pteval_t val = pte_val(pte); + + val &= ~_PAGE_NUMA; + val |= (_PAGE_PRESENT|_PAGE_ACCESSED); + return __pte(val); } #endif #ifndef pmd_mknonnuma static inline pmd_t pmd_mknonnuma(pmd_t pmd) { - pmd = pmd_clear_flags(pmd, _PAGE_NUMA); - return pmd_set_flags(pmd, _PAGE_PRESENT|_PAGE_ACCESSED); + pmdval_t val = pmd_val(pmd); + + val &= ~_PAGE_NUMA; + val |= (_PAGE_PRESENT|_PAGE_ACCESSED); + + return __pmd(val); } #endif #ifndef pte_mknuma static inline pte_t pte_mknuma(pte_t pte) { - pte = pte_set_flags(pte, _PAGE_NUMA); - return pte_clear_flags(pte, _PAGE_PRESENT); + pteval_t val = pte_val(pte); + + val &= ~_PAGE_PRESENT; + val |= _PAGE_NUMA; + + return __pte(val); } #endif @@ -729,8 +740,12 @@ static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr, #ifndef pmd_mknuma static inline pmd_t pmd_mknuma(pmd_t pmd) { - pmd = pmd_set_flags(pmd, _PAGE_NUMA); - return pmd_clear_flags(pmd, _PAGE_PRESENT); + pmdval_t val = pmd_val(pmd); + + val &= ~_PAGE_PRESENT; + val |= _PAGE_NUMA; + + return __pmd(val); } #endif -- GitLab From a663dad65f3f41a0f9a8d0f2f1bc352524c4ff65 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Fri, 18 Apr 2014 15:07:22 -0700 Subject: [PATCH 521/797] mm: fix CONFIG_DEBUG_VM_RB description This appears to be a copy/paste error. Update the description to reflect extra rbtree debug and checks for the config option instead of duplicating CONFIG_DEBUG_VM. Signed-off-by: Davidlohr Bueso Cc: Aswin Chandramouleeswaran Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- lib/Kconfig.debug | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 140b66a874c1..819ac51202c0 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -505,8 +505,7 @@ config DEBUG_VM_RB bool "Debug VM red-black trees" depends on DEBUG_VM help - Enable this to turn on more extended checks in the virtual-memory - system that may impact performance. + Enable VM red-black tree debugging information and extra validations. If unsure, say N. -- GitLab From b59b8cbca6291a23928f1a103defba03d1cdab2c Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 18 Apr 2014 15:07:23 -0700 Subject: [PATCH 522/797] mm: fix new kernel-doc warning in filemap.c Fix new kernel-doc warning in mm/filemap.c: Warning(mm/filemap.c:2600): Excess function parameter 'ppos' description in '__generic_file_aio_write' Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/filemap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mm/filemap.c b/mm/filemap.c index a82fbe4c9e8e..5020b280a771 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2581,7 +2581,6 @@ EXPORT_SYMBOL(generic_perform_write); * @iocb: IO state structure (file, offset, etc.) * @iov: vector with data to write * @nr_segs: number of segments in the vector - * @ppos: position where to write * * This function does all the work needed for actually writing data to a * file. It does all basic checks, removes SUID from the file, updates -- GitLab From b5a8cad376eebbd8598642697e92a27983aee802 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Fri, 18 Apr 2014 15:07:25 -0700 Subject: [PATCH 523/797] thp: close race between split and zap huge pages Sasha Levin has reported two THP BUGs[1][2]. I believe both of them have the same root cause. Let's look to them one by one. The first bug[1] is "kernel BUG at mm/huge_memory.c:1829!". It's BUG_ON(mapcount != page_mapcount(page)) in __split_huge_page(). From my testing I see that page_mapcount() is higher than mapcount here. I think it happens due to race between zap_huge_pmd() and page_check_address_pmd(). page_check_address_pmd() misses PMD which is under zap: CPU0 CPU1 zap_huge_pmd() pmdp_get_and_clear() __split_huge_page() anon_vma_interval_tree_foreach() __split_huge_page_splitting() page_check_address_pmd() mm_find_pmd() /* * We check if PMD present without taking ptl: no * serialization against zap_huge_pmd(). We miss this PMD, * it's not accounted to 'mapcount' in __split_huge_page(). */ pmd_present(pmd) == 0 BUG_ON(mapcount != page_mapcount(page)) // CRASH!!! page_remove_rmap(page) atomic_add_negative(-1, &page->_mapcount) The second bug[2] is "kernel BUG at mm/huge_memory.c:1371!". It's VM_BUG_ON_PAGE(!PageHead(page), page) in zap_huge_pmd(). This happens in similar way: CPU0 CPU1 zap_huge_pmd() pmdp_get_and_clear() page_remove_rmap(page) atomic_add_negative(-1, &page->_mapcount) __split_huge_page() anon_vma_interval_tree_foreach() __split_huge_page_splitting() page_check_address_pmd() mm_find_pmd() pmd_present(pmd) == 0 /* The same comment as above */ /* * No crash this time since we already decremented page->_mapcount in * zap_huge_pmd(). */ BUG_ON(mapcount != page_mapcount(page)) /* * We split the compound page here into small pages without * serialization against zap_huge_pmd() */ __split_huge_page_refcount() VM_BUG_ON_PAGE(!PageHead(page), page); // CRASH!!! So my understanding the problem is pmd_present() check in mm_find_pmd() without taking page table lock. The bug was introduced by me commit with commit 117b0791ac42. Sorry for that. :( Let's open code mm_find_pmd() in page_check_address_pmd() and do the check under page table lock. Note that __page_check_address() does the same for PTE entires if sync != 0. I've stress tested split and zap code paths for 36+ hours by now and don't see crashes with the patch applied. Before it took <20 min to trigger the first bug and few hours for second one (if we ignore first). [1] https://lkml.kernel.org/g/<53440991.9090001@oracle.com> [2] https://lkml.kernel.org/g/<5310C56C.60709@oracle.com> Signed-off-by: Kirill A. Shutemov Reported-by: Sasha Levin Tested-by: Sasha Levin Cc: Bob Liu Cc: Andrea Arcangeli Cc: Rik van Riel Cc: Mel Gorman Cc: Michel Lespinasse Cc: Dave Jones Cc: Vlastimil Babka Cc: [3.13+] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/huge_memory.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 64635f5278ff..b4b1feba6472 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1536,16 +1536,23 @@ pmd_t *page_check_address_pmd(struct page *page, enum page_check_address_pmd_flag flag, spinlock_t **ptl) { + pgd_t *pgd; + pud_t *pud; pmd_t *pmd; if (address & ~HPAGE_PMD_MASK) return NULL; - pmd = mm_find_pmd(mm, address); - if (!pmd) + pgd = pgd_offset(mm, address); + if (!pgd_present(*pgd)) return NULL; + pud = pud_offset(pgd, address); + if (!pud_present(*pud)) + return NULL; + pmd = pmd_offset(pud, address); + *ptl = pmd_lock(mm, pmd); - if (pmd_none(*pmd)) + if (!pmd_present(*pmd)) goto unlock; if (pmd_page(*pmd) != page) goto unlock; -- GitLab From ef78f3869c37c480f1d58462a760a40dabc823f4 Mon Sep 17 00:00:00 2001 From: Robert Nelson Date: Tue, 15 Apr 2014 10:09:59 -0500 Subject: [PATCH 524/797] ARM: dts: Add support for the BeagleBoard xM A/B BeagleBoard xM A/B has an inverted usb hub enable line vs the xM C Signed-off-by: Robert Nelson [tony@atomide.com: updated for missing bracket] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/omap3-beagle-xm-ab.dts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 arch/arm/boot/dts/omap3-beagle-xm-ab.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 35c146f31e46..0bdeba3f2da4 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -246,6 +246,7 @@ dtb-$(CONFIG_ARCH_OMAP2PLUS) += omap2420-h4.dtb \ omap3-sbc-t3730.dtb \ omap3-devkit8000.dtb \ omap3-beagle-xm.dtb \ + omap3-beagle-xm-ab.dtb \ omap3-evm.dtb \ omap3-evm-37xx.dtb \ omap3-ldp.dtb \ diff --git a/arch/arm/boot/dts/omap3-beagle-xm-ab.dts b/arch/arm/boot/dts/omap3-beagle-xm-ab.dts new file mode 100644 index 000000000000..7ac3bcf59d59 --- /dev/null +++ b/arch/arm/boot/dts/omap3-beagle-xm-ab.dts @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 "omap3-beagle-xm.dts" + +/ { + /* HS USB Port 2 Power enable was inverted with the xM C */ + hsusb2_power: hsusb2_power_reg { + enable-active-high; + }; +}; -- GitLab From 76e6dcece841faebbee78895780e8209ff40d922 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 18 Apr 2014 09:08:11 -0400 Subject: [PATCH 525/797] drm/radeon: disable dpm on rv770 by default There seem to be stability issues on a number of cards. bugs: https://bugs.freedesktop.org/show_bug.cgi?id=76286 https://bugzilla.redhat.com/show_bug.cgi?id=1085785 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=741619 Signed-off-by: Alex Deucher Cc: matthias.graf@st.ovqu.de Cc: bp@alien8.de Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index ee738a524639..0c4473db8501 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1257,6 +1257,7 @@ int radeon_pm_init(struct radeon_device *rdev) case CHIP_RV670: case CHIP_RS780: case CHIP_RS880: + case CHIP_RV770: case CHIP_BARTS: case CHIP_TURKS: case CHIP_CAICOS: @@ -1273,7 +1274,6 @@ int radeon_pm_init(struct radeon_device *rdev) else rdev->pm.pm_method = PM_METHOD_PROFILE; break; - case CHIP_RV770: case CHIP_RV730: case CHIP_RV710: case CHIP_RV740: -- GitLab From 24315814239a3fdb306244c99bd076bc79db4ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 19 Apr 2014 18:57:14 +0200 Subject: [PATCH 526/797] drm/radeon: use fixed PPL ref divider if needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- drivers/gpu/drm/radeon/radeon_display.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 2f7cbb901fb1..e6c3c5488259 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -880,7 +880,12 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, ref_div_min = pll->reference_div; else ref_div_min = pll->min_ref_div; - ref_div_max = pll->max_ref_div; + + if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && + pll->flags & RADEON_PLL_USE_REF_DIV) + ref_div_max = pll->reference_div; + else + ref_div_max = pll->max_ref_div; /* determine allowed post divider range */ if (pll->flags & RADEON_PLL_USE_POST_DIV) { -- GitLab From 404ca80eb5c2727d78cd517d12108b040c522e12 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Sat, 19 Apr 2014 10:15:07 -0700 Subject: [PATCH 527/797] coredump: fix va_list corruption A va_list needs to be copied in case it needs to be used twice. Thanks to Hugh for debugging this issue, leading to various panics. Tested: lpq84:~# echo "|/foobar12345 %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h" >/proc/sys/kernel/core_pattern 'produce_core' is simply : main() { *(int *)0 = 1;} lpq84:~# ./produce_core Segmentation fault (core dumped) lpq84:~# dmesg | tail -1 [ 614.352947] Core dump to |/foobar12345 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 lpq84 (null) pipe failed Notice the last argument was replaced by a NULL (we were lucky enough to not crash, but do not try this on your production machine !) After fix : lpq83:~# echo "|/foobar12345 %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h %h" >/proc/sys/kernel/core_pattern lpq83:~# ./produce_core Segmentation fault lpq83:~# dmesg | tail -1 [ 740.800441] Core dump to |/foobar12345 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 lpq83 pipe failed Fixes: 5fe9d8ca21cc ("coredump: cn_vprintf() has no reason to call vsnprintf() twice") Signed-off-by: Eric Dumazet Diagnosed-by: Hugh Dickins Acked-by: Oleg Nesterov Cc: Neil Horman Cc: Andrew Morton Cc: stable@vger.kernel.org # 3.11+ Signed-off-by: Linus Torvalds --- fs/coredump.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/coredump.c b/fs/coredump.c index e3ad709a4232..0b2528fb640e 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -73,10 +73,15 @@ static int expand_corename(struct core_name *cn, int size) static int cn_vprintf(struct core_name *cn, const char *fmt, va_list arg) { int free, need; + va_list arg_copy; again: free = cn->size - cn->used; - need = vsnprintf(cn->corename + cn->used, free, fmt, arg); + + va_copy(arg_copy, arg); + need = vsnprintf(cn->corename + cn->used, free, fmt, arg_copy); + va_end(arg_copy); + if (need < free) { cn->used += need; return 0; -- GitLab From a8680e0d5efd46aa54d7085e5b4a268f726922c7 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sat, 19 Apr 2014 16:37:31 -0400 Subject: [PATCH 528/797] ext4: fix COLLAPSE_RANGE failure with 1KB block size When formatting with 1KB or 2KB(not aligned with PAGE SIZE) block size, xfstests generic/075 and 091 are failing. The offset supplied to function truncate_pagecache_range is block size aligned. In this function start offset is re-aligned to PAGE_SIZE by rounding_up to the next page boundary. Due to this rounding up, old data remains in the page cache when blocksize is less than page size and start offset is not aligned with page size. In case of collapse range, we need to align start offset to page size boundary by doing a round down operation instead of round up. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 9b9251adb400..d6bca2a1debe 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5395,7 +5395,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) ext4_lblk_t punch_start, punch_stop; handle_t *handle; unsigned int credits; - loff_t new_size; + loff_t new_size, ioffset; int ret; /* Collapse range works only on fs block size aligned offsets. */ @@ -5418,8 +5418,15 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) return ret; } + /* + * Need to round down offset to be aligned with page size boundary + * for page size > block size. + */ + ioffset = round_down(offset, PAGE_SIZE); + /* Write out all dirty pages */ - ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); + ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, + LLONG_MAX); if (ret) return ret; @@ -5441,7 +5448,7 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) goto out_mutex; } - truncate_pagecache(inode, offset); + truncate_pagecache(inode, ioffset); /* Wait for existing dio to complete */ ext4_inode_block_unlocked_dio(inode); -- GitLab From 0a04b248532b358b27a8da050642da6f5f304b03 Mon Sep 17 00:00:00 2001 From: Namjae Jeon Date: Sat, 19 Apr 2014 16:38:21 -0400 Subject: [PATCH 529/797] ext4: disable COLLAPSE_RANGE for bigalloc Once COLLAPSE RANGE is be disable for ext4 with bigalloc feature till finding root-cause of problem. It will be enable with fixing that regression of xfstest(generic 075 and 091) again. Signed-off-by: Namjae Jeon Signed-off-by: Ashish Sangwan Reviewed-by: Lukas Czerner Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index d6bca2a1debe..01b0c208f625 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5406,6 +5406,9 @@ int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len) if (!S_ISREG(inode->i_mode)) return -EINVAL; + if (EXT4_SB(inode->i_sb)->s_cluster_ratio > 1) + return -EOPNOTSUPP; + trace_ext4_collapse_range(inode, offset, len); punch_start = offset >> EXT4_BLOCK_SIZE_BITS(sb); -- GitLab From 06491e84f0f95dbe105b74fef32e7063e349f2d7 Mon Sep 17 00:00:00 2001 From: Adam Thomson Date: Tue, 8 Apr 2014 13:55:17 -0700 Subject: [PATCH 530/797] Input: da9055_onkey - remove use of regmap_irq_get_virq() Using platform_get_irq_byname() to retrieve the IRQ number returns the VIRQ number rather than the local IRQ number for the device. Passing that value then into regmap_irq_get_virq() causes a failure because the function is expecting the local IRQ number (e.g. 0, 1, 2, 3, etc). This patch removes use of regmap_irq_get_virq() to prevent this failure from happening. Signed-off-by: Adam Thomson Signed-off-by: Andrew Morton Signed-off-by: Dmitry Torokhov --- drivers/input/misc/da9055_onkey.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/input/misc/da9055_onkey.c b/drivers/input/misc/da9055_onkey.c index 4b11ede34950..4765799fef74 100644 --- a/drivers/input/misc/da9055_onkey.c +++ b/drivers/input/misc/da9055_onkey.c @@ -109,7 +109,6 @@ static int da9055_onkey_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&onkey->work, da9055_onkey_work); - irq = regmap_irq_get_virq(da9055->irq_data, irq); err = request_threaded_irq(irq, NULL, da9055_onkey_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "ONKEY", onkey); -- GitLab From 2fdf4cd9a2afb113e566dfe6ee5df55ada8c0631 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Sat, 12 Apr 2014 13:42:24 -0700 Subject: [PATCH 531/797] Input: ads7846 - fix device usage within attribute show With commit e585c40ba (Input: ads7846 - convert to hwmon_device_register_with_groups()) the device passed to the attribute's show function isn't the spi device as before. So fixup the passed device to ads7846_read12_ser. Signed-off-by: Alexander Stein Acked-by: Guenter Roeck Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 45a06e495ed2..7f8aa981500d 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -425,7 +425,7 @@ static int ads7845_read12_ser(struct device *dev, unsigned command) name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct ads7846 *ts = dev_get_drvdata(dev); \ - ssize_t v = ads7846_read12_ser(dev, \ + ssize_t v = ads7846_read12_ser(&ts->spi->dev, \ READ_12BIT_SER(var)); \ if (v < 0) \ return v; \ -- GitLab From 91ae0e77836b4a13f511b4fc62dc31c523858187 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Sat, 12 Apr 2014 13:43:25 -0700 Subject: [PATCH 532/797] Input: wacom - missed the last bit of expresskey for DTU-1031 Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 05f371df6c40..3d094c95851d 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1838,7 +1838,7 @@ int wacom_setup_input_capabilities(struct input_dev *input_dev, case DTU: if (features->type == DTUS) { input_set_capability(input_dev, EV_MSC, MSC_SERIAL); - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) __set_bit(BTN_0 + i, input_dev->keybit); } __set_bit(BTN_TOOL_PEN, input_dev->keybit); -- GitLab From 5866d9e3b7ecdf96a6089d12bb65736d7c473bce Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Sat, 19 Apr 2014 13:46:40 -0700 Subject: [PATCH 533/797] Input: wacom - use full 32-bit HID Usage value in switch statement A HID Usage is a 32-bit value: an upper 16-bit "page" and a lower 16-bit ID. While the two halves are normally reported seperately, only the combination uniquely idenfifes a particular HID Usage. The existing code performs the comparison in two steps, first performing a switch on the ID and then verifying the page within each case. While this works fine, it is very akward to handle two Usages that share a single ID, such as HID_USAGE_PRESSURE and HID_USAGE_X because the case statement can only have a single identifier. To work around this, we now check the full 32-bit HID Usage directly rather than first checking the ID and then the page. This allows the switch statement to have distinct cases for e.g. HID_USAGE_PRESSURE and HID_USAGE_X. Signed-off-by: Jason Gerecke Tested-by: Aaron Skomra Reviewed-by: Carl Worth Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 237 ++++++++++++++----------------- 1 file changed, 109 insertions(+), 128 deletions(-) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b16ebef5b911..5be617755461 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -22,23 +22,17 @@ #define HID_USAGE_PAGE_DIGITIZER 0x0d #define HID_USAGE_PAGE_DESKTOP 0x01 #define HID_USAGE 0x09 -#define HID_USAGE_X 0x30 -#define HID_USAGE_Y 0x31 -#define HID_USAGE_X_TILT 0x3d -#define HID_USAGE_Y_TILT 0x3e -#define HID_USAGE_FINGER 0x22 -#define HID_USAGE_STYLUS 0x20 -#define HID_USAGE_CONTACTMAX 0x55 +#define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30) +#define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d) +#define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e) +#define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22) +#define HID_USAGE_STYLUS ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x20) +#define HID_USAGE_CONTACTMAX ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x55) #define HID_COLLECTION 0xa1 #define HID_COLLECTION_LOGICAL 0x02 #define HID_COLLECTION_END 0xc0 -enum { - WCM_UNDEFINED = 0, - WCM_DESKTOP, - WCM_DIGITIZER, -}; - struct hid_descriptor { struct usb_descriptor_header header; __le16 bcdHID; @@ -305,7 +299,7 @@ static int wacom_parse_hid(struct usb_interface *intf, char limit = 0; /* result has to be defined as int for some devices */ int result = 0, touch_max = 0; - int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0; + int i = 0, page = 0, finger = 0, pen = 0; unsigned char *report; report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL); @@ -332,134 +326,121 @@ static int wacom_parse_hid(struct usb_interface *intf, switch (report[i]) { case HID_USAGE_PAGE: - switch (report[i + 1]) { - case HID_USAGE_PAGE_DIGITIZER: - usage = WCM_DIGITIZER; - i++; - break; - - case HID_USAGE_PAGE_DESKTOP: - usage = WCM_DESKTOP; - i++; - break; - } + page = report[i + 1]; + i++; break; case HID_USAGE: - switch (report[i + 1]) { + switch (page << 16 | report[i + 1]) { case HID_USAGE_X: - if (usage == WCM_DESKTOP) { - if (finger) { - features->device_type = BTN_TOOL_FINGER; - /* touch device at least supports one touch point */ - touch_max = 1; - switch (features->type) { - case TABLETPC2FG: - features->pktlen = WACOM_PKGLEN_TPC2FG; - break; - - case MTSCREEN: - case WACOM_24HDT: - features->pktlen = WACOM_PKGLEN_MTOUCH; - break; - - case MTTPC: - features->pktlen = WACOM_PKGLEN_MTTPC; - break; - - case BAMBOO_PT: - features->pktlen = WACOM_PKGLEN_BBTOUCH; - break; - - default: - features->pktlen = WACOM_PKGLEN_GRAPHIRE; - break; - } - - switch (features->type) { - case BAMBOO_PT: - features->x_phy = - get_unaligned_le16(&report[i + 5]); - features->x_max = - get_unaligned_le16(&report[i + 8]); - i += 15; - break; - - case WACOM_24HDT: - features->x_max = - get_unaligned_le16(&report[i + 3]); - features->x_phy = - get_unaligned_le16(&report[i + 8]); - features->unit = report[i - 1]; - features->unitExpo = report[i - 3]; - i += 12; - break; - - default: - features->x_max = - get_unaligned_le16(&report[i + 3]); - features->x_phy = - get_unaligned_le16(&report[i + 6]); - features->unit = report[i + 9]; - features->unitExpo = report[i + 11]; - i += 12; - break; - } - } else if (pen) { - /* penabled only accepts exact bytes of data */ - if (features->type >= TABLETPC) - features->pktlen = WACOM_PKGLEN_GRAPHIRE; - features->device_type = BTN_TOOL_PEN; + if (finger) { + features->device_type = BTN_TOOL_FINGER; + /* touch device at least supports one touch point */ + touch_max = 1; + switch (features->type) { + case TABLETPC2FG: + features->pktlen = WACOM_PKGLEN_TPC2FG; + break; + + case MTSCREEN: + case WACOM_24HDT: + features->pktlen = WACOM_PKGLEN_MTOUCH; + break; + + case MTTPC: + features->pktlen = WACOM_PKGLEN_MTTPC; + break; + + case BAMBOO_PT: + features->pktlen = WACOM_PKGLEN_BBTOUCH; + break; + + default: + features->pktlen = WACOM_PKGLEN_GRAPHIRE; + break; + } + + switch (features->type) { + case BAMBOO_PT: + features->x_phy = + get_unaligned_le16(&report[i + 5]); + features->x_max = + get_unaligned_le16(&report[i + 8]); + i += 15; + break; + + case WACOM_24HDT: features->x_max = get_unaligned_le16(&report[i + 3]); - i += 4; + features->x_phy = + get_unaligned_le16(&report[i + 8]); + features->unit = report[i - 1]; + features->unitExpo = report[i - 3]; + i += 12; + break; + + default: + features->x_max = + get_unaligned_le16(&report[i + 3]); + features->x_phy = + get_unaligned_le16(&report[i + 6]); + features->unit = report[i + 9]; + features->unitExpo = report[i + 11]; + i += 12; + break; } + } else if (pen) { + /* penabled only accepts exact bytes of data */ + if (features->type >= TABLETPC) + features->pktlen = WACOM_PKGLEN_GRAPHIRE; + features->device_type = BTN_TOOL_PEN; + features->x_max = + get_unaligned_le16(&report[i + 3]); + i += 4; } break; case HID_USAGE_Y: - if (usage == WCM_DESKTOP) { - if (finger) { - switch (features->type) { - case TABLETPC2FG: - case MTSCREEN: - case MTTPC: - features->y_max = - get_unaligned_le16(&report[i + 3]); - features->y_phy = - get_unaligned_le16(&report[i + 6]); - i += 7; - break; - - case WACOM_24HDT: - features->y_max = - get_unaligned_le16(&report[i + 3]); - features->y_phy = - get_unaligned_le16(&report[i - 2]); - i += 7; - break; - - case BAMBOO_PT: - features->y_phy = - get_unaligned_le16(&report[i + 3]); - features->y_max = - get_unaligned_le16(&report[i + 6]); - i += 12; - break; - - default: - features->y_max = - features->x_max; - features->y_phy = - get_unaligned_le16(&report[i + 3]); - i += 4; - break; - } - } else if (pen) { + if (finger) { + switch (features->type) { + case TABLETPC2FG: + case MTSCREEN: + case MTTPC: + features->y_max = + get_unaligned_le16(&report[i + 3]); + features->y_phy = + get_unaligned_le16(&report[i + 6]); + i += 7; + break; + + case WACOM_24HDT: + features->y_max = + get_unaligned_le16(&report[i + 3]); + features->y_phy = + get_unaligned_le16(&report[i - 2]); + i += 7; + break; + + case BAMBOO_PT: + features->y_phy = + get_unaligned_le16(&report[i + 3]); + features->y_max = + get_unaligned_le16(&report[i + 6]); + i += 12; + break; + + default: features->y_max = + features->x_max; + features->y_phy = get_unaligned_le16(&report[i + 3]); i += 4; + break; } + } else if (pen) { + features->y_max = + get_unaligned_le16(&report[i + 3]); + i += 4; } break; @@ -489,7 +470,7 @@ static int wacom_parse_hid(struct usb_interface *intf, case HID_COLLECTION_END: /* reset UsagePage and Finger */ - finger = usage = 0; + finger = page = 0; break; case HID_COLLECTION: -- GitLab From e9fc413f4a5ebd9f0f7bdf923c43191e99fc1970 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Sat, 19 Apr 2014 13:49:37 -0700 Subject: [PATCH 534/797] Input: wacom - override 'pressure_max' with value from HID_USAGE_PRESSURE The 0xEC sensor is used in multiple tablet PCs and curiously has versions that report 256 levels of pressure (Samsung Slate 7) as well as versions that report 1024 levels (Lenovo Thinkpad Yoga). To allow both versions to work properly, we allow the value of HID_USAGE_PRESSURE reported to override pressure_max. Signed-off-by: Jason Gerecke Tested-by: Aaron Skomra Reviewed-by: Carl Worth Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 5be617755461..611fc3905d00 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -24,6 +24,7 @@ #define HID_USAGE 0x09 #define HID_USAGE_X ((HID_USAGE_PAGE_DESKTOP << 16) | 0x30) #define HID_USAGE_Y ((HID_USAGE_PAGE_DESKTOP << 16) | 0x31) +#define HID_USAGE_PRESSURE ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x30) #define HID_USAGE_X_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3d) #define HID_USAGE_Y_TILT ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x3e) #define HID_USAGE_FINGER ((HID_USAGE_PAGE_DIGITIZER << 16) | 0x22) @@ -465,6 +466,14 @@ static int wacom_parse_hid(struct usb_interface *intf, wacom_retrieve_report_data(intf, features); i++; break; + + case HID_USAGE_PRESSURE: + if (pen) { + features->pressure_max = + get_unaligned_le16(&report[i + 3]); + i += 4; + } + break; } break; -- GitLab From 74b634178e5f0e2d8d2d26f308c440687930274b Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Sat, 19 Apr 2014 13:50:22 -0700 Subject: [PATCH 535/797] Input: wacom - references to 'wacom->data' should use 'unsigned char*' 'wacom->data' contains raw binary data and can lead to unexpected behavior if a byte under examination happens to have its MSB set. Signed-off-by: Jason Gerecke Tested-by: Aaron Skomra Reviewed-by: Carl Worth Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 3d094c95851d..99710e9fdd6a 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -178,10 +178,9 @@ static int wacom_ptu_irq(struct wacom_wac *wacom) static int wacom_dtu_irq(struct wacom_wac *wacom) { - struct wacom_features *features = &wacom->features; - char *data = wacom->data; + unsigned char *data = wacom->data; struct input_dev *input = wacom->input; - int prox = data[1] & 0x20, pressure; + int prox = data[1] & 0x20; dev_dbg(input->dev.parent, "%s: received report #%d", __func__, data[0]); @@ -198,10 +197,7 @@ static int wacom_dtu_irq(struct wacom_wac *wacom) input_report_key(input, BTN_STYLUS2, data[1] & 0x10); input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = features->pressure_max + pressure + 1; - input_report_abs(input, ABS_PRESSURE, pressure); + input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]); input_report_key(input, BTN_TOUCH, data[1] & 0x05); if (!prox) /* out-prox */ wacom->id[0] = 0; @@ -906,7 +902,7 @@ static int int_dist(int x1, int y1, int x2, int y2) static int wacom_24hdt_irq(struct wacom_wac *wacom) { struct input_dev *input = wacom->input; - char *data = wacom->data; + unsigned char *data = wacom->data; int i; int current_num_contacts = data[61]; int contacts_to_send = 0; @@ -959,7 +955,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) static int wacom_mt_touch(struct wacom_wac *wacom) { struct input_dev *input = wacom->input; - char *data = wacom->data; + unsigned char *data = wacom->data; int i; int current_num_contacts = data[2]; int contacts_to_send = 0; @@ -1038,7 +1034,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom) static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) { - char *data = wacom->data; + unsigned char *data = wacom->data; struct input_dev *input = wacom->input; bool prox; int x = 0, y = 0; @@ -1074,10 +1070,8 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) static int wacom_tpc_pen(struct wacom_wac *wacom) { - struct wacom_features *features = &wacom->features; - char *data = wacom->data; + unsigned char *data = wacom->data; struct input_dev *input = wacom->input; - int pressure; bool prox = data[1] & 0x20; if (!wacom->shared->stylus_in_proximity) /* first in prox */ @@ -1093,10 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom) input_report_key(input, BTN_STYLUS2, data[1] & 0x10); input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - pressure = ((data[7] & 0x01) << 8) | data[6]; - if (pressure < 0) - pressure = features->pressure_max + pressure + 1; - input_report_abs(input, ABS_PRESSURE, pressure); + input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]); input_report_key(input, BTN_TOUCH, data[1] & 0x05); input_report_key(input, wacom->tool[0], prox); return 1; @@ -1107,7 +1098,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom) static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) { - char *data = wacom->data; + unsigned char *data = wacom->data; dev_dbg(wacom->input->dev.parent, "%s: received report #%d\n", __func__, data[0]); -- GitLab From 38a1807badd26d413e8f2b0393a0c5bfdf9e912b Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Sat, 19 Apr 2014 13:51:41 -0700 Subject: [PATCH 536/797] Input: wacom - handle 1024 pressure levels in wacom_tpc_pen Some tablet PC sensors (e.g. the 0xEC found in the Thinkpad Yoga) report more than 256 pressure levels and will experience wraparound unless the full range is read. Signed-off-by: Jason Gerecke Tested-by: Aaron Skomra Reviewed-by: Carl Worth Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 99710e9fdd6a..4822c57a3756 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1087,7 +1087,7 @@ static int wacom_tpc_pen(struct wacom_wac *wacom) input_report_key(input, BTN_STYLUS2, data[1] & 0x10); input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); input_report_abs(input, ABS_Y, le16_to_cpup((__le16 *)&data[4])); - input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x01) << 8) | data[6]); + input_report_abs(input, ABS_PRESSURE, ((data[7] & 0x03) << 8) | data[6]); input_report_key(input, BTN_TOUCH, data[1] & 0x05); input_report_key(input, wacom->tool[0], prox); return 1; -- GitLab From acb61fc8ed73eb477a9044272d7a1b1f5a572f91 Mon Sep 17 00:00:00 2001 From: Alexander Yarygin Date: Wed, 9 Apr 2014 16:21:59 +0200 Subject: [PATCH 537/797] perf kvm: Fix 'Min time' counting in report command Every event in the perf-kvm has a 'stats' structure, which contains max/min/average/etc times of handling this event. The problem is that the 'perf-kvm stat report' command always shows that 'min time' is 0us for every event. Example: # perf kvm stat report Analyze events for all VCPUs: VM-EXIT Samples Samples% Time% Min Time Max Time Avg time [..] 0xB2 MSCH 12 0.07% 0.00% 0us 8us 7.31us ( +- 2.11% ) 0xB2 CHSC 12 0.07% 0.00% 0us 18us 9.39us ( +- 9.49% ) 0xB2 STPX 8 0.05% 0.00% 0us 2us 1.88us ( +- 7.18% ) 0xB2 STSI 7 0.04% 0.00% 0us 44us 16.49us ( +- 38.20% ) [..] This happens because the 'stats' structure is not initialized and stats->min equals to 0. Lets initialize the structure for every event after its allocation using init_stats() function. This initializes stats->min to -1 and makes 'Min time' statistics counting work: # perf kvm stat report Analyze events for all VCPUs: VM-EXIT Samples Samples% Time% Min Time Max Time Avg time [..] 0xB2 MSCH 12 0.07% 0.00% 6us 8us 7.31us ( +- 2.11% ) 0xB2 CHSC 12 0.07% 0.00% 7us 18us 9.39us ( +- 9.49% ) 0xB2 STPX 8 0.05% 0.00% 1us 2us 1.88us ( +- 7.18% ) 0xB2 STSI 7 0.04% 0.00% 1us 44us 16.49us ( +- 38.20% ) [..] Signed-off-by: Alexander Yarygin Signed-off-by: Christian Borntraeger Reviewed-by: David Ahern Link: http://lkml.kernel.org/r/1397053319-2130-3-git-send-email-borntraeger@de.ibm.com [ Fixing the perf examples changelog output ] Signed-off-by: Jiri Olsa --- tools/perf/builtin-kvm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 21c164b8f9db..0f1e5a2f6ad7 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -404,6 +404,7 @@ static struct kvm_event *kvm_alloc_init_event(struct event_key *key) } event->key = *key; + init_stats(&event->total.stats); return event; } -- GitLab From 922d0e4d9f042f68baea28e5b3bd7bb708875f2e Mon Sep 17 00:00:00 2001 From: Vladimir Nikulichev Date: Thu, 17 Apr 2014 08:27:01 -0700 Subject: [PATCH 538/797] perf tools: Adjust symbols in VDSO pert-report doesn't resolve function names in VDSO: $ perf report --stdio -g flat,0.0,15,callee --sort pid ... 8.76% 0x7fff6b1fe861 __gettimeofday ACE_OS::gettimeofday() ... In this case symbol values should be adjusted the same way as for executables, relocatable objects and prelinked libraries. After fix: $ perf report --stdio -g flat,0.0,15,callee --sort pid ... 8.76% __vdso_gettimeofday __gettimeofday ACE_OS::gettimeofday() Signed-off-by: Vladimir Nikulichev Tested-by: Namhyung Kim Reviewed-by: Adrian Hunter Link: http://lkml.kernel.org/r/969812.163009436-sendEmail@nvs Signed-off-by: Jiri Olsa --- tools/perf/util/symbol-elf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 3b7dbf51d4a9..6864661a79dd 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -6,6 +6,7 @@ #include #include "symbol.h" +#include "vdso.h" #include #include "debug.h" @@ -618,6 +619,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, GElf_Shdr shdr; ss->adjust_symbols = (ehdr.e_type == ET_EXEC || ehdr.e_type == ET_REL || + is_vdso_map(dso->short_name) || elf_section_by_name(elf, &ehdr, &shdr, ".gnu.prelink_undo", NULL) != NULL); -- GitLab From ffa91880a992ec1aaee4b4f7c9ddffda0c277ba9 Mon Sep 17 00:00:00 2001 From: Adrien BAK Date: Fri, 18 Apr 2014 11:00:43 +0900 Subject: [PATCH 539/797] perf tools: Improve error reporting In the current version, when using perf record, if something goes wrong in tools/perf/builtin-record.c:375 session = perf_session__new(file, false, NULL); The error message: "Not enough memory for reading per file header" is issued. This error message seems to be outdated and is not very helpful. This patch proposes to replace this error message by "Perf session creation failed" I believe this issue has been brought to lkml: https://lkml.org/lkml/2014/2/24/458 although this patch only tackles a (small) part of the issue. Additionnaly, this patch improves error reporting in tools/perf/util/data.c open_file_write. Currently, if the call to open fails, the user is unaware of it. This patch logs the error, before returning the error code to the caller. Reported-by: Will Deacon Signed-off-by: Adrien BAK Link: http://lkml.kernel.org/r/1397786443.3093.4.camel@beast [ Reorganize the changelog into paragraphs ] [ Added empty line after fd declaration in open_file_write ] Signed-off-by: Jiri Olsa --- tools/perf/builtin-record.c | 2 +- tools/perf/util/data.c | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index eb524f91bffe..8ce62ef7f6c3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -374,7 +374,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) session = perf_session__new(file, false, NULL); if (session == NULL) { - pr_err("Not enough memory for reading perf file header\n"); + pr_err("Perf session creation failed.\n"); return -1; } diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 1fbcd8bdc11b..55de44ecebef 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -86,10 +86,17 @@ static int open_file_read(struct perf_data_file *file) static int open_file_write(struct perf_data_file *file) { + int fd; + if (check_backup(file)) return -1; - return open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); + + if (fd < 0) + pr_err("failed to open %s : %s\n", file->path, strerror(errno)); + + return fd; } static int open_file(struct perf_data_file *file) -- GitLab From 0456c66f4e905e1ca839318219c770988b47975c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 20:39:35 -0700 Subject: [PATCH 540/797] Input: serio - add firmware_id sysfs attribute serio devices exposed via platform firmware interfaces such as ACPI may provide additional identifying information of use to userspace. We don't associate the serio devices with the firmware device (we don't set it as parent), so there's no way for userspace to make use of this information. We cannot change the parent for serio devices instantiated though a firmware interface as that would break suspend / resume ordering. Therefore this patch adds a new firmware_id sysfs attribute so that userspace can get a string from there with any additional identifying information the firmware interface may provide. Signed-off-by: Hans de Goede Acked-by: Peter Hutterer Signed-off-by: Dmitry Torokhov --- drivers/input/serio/serio.c | 14 ++++++++++++++ include/linux/serio.h | 1 + 2 files changed, 15 insertions(+) diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 8f4c4ab04bc2..b29134de983b 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -451,6 +451,13 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute * return retval; } +static ssize_t firmware_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct serio *serio = to_serio_port(dev); + + return sprintf(buf, "%s\n", serio->firmware_id); +} + static DEVICE_ATTR_RO(type); static DEVICE_ATTR_RO(proto); static DEVICE_ATTR_RO(id); @@ -473,12 +480,14 @@ static DEVICE_ATTR_RO(modalias); static DEVICE_ATTR_WO(drvctl); static DEVICE_ATTR(description, S_IRUGO, serio_show_description, NULL); static DEVICE_ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode); +static DEVICE_ATTR_RO(firmware_id); static struct attribute *serio_device_attrs[] = { &dev_attr_modalias.attr, &dev_attr_description.attr, &dev_attr_drvctl.attr, &dev_attr_bind_mode.attr, + &dev_attr_firmware_id.attr, NULL }; @@ -921,9 +930,14 @@ static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto); SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id); SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); + SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); + if (serio->firmware_id[0]) + SERIO_ADD_UEVENT_VAR("SERIO_FIRMWARE_ID=%s", + serio->firmware_id); + return 0; } #undef SERIO_ADD_UEVENT_VAR diff --git a/include/linux/serio.h b/include/linux/serio.h index 36aac733840a..9f779c7a2da4 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h @@ -23,6 +23,7 @@ struct serio { char name[32]; char phys[32]; + char firmware_id[128]; bool manual_bind; -- GitLab From a7c5868c3482127cb308c779b8a6460a3353c17f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 20:47:35 -0700 Subject: [PATCH 541/797] Input: i8042 - add firmware_id support Fill in the new serio firmware_id sysfs attribute for pnp instantiated 8042 serio ports. Signed-off-by: Hans de Goede Acked-by: Peter Hutterer Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 15 +++++++++++++++ drivers/input/serio/i8042.c | 6 ++++++ 2 files changed, 21 insertions(+) diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 0ec9abbe31fe..381b20d4c561 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -702,6 +702,17 @@ static int i8042_pnp_aux_irq; static char i8042_pnp_kbd_name[32]; static char i8042_pnp_aux_name[32]; +static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size) +{ + strlcpy(dst, "PNP:", dst_size); + + while (id) { + strlcat(dst, " ", dst_size); + strlcat(dst, id->id, dst_size); + id = id->next; + } +} + static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did) { if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1) @@ -718,6 +729,8 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id * strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name)); strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name)); } + i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id, + sizeof(i8042_kbd_firmware_id)); /* Keyboard ports are always supposed to be wakeup-enabled */ device_set_wakeup_enable(&dev->dev, true); @@ -742,6 +755,8 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id * strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name)); strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name)); } + i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id, + sizeof(i8042_aux_firmware_id)); i8042_pnp_aux_devices++; return 0; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 020053fa5aaa..3807c3e971cc 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -87,6 +87,8 @@ MODULE_PARM_DESC(debug, "Turn i8042 debugging mode on and off"); #endif static bool i8042_bypass_aux_irq_test; +static char i8042_kbd_firmware_id[128]; +static char i8042_aux_firmware_id[128]; #include "i8042.h" @@ -1218,6 +1220,8 @@ static int __init i8042_create_kbd_port(void) serio->dev.parent = &i8042_platform_device->dev; strlcpy(serio->name, "i8042 KBD port", sizeof(serio->name)); strlcpy(serio->phys, I8042_KBD_PHYS_DESC, sizeof(serio->phys)); + strlcpy(serio->firmware_id, i8042_kbd_firmware_id, + sizeof(serio->firmware_id)); port->serio = serio; port->irq = I8042_KBD_IRQ; @@ -1244,6 +1248,8 @@ static int __init i8042_create_aux_port(int idx) if (idx < 0) { strlcpy(serio->name, "i8042 AUX port", sizeof(serio->name)); strlcpy(serio->phys, I8042_AUX_PHYS_DESC, sizeof(serio->phys)); + strlcpy(serio->firmware_id, i8042_aux_firmware_id, + sizeof(serio->firmware_id)); serio->close = i8042_port_close; } else { snprintf(serio->name, sizeof(serio->name), "i8042 AUX%d port", idx); -- GitLab From f37c013409bb78ebb958821aa10d069e707cabac Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 22:25:45 -0700 Subject: [PATCH 542/797] Input: Add INPUT_PROP_TOPBUTTONPAD device property On some newer laptops with a trackpoint the physical buttons for the trackpoint have been removed to allow for a larger touchpad. On these laptops the buttonpad has clearly marked areas on the top which are to be used as trackpad buttons. Users of the event device-node need to know about this, so that they can properly interpret BTN_LEFT events as being a left / right / middle click depending on where on the button pad the clicking finger is. This commits adds a INPUT_PROP_TOPBUTTONPAD device property which drivers for such buttonpads will use to signal to the user that this buttonpad not only has the normal bottom button area, but also a top button area. Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- include/uapi/linux/input.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h index bd24470d24a2..f4849525519c 100644 --- a/include/uapi/linux/input.h +++ b/include/uapi/linux/input.h @@ -164,6 +164,7 @@ struct input_keymap_entry { #define INPUT_PROP_DIRECT 0x01 /* direct input devices */ #define INPUT_PROP_BUTTONPAD 0x02 /* has button(s) under pad */ #define INPUT_PROP_SEMI_MT 0x03 /* touch rectangle only */ +#define INPUT_PROP_TOPBUTTONPAD 0x04 /* softbuttons at top of pad */ #define INPUT_PROP_MAX 0x1f #define INPUT_PROP_CNT (INPUT_PROP_MAX + 1) -- GitLab From 43e19888b1fe2a3e8a5543030c5b286cde38b3f5 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 22:26:41 -0700 Subject: [PATCH 543/797] Input: synaptics - report INPUT_PROP_TOPBUTTONPAD property Check PNP ID of the PS/2 AUX port and report INPUT_PROP_TOPBUTTONPAD property for for touchpads with top button areas. Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 55 +++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index d8d49d10f9bb..9d754103337d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -117,6 +117,44 @@ void synaptics_reset(struct psmouse *psmouse) } #ifdef CONFIG_MOUSE_PS2_SYNAPTICS +/* This list has been kindly provided by Synaptics. */ +static const char * const topbuttonpad_pnp_ids[] = { + "LEN0017", + "LEN0018", + "LEN0019", + "LEN0023", + "LEN002A", + "LEN002B", + "LEN002C", + "LEN002D", + "LEN002E", + "LEN0033", /* Helix */ + "LEN0034", /* T431s, T540, X1 Carbon 2nd */ + "LEN0035", /* X240 */ + "LEN0036", /* T440 */ + "LEN0037", + "LEN0038", + "LEN0041", + "LEN0042", /* Yoga */ + "LEN0045", + "LEN0046", + "LEN0047", + "LEN0048", + "LEN0049", + "LEN2000", + "LEN2001", + "LEN2002", + "LEN2003", + "LEN2004", /* L440 */ + "LEN2005", + "LEN2006", + "LEN2007", + "LEN2008", + "LEN2009", + "LEN200A", + "LEN200B", + NULL +}; /***************************************************************************** * Synaptics communications functions @@ -1255,8 +1293,10 @@ static void set_abs_position_params(struct input_dev *dev, input_abs_set_res(dev, y_code, priv->y_res); } -static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) +static void set_input_params(struct psmouse *psmouse, + struct synaptics_data *priv) { + struct input_dev *dev = psmouse->dev; int i; /* Things that apply to both modes */ @@ -1325,6 +1365,17 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) { __set_bit(INPUT_PROP_BUTTONPAD, dev->propbit); + /* See if this buttonpad has a top button area */ + if (!strncmp(psmouse->ps2dev.serio->firmware_id, "PNP:", 4)) { + for (i = 0; topbuttonpad_pnp_ids[i]; i++) { + if (strstr(psmouse->ps2dev.serio->firmware_id, + topbuttonpad_pnp_ids[i])) { + __set_bit(INPUT_PROP_TOPBUTTONPAD, + dev->propbit); + break; + } + } + } /* Clickpads report only left button */ __clear_bit(BTN_RIGHT, dev->keybit); __clear_bit(BTN_MIDDLE, dev->keybit); @@ -1593,7 +1644,7 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) priv->capabilities, priv->ext_cap, priv->ext_cap_0c, priv->board_id, priv->firmware_id); - set_input_params(psmouse->dev, priv); + set_input_params(psmouse, priv); /* * Encode touchpad model so that it can be used to set -- GitLab From 46a2986ebbe18757c2d8c352f8fb6e0f4f0754e3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 19 Apr 2014 22:31:18 -0700 Subject: [PATCH 544/797] Input: synaptics - add min/max quirk for ThinkPad T431s, L440, L540, S1 Yoga and X1 We expect that all the Haswell series will need such quirks, sigh. The T431s seems to be T430 hardware in a T440s case, using the T440s touchpad, with the same min/max issue. The X1 Carbon 3rd generation name says 2nd while it is a 3rd generation. The X1 and T431s share a PnPID with the T540p, but the reported ranges are closer to those of the T440s. HdG: Squashed 5 quirk patches into one. T431s + L440 + L540 are written by me, S1 Yoga and X1 are written by Benjamin Tissoires. Hdg: Standardized S1 Yoga and X1 values, Yoga uses the same touchpad as the X240, X1 uses the same touchpad as the T440. Cc: stable@vger.kernel.org Signed-off-by: Benjamin Tissoires Signed-off-by: Hans de Goede Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 9d754103337d..ef9f4913450d 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -1565,6 +1565,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1232, 5710, 1156, 4696}, }, + { + /* Lenovo ThinkPad T431s */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T431"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, { /* Lenovo ThinkPad T440s */ .matches = { @@ -1573,6 +1581,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1024, 5112, 2024, 4832}, }, + { + /* Lenovo ThinkPad L440 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L440"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, { /* Lenovo ThinkPad T540p */ .matches = { @@ -1581,6 +1597,32 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { }, .driver_data = (int []){1024, 5056, 2058, 4832}, }, + { + /* Lenovo ThinkPad L540 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L540"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, + { + /* Lenovo Yoga S1 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, + "ThinkPad S1 Yoga"), + }, + .driver_data = (int []){1232, 5710, 1156, 4696}, + }, + { + /* Lenovo ThinkPad X1 Carbon Haswell (3rd generation) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, + "ThinkPad X1 Carbon 2nd"), + }, + .driver_data = (int []){1024, 5112, 2024, 4832}, + }, #endif { } }; -- GitLab From c2fb3094669a3205f16a32f4119d0afe40b1a1fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 20 Apr 2014 13:24:32 +0200 Subject: [PATCH 545/797] drm/radeon: improve PLL limit handling in post div calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This improves the PLL parameters when we work at the limits of the allowed ranges. Signed-off-by: Christian König --- drivers/gpu/drm/radeon/radeon_display.c | 77 ++++++++++++++++--------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index e6c3c5488259..8d99d5ee8014 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -839,6 +839,38 @@ static void avivo_reduce_ratio(unsigned *nom, unsigned *den, } } +/** + * avivo_get_fb_ref_div - feedback and ref divider calculation + * + * @nom: nominator + * @den: denominator + * @post_div: post divider + * @fb_div_max: feedback divider maximum + * @ref_div_max: reference divider maximum + * @fb_div: resulting feedback divider + * @ref_div: resulting reference divider + * + * Calculate feedback and reference divider for a given post divider. Makes + * sure we stay within the limits. + */ +static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div, + unsigned fb_div_max, unsigned ref_div_max, + unsigned *fb_div, unsigned *ref_div) +{ + /* limit reference * post divider to a maximum */ + ref_div_max = min(210 / post_div, ref_div_max); + + /* get matching reference and feedback divider */ + *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max); + *fb_div = DIV_ROUND_CLOSEST(nom * *ref_div * post_div, den); + + /* limit fb divider to its maximum */ + if (*fb_div > fb_div_max) { + *ref_div = DIV_ROUND_CLOSEST(*ref_div * fb_div_max, *fb_div); + *fb_div = fb_div_max; + } +} + /** * radeon_compute_pll_avivo - compute PLL paramaters * @@ -860,6 +892,9 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, u32 *ref_div_p, u32 *post_div_p) { + unsigned target_clock = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ? + freq : freq / 10; + unsigned fb_div_min, fb_div_max, fb_div; unsigned post_div_min, post_div_max, post_div; unsigned ref_div_min, ref_div_max, ref_div; @@ -892,7 +927,6 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, post_div_min = pll->post_div; post_div_max = pll->post_div; } else { - unsigned target_clock = freq / 10; unsigned vco_min, vco_max; if (pll->flags & RADEON_PLL_IS_LCD) { @@ -903,6 +937,11 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, vco_max = pll->pll_out_max; } + if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { + vco_min *= 10; + vco_max *= 10; + } + post_div_min = vco_min / target_clock; if ((target_clock * post_div_min) < vco_min) ++post_div_min; @@ -917,7 +956,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, } /* represent the searched ratio as fractional number */ - nom = pll->flags & RADEON_PLL_USE_FRAC_FB_DIV ? freq : freq / 10; + nom = target_clock; den = pll->reference_freq; /* reduce the numbers to a simpler ratio */ @@ -931,7 +970,12 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, diff_best = ~0; for (post_div = post_div_min; post_div <= post_div_max; ++post_div) { - unsigned diff = abs(den - den / post_div * post_div); + unsigned diff; + avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, + ref_div_max, &fb_div, &ref_div); + diff = abs(target_clock - (pll->reference_freq * fb_div) / + (ref_div * post_div)); + if (diff < diff_best || (diff == diff_best && !(pll->flags & RADEON_PLL_PREFER_MINM_OVER_MAXP))) { @@ -941,28 +985,9 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, } post_div = post_div_best; - /* limit reference * post divider to a maximum */ - ref_div_max = min(210 / post_div, ref_div_max); - - /* get matching reference and feedback divider */ - ref_div = max(DIV_ROUND_CLOSEST(den, post_div), 1u); - fb_div = DIV_ROUND_CLOSEST(nom * ref_div * post_div, den); - - /* we're almost done, but reference and feedback - divider might be to large now */ - - nom = fb_div; - den = ref_div; - - if (fb_div > fb_div_max) { - ref_div = DIV_ROUND_CLOSEST(den * fb_div_max, nom); - fb_div = fb_div_max; - } - - if (ref_div > ref_div_max) { - ref_div = ref_div_max; - fb_div = DIV_ROUND_CLOSEST(nom * ref_div_max, den); - } + /* get the feedback and reference divider for the optimal value */ + avivo_get_fb_ref_div(nom, den, post_div, fb_div_max, ref_div_max, + &fb_div, &ref_div); /* reduce the numbers to a simpler ratio once more */ /* this also makes sure that the reference divider is large enough */ @@ -984,7 +1009,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, *post_div_p = post_div; DRM_DEBUG_KMS("%d - %d, pll dividers - fb: %d.%d ref: %d, post %d\n", - freq, *dot_clock_p, *fb_div_p, *frac_fb_div_p, + freq, *dot_clock_p * 10, *fb_div_p, *frac_fb_div_p, ref_div, post_div); } -- GitLab From a798c10faf62a505d24e5f6213fbaf904a39623f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 20 Apr 2014 11:08:50 -0700 Subject: [PATCH 546/797] Linux 3.15-rc2 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 60ccbfe750a2..80a2d2448531 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 15 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = -rc2 NAME = Shuffling Zombie Juror # *DOCUMENTATION* -- GitLab From da343fc776e0bcb238b65d9d24610819b95d0ef4 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 18 Apr 2014 14:19:47 +0200 Subject: [PATCH 547/797] irqchip: armada-370-xp: fix invalid cast of signed value into unsigned variable The armada_370_xp_alloc_msi() function returns a signed int, which is negative on error. However, we store the return value into an irq_hw_number_t, which is unsigned. Therefore, we actually never test if armada_370_xp_alloc_msi() returns an error or not, which may lead us to use hwirq numbers of as 0xffffffe4 (when armada_370_xp_alloc_msi() returns -ENOSPC). This commit fixes that by storing the return value of armada_370_xp_alloc_msi() in a signed variable. Fixes: 31f614edb726fcc4d5aa0f2895fbdec9b04a3ca4 ('irqchip: armada-370-xp: implement MSI support') Cc: # v3.13+ Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397823593-1932-2-git-send-email-thomas.petazzoni@free-electrons.com Tested-by: Neil Greatorex Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 41be897df8d5..3c8d89b62a21 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -132,8 +132,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip *chip, struct msi_desc *desc) { struct msi_msg msg; - irq_hw_number_t hwirq; - int virq; + int virq, hwirq; hwirq = armada_370_xp_alloc_msi(); if (hwirq < 0) -- GitLab From 830cbe4b7a918613276aa3d3b28d24410623f92c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Fri, 18 Apr 2014 14:19:48 +0200 Subject: [PATCH 548/797] irqchip: armada-370-xp: implement the ->check_device() msi_chip operation Until now, we were leaving the ->check_device() msi_chip operation empty, which leads the PCI core to believe that we support both MSI and MSI-X. In fact, we do not support MSI-X, so we have to tell this to the PCI core by providing an implementation of this operation. Fixes: 31f614edb726fcc4d5aa0f2895fbdec9b04a3ca4 ('irqchip: armada-370-xp: implement MSI support') Cc: # v3.13+ Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397823593-1932-3-git-send-email-thomas.petazzoni@free-electrons.com Tested-by: Neil Greatorex Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 3c8d89b62a21..78b0ac9129d7 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -162,6 +162,15 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip, armada_370_xp_free_msi(d->hwirq); } +static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct pci_dev *dev, + int nvec, int type) +{ + /* We support MSI, but not MSI-X */ + if (type == PCI_CAP_ID_MSI) + return 0; + return -EINVAL; +} + static struct irq_chip armada_370_xp_msi_irq_chip = { .name = "armada_370_xp_msi_irq", .irq_enable = unmask_msi_irq, @@ -200,6 +209,7 @@ static int armada_370_xp_msi_init(struct device_node *node, msi_chip->setup_irq = armada_370_xp_setup_msi_irq; msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq; + msi_chip->check_device = armada_370_xp_check_msi_device; msi_chip->of_node = node; armada_370_xp_msi_domain = -- GitLab From ff3c664505bf8a8334bca5045e87b85cfe4d2277 Mon Sep 17 00:00:00 2001 From: Neil Greatorex Date: Fri, 18 Apr 2014 14:19:49 +0200 Subject: [PATCH 549/797] irqchip: armada-370-xp: Fix releasing of MSIs Store the value of d->hwirq in a local variable as the real value is wiped out by calling irq_dispose_mapping. Without this patch, the armada_370_xp_free_msi function would always free MSI#0, no matter what was passed to it. Fixes: 31f614edb726fcc4d5aa0f2895fbdec9b04a3ca4 ('irqchip: armada-370-xp: implement MSI support') Cc: # v3.13+ Signed-off-by: Neil Greatorex Link: https://lkml.kernel.org/r/1397823593-1932-4-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397823593-1932-4-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 78b0ac9129d7..868d11bc00d2 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -158,8 +158,10 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip, unsigned int irq) { struct irq_data *d = irq_get_irq_data(irq); + unsigned long hwirq = d->hwirq; + irq_dispose_mapping(irq); - armada_370_xp_free_msi(d->hwirq); + armada_370_xp_free_msi(hwirq); } static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct pci_dev *dev, -- GitLab From 0d71832e3004a0833938cc28a096823cd55b8e79 Mon Sep 17 00:00:00 2001 From: Tristan Schmelcher Date: Mon, 11 Nov 2013 13:03:06 -0500 Subject: [PATCH 550/797] uml: Simplify tempdir logic. Inferring the mount hierarchy correctly from /proc/mounts is hard when MS_MOVE may have been used, and the previous code did it wrongly. This change simplifies the logic to only require that /dev/shm be _on_ tmpfs (which can be checked trivially with statfs) rather than that it be a _mountpoint_ of tmpfs, since there isn't a compelling reason to be that strict. We also now check for tmpfs on whatever directory we ultimately use so that the user is better informed. This change also moves the more standard TMPDIR environment variable check ahead of the others. Applies to 3.12. Signed-off-by: Tristan Schmelcher Signed-off-by: Richard Weinberger --- arch/um/os-Linux/mem.c | 372 +++++++++-------------------------------- 1 file changed, 75 insertions(+), 297 deletions(-) diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 3c4af77e51a2..897e9ad0c108 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c @@ -12,337 +12,117 @@ #include #include #include -#include +#include +#include #include #include -/* Modified by which_tmpdir, which is called during early boot */ -static char *default_tmpdir = "/tmp"; - -/* - * Modified when creating the physical memory file and when checking - * the tmp filesystem for usability, both happening during early boot. - */ +/* Set by make_tempfile() during early boot. */ static char *tempdir = NULL; -static void __init find_tempdir(void) +/* Check if dir is on tmpfs. Return 0 if yes, -1 if no or error. */ +static int __init check_tmpfs(const char *dir) { - const char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; - int i; - char *dir = NULL; - - if (tempdir != NULL) - /* We've already been called */ - return; - for (i = 0; dirs[i]; i++) { - dir = getenv(dirs[i]); - if ((dir != NULL) && (*dir != '\0')) - break; - } - if ((dir == NULL) || (*dir == '\0')) - dir = default_tmpdir; + struct statfs st; - tempdir = malloc(strlen(dir) + 2); - if (tempdir == NULL) { - fprintf(stderr, "Failed to malloc tempdir, " - "errno = %d\n", errno); - return; - } - strcpy(tempdir, dir); - strcat(tempdir, "/"); -} - -/* - * Remove bytes from the front of the buffer and refill it so that if there's a - * partial string that we care about, it will be completed, and we can recognize - * it. - */ -static int pop(int fd, char *buf, size_t size, size_t npop) -{ - ssize_t n; - size_t len = strlen(&buf[npop]); - - memmove(buf, &buf[npop], len + 1); - n = read(fd, &buf[len], size - len - 1); - if (n < 0) - return -errno; - - buf[len + n] = '\0'; - return 1; -} - -/* - * This will return 1, with the first character in buf being the - * character following the next instance of c in the file. This will - * read the file as needed. If there's an error, -errno is returned; - * if the end of the file is reached, 0 is returned. - */ -static int next(int fd, char *buf, size_t size, char c) -{ - ssize_t n; - char *ptr; - - while ((ptr = strchr(buf, c)) == NULL) { - n = read(fd, buf, size - 1); - if (n == 0) - return 0; - else if (n < 0) - return -errno; - - buf[n] = '\0'; + printf("Checking if %s is on tmpfs...", dir); + if (statfs(dir, &st) < 0) { + printf("%s\n", strerror(errno)); + } else if (st.f_type != TMPFS_MAGIC) { + printf("no\n"); + } else { + printf("OK\n"); + return 0; } - - return pop(fd, buf, size, ptr - buf + 1); + return -1; } /* - * Decode an octal-escaped and space-terminated path of the form used by - * /proc/mounts. May be used to decode a path in-place. "out" must be at least - * as large as the input. The output is always null-terminated. "len" gets the - * length of the output, excluding the trailing null. Returns 0 if a full path - * was successfully decoded, otherwise an error. + * Choose the tempdir to use. We want something on tmpfs so that our memory is + * not subject to the host's vm.dirty_ratio. If a tempdir is specified in the + * environment, we use that even if it's not on tmpfs, but we warn the user. + * Otherwise, we try common tmpfs locations, and if no tmpfs directory is found + * then we fall back to /tmp. */ -static int decode_path(const char *in, char *out, size_t *len) +static char * __init choose_tempdir(void) { - char *first = out; - int c; + static const char * const vars[] = { + "TMPDIR", + "TMP", + "TEMP", + NULL + }; + static const char fallback_dir[] = "/tmp"; + static const char * const tmpfs_dirs[] = { + "/dev/shm", + fallback_dir, + NULL + }; int i; - int ret = -EINVAL; - while (1) { - switch (*in) { - case '\0': - goto out; - - case ' ': - ret = 0; - goto out; - - case '\\': - in++; - c = 0; - for (i = 0; i < 3; i++) { - if (*in < '0' || *in > '7') - goto out; - c = (c << 3) | (*in++ - '0'); - } - *(unsigned char *)out++ = (unsigned char) c; - break; - - default: - *out++ = *in++; - break; + const char *dir; + + printf("Checking environment variables for a tempdir..."); + for (i = 0; vars[i]; i++) { + dir = getenv(vars[i]); + if ((dir != NULL) && (*dir != '\0')) { + printf("%s\n", dir); + if (check_tmpfs(dir) >= 0) + goto done; + else + goto warn; } } + printf("none found\n"); -out: - *out = '\0'; - *len = out - first; - return ret; -} - -/* - * Computes the length of s when encoded with three-digit octal escape sequences - * for the characters in chars. - */ -static size_t octal_encoded_length(const char *s, const char *chars) -{ - size_t len = strlen(s); - while ((s = strpbrk(s, chars)) != NULL) { - len += 3; - s++; - } - - return len; -} - -enum { - OUTCOME_NOTHING_MOUNTED, - OUTCOME_TMPFS_MOUNT, - OUTCOME_NON_TMPFS_MOUNT, -}; - -/* Read a line of /proc/mounts data looking for a tmpfs mount at "path". */ -static int read_mount(int fd, char *buf, size_t bufsize, const char *path, - int *outcome) -{ - int found; - int match; - char *space; - size_t len; - - enum { - MATCH_NONE, - MATCH_EXACT, - MATCH_PARENT, - }; - - found = next(fd, buf, bufsize, ' '); - if (found != 1) - return found; - - /* - * If there's no following space in the buffer, then this path is - * truncated, so it can't be the one we're looking for. - */ - space = strchr(buf, ' '); - if (space) { - match = MATCH_NONE; - if (!decode_path(buf, buf, &len)) { - if (!strcmp(buf, path)) - match = MATCH_EXACT; - else if (!strncmp(buf, path, len) - && (path[len] == '/' || !strcmp(buf, "/"))) - match = MATCH_PARENT; - } - - found = pop(fd, buf, bufsize, space - buf + 1); - if (found != 1) - return found; - - switch (match) { - case MATCH_EXACT: - if (!strncmp(buf, "tmpfs", strlen("tmpfs"))) - *outcome = OUTCOME_TMPFS_MOUNT; - else - *outcome = OUTCOME_NON_TMPFS_MOUNT; - break; - - case MATCH_PARENT: - /* This mount obscures any previous ones. */ - *outcome = OUTCOME_NOTHING_MOUNTED; - break; - } + for (i = 0; tmpfs_dirs[i]; i++) { + dir = tmpfs_dirs[i]; + if (check_tmpfs(dir) >= 0) + goto done; } - return next(fd, buf, bufsize, '\n'); + dir = fallback_dir; +warn: + printf("Warning: tempdir %s is not on tmpfs\n", dir); +done: + /* Make a copy since getenv results may not remain valid forever. */ + return strdup(dir); } -/* which_tmpdir is called only during early boot */ -static int checked_tmpdir = 0; - /* - * Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner - * way to do this than to parse /proc/mounts. statfs will return the - * same filesystem magic number and fs id for both /dev and /dev/shm - * when they are both tmpfs, so you can't tell if they are different - * filesystems. Also, there seems to be no other way of finding the - * mount point of a filesystem from within it. - * - * If a /dev/shm tmpfs entry is found, then we switch to using it. - * Otherwise, we stay with the default /tmp. + * Create an unlinked tempfile in a suitable tempdir. template must be the + * basename part of the template with a leading '/'. */ -static void which_tmpdir(void) +static int __init make_tempfile(const char *template) { + char *tempname; int fd; - int found; - int outcome; - char *path; - char *buf; - size_t bufsize; - if (checked_tmpdir) - return; - - checked_tmpdir = 1; - - printf("Checking for tmpfs mount on /dev/shm..."); - - path = realpath("/dev/shm", NULL); - if (!path) { - printf("failed to check real path, errno = %d\n", errno); - return; - } - printf("%s...", path); - - /* - * The buffer needs to be able to fit the full octal-escaped path, a - * space, and a trailing null in order to successfully decode it. - */ - bufsize = octal_encoded_length(path, " \t\n\\") + 2; - - if (bufsize < 128) - bufsize = 128; - - buf = malloc(bufsize); - if (!buf) { - printf("malloc failed, errno = %d\n", errno); - goto out; - } - buf[0] = '\0'; - - fd = open("/proc/mounts", O_RDONLY); - if (fd < 0) { - printf("failed to open /proc/mounts, errno = %d\n", errno); - goto out1; - } - - outcome = OUTCOME_NOTHING_MOUNTED; - while (1) { - found = read_mount(fd, buf, bufsize, path, &outcome); - if (found != 1) - break; - } - - if (found < 0) { - printf("read returned errno %d\n", -found); - } else { - switch (outcome) { - case OUTCOME_TMPFS_MOUNT: - printf("OK\n"); - default_tmpdir = "/dev/shm"; - break; - - case OUTCOME_NON_TMPFS_MOUNT: - printf("not tmpfs\n"); - break; - - default: - printf("nothing mounted on /dev/shm\n"); - break; + if (tempdir == NULL) { + tempdir = choose_tempdir(); + if (tempdir == NULL) { + fprintf(stderr, "Failed to choose tempdir: %s\n", + strerror(errno)); + return -1; } } - close(fd); -out1: - free(buf); -out: - free(path); -} - -static int __init make_tempfile(const char *template, char **out_tempname, - int do_unlink) -{ - char *tempname; - int fd; - - which_tmpdir(); - tempname = malloc(MAXPATHLEN); + tempname = malloc(strlen(tempdir) + strlen(template) + 1); if (tempname == NULL) return -1; - find_tempdir(); - if ((tempdir == NULL) || (strlen(tempdir) >= MAXPATHLEN)) - goto out; - - if (template[0] != '/') - strcpy(tempname, tempdir); - else - tempname[0] = '\0'; - strncat(tempname, template, MAXPATHLEN-1-strlen(tempname)); + strcpy(tempname, tempdir); + strcat(tempname, template); fd = mkstemp(tempname); if (fd < 0) { fprintf(stderr, "open - cannot create %s: %s\n", tempname, strerror(errno)); goto out; } - if (do_unlink && (unlink(tempname) < 0)) { + if (unlink(tempname) < 0) { perror("unlink"); goto close; } - if (out_tempname) { - *out_tempname = tempname; - } else - free(tempname); + free(tempname); return fd; close: close(fd); @@ -351,14 +131,14 @@ static int __init make_tempfile(const char *template, char **out_tempname, return -1; } -#define TEMPNAME_TEMPLATE "vm_file-XXXXXX" +#define TEMPNAME_TEMPLATE "/vm_file-XXXXXX" static int __init create_tmp_file(unsigned long long len) { int fd, err; char zero; - fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1); + fd = make_tempfile(TEMPNAME_TEMPLATE); if (fd < 0) exit(1); @@ -402,7 +182,6 @@ int __init create_mem_file(unsigned long long len) return fd; } - void __init check_tmpexec(void) { void *addr; @@ -410,14 +189,13 @@ void __init check_tmpexec(void) addr = mmap(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); - printf("Checking PROT_EXEC mmap in %s...",tempdir); - fflush(stdout); + printf("Checking PROT_EXEC mmap in %s...", tempdir); if (addr == MAP_FAILED) { err = errno; - perror("failed"); + printf("%s\n", strerror(err)); close(fd); if (err == EPERM) - printf("%s must be not mounted noexec\n",tempdir); + printf("%s must be not mounted noexec\n", tempdir); exit(1); } printf("OK\n"); -- GitLab From 9fcb663be42e4727c1beabc7c80e2d839199e6b1 Mon Sep 17 00:00:00 2001 From: Anton Ivanov Date: Fri, 7 Mar 2014 18:37:46 +0000 Subject: [PATCH 551/797] um: Missing pipe handling UML does not handle sigpipe. As a result when running it under expect or redirecting the IO from the console to an external program it will crash if the program stops or exits. Signed-off-by: Anton Ivanov Signed-off-by: Richard Weinberger --- arch/um/os-Linux/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index e1704ff600ff..df9191acd926 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -151,6 +151,7 @@ int __init main(int argc, char **argv, char **envp) #endif do_uml_initcalls(); + change_sig(SIGPIPE, 0); ret = linux_main(argc, argv); /* -- GitLab From 0565103d1adbd765ca45248d04c327c076dd1571 Mon Sep 17 00:00:00 2001 From: Anton Ivanov Date: Fri, 7 Mar 2014 18:37:47 +0000 Subject: [PATCH 552/797] um: Memory corruption on startup The reverse case of this race (you must msync before read) is well known. This is the not so common one. It can be triggered only on systems which do a lot of task switching and only at UML startup. If you are starting 200+ UMLs ~ 0.5% will always die without this fix. Signed-off-by: Anton Ivanov [rw: minor whitespace fixes] Signed-off-by: Richard Weinberger --- arch/um/include/shared/os.h | 1 + arch/um/kernel/physmem.c | 1 + arch/um/os-Linux/file.c | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index 75298d3358e7..08eec0b691b0 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h @@ -136,6 +136,7 @@ extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); extern int os_get_ifname(int fd, char *namebuf); extern int os_set_slip(int fd); extern int os_mode_fd(int fd, int mode); +extern int os_fsync_file(int fd); extern int os_seek_file(int fd, unsigned long long offset); extern int os_open_file(const char *file, struct openflags flags, int mode); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index f116db15d402..30fdd5d0067b 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -103,6 +103,7 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end, */ os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE); + os_fsync_file(physmem_fd); bootmap_size = init_bootmem(pfn, pfn + delta); free_bootmem(__pa(reserve_end) + bootmap_size, diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 07a750197bb0..08d90fba952c 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -237,6 +237,12 @@ void os_close_file(int fd) { close(fd); } +int os_fsync_file(int fd) +{ + if (fsync(fd) < 0) + return -errno; + return 0; +} int os_seek_file(int fd, unsigned long long offset) { -- GitLab From 2697e4fb9209dfe1d1b24c92d254158f63d4bc8e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 15 Apr 2014 16:58:09 +0300 Subject: [PATCH 553/797] ASoC: dapm: Fix widget double free with auto-disable DAPM kcontrol Commit 9e1fda4ae158 ("ASoC: dapm: Implement mixer input auto-disable") is trying to free the widget it allocated by snd_soc_dapm_new_control() call in dapm_kcontrol_data_alloc() by adding kfree(data->widget) to dapm_kcontrol_free(). This is causing a widget double free with auto-disabled DAPM kcontrols in sound card unregistration because widgets are already freed before dapm_kcontrol_free() is called. Reason for that is all widgets are added into dapm->card->widgets list in snd_soc_dapm_new_control() and freed in dapm_free_widgets() during execution of snd_soc_dapm_free(). Now snd_soc_dapm_free() calls for different DAPM contexts happens before snd_card_free() call from where the call chain to dapm_kcontrol_free() begins: soc_cleanup_card_resources() soc_remove_dai_links() soc_remove_link_dais() snd_soc_dapm_free(&cpu_dai->dapm) soc_remove_link_components() soc_remove_platform() snd_soc_dapm_free(&platform->dapm) soc_remove_codec() snd_soc_dapm_free(&codec->dapm) snd_soc_dapm_free(&card->dapm) snd_card_free() snd_card_do_free() snd_device_free_all() snd_device_free() snd_ctl_dev_free() snd_ctl_remove() snd_ctl_free_one() dapm_kcontrol_free() This wasn't making harm with ordinary DAPM kcontrols since data->widget is NULL for them. Fixes: 9e1fda4ae158 (ASoC: dapm: Implement mixer input auto-disable) Signed-off-by: Jarkko Nikula Acked-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- sound/soc/soc-dapm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c8a780d0d057..7769b0a2bc5a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -254,7 +254,6 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, static void dapm_kcontrol_free(struct snd_kcontrol *kctl) { struct dapm_kcontrol_data *data = snd_kcontrol_chip(kctl); - kfree(data->widget); kfree(data->wlist); kfree(data); } -- GitLab From 67c99a72e3006e4276e91d7282a3d6734fc77a0b Mon Sep 17 00:00:00 2001 From: "scameron@beardog.cce.hp.com" Date: Mon, 14 Apr 2014 14:01:09 -0500 Subject: [PATCH 554/797] [SCSI] hpsa: fix NULL dereference in hpsa_put_ctlr_into_performant_mode() Initialize local variable trans_support before it is used rather than after. It is supposed to contain the value of a register on the controller containing bits that describe which transport modes the controller supports (e.g. "performant", "ioaccel1", "ioaccel2"). A NULL pointer dereference will almost certainly occur if trans_support is not initialized at the right point. If for example the uninitialized trans_support value does not have the bit set for ioaccel2 support when it should be, then ioaccel2_alloc_cmds_and_bft() will not get called as it should be and the h->ioaccel2_blockFetchTable array will remain NULL instead of being allocated. Too late, trans_support finally gets initialized with the correct value with ioaccel2 mode bit set, which later causes calc_bucket_map() to be called to fill in h->ioaccel2_blockFetchTable[]. However h->ioaccel2_blockFetchTable is NULL because it didn't get allocated because earlier trans_support wasn't initialized at the right point. Fixes: e1f7de0cdd68d246d7008241cd9e443a54f880a8 Signed-off-by: Stephen M. Cameron Reported-by: Baoquan He Tested-by: Baoquan He Signed-off-by: James Bottomley --- drivers/scsi/hpsa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 8cf4a0c69baf..9a6e4a2cd072 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -7463,6 +7463,10 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) if (hpsa_simple_mode) return; + trans_support = readl(&(h->cfgtable->TransportSupport)); + if (!(trans_support & PERFORMANT_MODE)) + return; + /* Check for I/O accelerator mode support */ if (trans_support & CFGTBL_Trans_io_accel1) { transMethod |= CFGTBL_Trans_io_accel1 | @@ -7479,10 +7483,6 @@ static void hpsa_put_ctlr_into_performant_mode(struct ctlr_info *h) } /* TODO, check that this next line h->nreply_queues is correct */ - trans_support = readl(&(h->cfgtable->TransportSupport)); - if (!(trans_support & PERFORMANT_MODE)) - return; - h->nreply_queues = h->msix_vector > 0 ? h->msix_vector : 1; hpsa_get_max_perf_mode_cmds(h); /* Performant mode ring buffer and supporting data structures */ -- GitLab From 5e012aad85f2ee31d7de5c21d63ccd2702d63db2 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 15 Apr 2014 12:24:55 +0200 Subject: [PATCH 555/797] [SCSI] don't reference freed command in scsi_init_sgtable Patch commit 0479633686d370303e3430256ace4bd5f7f138dc Author: Christoph Hellwig Date: Thu Feb 20 14:20:55 2014 -0800 [SCSI] do not manipulate device reference counts in scsi_get/put_command Introduced a use after free: when scsi_init_io fails we have to release our device reference, but we do this trying to reference the just freed command. Add a local scsi_device pointer to fix this. Fixes: 0479633686d370303e3430256ace4bd5f7f138dc Reported-by: Sander Eikelenboom Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 65a123d9c676..54eff6a79fb8 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1044,6 +1044,7 @@ static int scsi_init_sgtable(struct request *req, struct scsi_data_buffer *sdb, */ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) { + struct scsi_device *sdev = cmd->device; struct request *rq = cmd->request; int error = scsi_init_sgtable(rq, &cmd->sdb, gfp_mask); @@ -1091,7 +1092,7 @@ int scsi_init_io(struct scsi_cmnd *cmd, gfp_t gfp_mask) scsi_release_buffers(cmd); cmd->request->special = NULL; scsi_put_command(cmd); - put_device(&cmd->device->sdev_gendev); + put_device(&sdev->sdev_gendev); return error; } EXPORT_SYMBOL(scsi_init_io); -- GitLab From 68c03d9193f55dad93036f439b94912c5003a173 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 15 Apr 2014 12:24:56 +0200 Subject: [PATCH 556/797] [SCSI] don't reference freed command in scsi_prep_return Patch commit 0479633686d370303e3430256ace4bd5f7f138dc Author: Christoph Hellwig Date: Thu Feb 20 14:20:55 2014 -0800 [SCSI] do not manipulate device reference counts in scsi_get/put_command Introduced a use after free:I in the kill case of scsi_prep_return we have to release our device reference, but we do this trying to reference the just freed command. Use the local sdev pointer instead. Fixes: 0479633686d370303e3430256ace4bd5f7f138dc Reported-by: Joe Lawrence Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 54eff6a79fb8..7fa54fe51f63 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1274,7 +1274,7 @@ int scsi_prep_return(struct request_queue *q, struct request *req, int ret) struct scsi_cmnd *cmd = req->special; scsi_release_buffers(cmd); scsi_put_command(cmd); - put_device(&cmd->device->sdev_gendev); + put_device(&sdev->sdev_gendev); req->special = NULL; } break; -- GitLab From 9189a330936fe053d48e14c10a8d90aaef4408c9 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 21 Apr 2014 10:15:12 -0500 Subject: [PATCH 557/797] Revert "usb: gadget: u_ether: move hardware transmit to RX NAPI" This reverts commit 716fb91dfe1777bd6d5e598f3d3572214b3ed296. That commit caused a regression which would end up in a kernel BUG() as below: [ 101.554300] g_ether gadget: full-speed config #1: CDC Subset/SAFE [ 101.585186] ------------[ cut here ]------------ [ 101.600587] kernel BUG at include/linux/netdevice.h:495! [ 101.615850] Internal error: Oops - BUG: 0 [#1] PREEMPT ARM [ 101.645539] Modules linked in: [ 101.660483] CPU: 0 PID: 0 Comm: swapper Not tainted 3.15.0-rc1+ #104 [ 101.690175] task: c05dc5c8 ti: c05d2000 task.ti: c05d2000 [ 101.705579] PC is at eth_start+0x64/0x8c [ 101.720981] LR is at __netif_schedule+0x7c/0x90 [ 101.736455] pc : [] lr : [] psr: 60000093 [ 101.736455] sp : c05d3d18 ip : c05d3cf8 fp : c05d3d2c [ 101.782340] r10: 00000000 r9 : c196c1f0 r8 : c196c1a0 [ 101.797823] r7 : 00000000 r6 : 00000002 r5 : c1976400 r4 : c1976400 [ 101.828058] r3 : 00000000 r2 : c05d3ce8 r1 : 00000001 r0 : 00000002 [ 101.858722] Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel Reported-by: Robert Jarzmik Signed-of-by: Felipe Balbi --- drivers/usb/gadget/u_ether.c | 101 ++++++++++++----------------------- 1 file changed, 35 insertions(+), 66 deletions(-) diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 50d09c289137..b7d4f82872b7 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -48,8 +48,6 @@ #define UETH__VERSION "29-May-2008" -#define GETHER_NAPI_WEIGHT 32 - struct eth_dev { /* lock is held while accessing port_usb */ @@ -74,7 +72,6 @@ struct eth_dev { struct sk_buff_head *list); struct work_struct work; - struct napi_struct rx_napi; unsigned long todo; #define WORK_RX_MEMORY 0 @@ -256,16 +253,18 @@ rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) DBG(dev, "rx submit --> %d\n", retval); if (skb) dev_kfree_skb_any(skb); + spin_lock_irqsave(&dev->req_lock, flags); + list_add(&req->list, &dev->rx_reqs); + spin_unlock_irqrestore(&dev->req_lock, flags); } return retval; } static void rx_complete(struct usb_ep *ep, struct usb_request *req) { - struct sk_buff *skb = req->context; + struct sk_buff *skb = req->context, *skb2; struct eth_dev *dev = ep->driver_data; int status = req->status; - bool rx_queue = 0; switch (status) { @@ -289,8 +288,30 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) } else { skb_queue_tail(&dev->rx_frames, skb); } - if (!status) - rx_queue = 1; + skb = NULL; + + skb2 = skb_dequeue(&dev->rx_frames); + while (skb2) { + if (status < 0 + || ETH_HLEN > skb2->len + || skb2->len > VLAN_ETH_FRAME_LEN) { + dev->net->stats.rx_errors++; + dev->net->stats.rx_length_errors++; + DBG(dev, "rx length %d\n", skb2->len); + dev_kfree_skb_any(skb2); + goto next_frame; + } + skb2->protocol = eth_type_trans(skb2, dev->net); + dev->net->stats.rx_packets++; + dev->net->stats.rx_bytes += skb2->len; + + /* no buffer copies needed, unless hardware can't + * use skb buffers. + */ + status = netif_rx(skb2); +next_frame: + skb2 = skb_dequeue(&dev->rx_frames); + } break; /* software-driven interface shutdown */ @@ -313,20 +334,22 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req) /* FALLTHROUGH */ default: - rx_queue = 1; - dev_kfree_skb_any(skb); dev->net->stats.rx_errors++; DBG(dev, "rx status %d\n", status); break; } + if (skb) + dev_kfree_skb_any(skb); + if (!netif_running(dev->net)) { clean: spin_lock(&dev->req_lock); list_add(&req->list, &dev->rx_reqs); spin_unlock(&dev->req_lock); - - if (rx_queue && likely(napi_schedule_prep(&dev->rx_napi))) - __napi_schedule(&dev->rx_napi); + req = NULL; + } + if (req) + rx_submit(dev, req, GFP_ATOMIC); } static int prealloc(struct list_head *list, struct usb_ep *ep, unsigned n) @@ -391,24 +414,16 @@ static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags) { struct usb_request *req; unsigned long flags; - int rx_counts = 0; /* fill unused rxq slots with some skb */ spin_lock_irqsave(&dev->req_lock, flags); while (!list_empty(&dev->rx_reqs)) { - - if (++rx_counts > qlen(dev->gadget, dev->qmult)) - break; - req = container_of(dev->rx_reqs.next, struct usb_request, list); list_del_init(&req->list); spin_unlock_irqrestore(&dev->req_lock, flags); if (rx_submit(dev, req, gfp_flags) < 0) { - spin_lock_irqsave(&dev->req_lock, flags); - list_add(&req->list, &dev->rx_reqs); - spin_unlock_irqrestore(&dev->req_lock, flags); defer_kevent(dev, WORK_RX_MEMORY); return; } @@ -418,41 +433,6 @@ static void rx_fill(struct eth_dev *dev, gfp_t gfp_flags) spin_unlock_irqrestore(&dev->req_lock, flags); } -static int gether_poll(struct napi_struct *napi, int budget) -{ - struct eth_dev *dev = container_of(napi, struct eth_dev, rx_napi); - struct sk_buff *skb; - unsigned int work_done = 0; - int status = 0; - - while ((skb = skb_dequeue(&dev->rx_frames))) { - if (status < 0 - || ETH_HLEN > skb->len - || skb->len > VLAN_ETH_FRAME_LEN) { - dev->net->stats.rx_errors++; - dev->net->stats.rx_length_errors++; - DBG(dev, "rx length %d\n", skb->len); - dev_kfree_skb_any(skb); - continue; - } - skb->protocol = eth_type_trans(skb, dev->net); - dev->net->stats.rx_packets++; - dev->net->stats.rx_bytes += skb->len; - - status = netif_rx_ni(skb); - } - - if (netif_running(dev->net)) { - rx_fill(dev, GFP_KERNEL); - work_done++; - } - - if (work_done < budget) - napi_complete(&dev->rx_napi); - - return work_done; -} - static void eth_work(struct work_struct *work) { struct eth_dev *dev = container_of(work, struct eth_dev, work); @@ -645,7 +625,6 @@ static void eth_start(struct eth_dev *dev, gfp_t gfp_flags) /* and open the tx floodgates */ atomic_set(&dev->tx_qlen, 0); netif_wake_queue(dev->net); - napi_enable(&dev->rx_napi); } static int eth_open(struct net_device *net) @@ -672,7 +651,6 @@ static int eth_stop(struct net_device *net) unsigned long flags; VDBG(dev, "%s\n", __func__); - napi_disable(&dev->rx_napi); netif_stop_queue(net); DBG(dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", @@ -790,7 +768,6 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g, return ERR_PTR(-ENOMEM); dev = netdev_priv(net); - netif_napi_add(net, &dev->rx_napi, gether_poll, GETHER_NAPI_WEIGHT); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); @@ -853,7 +830,6 @@ struct net_device *gether_setup_name_default(const char *netname) return ERR_PTR(-ENOMEM); dev = netdev_priv(net); - netif_napi_add(net, &dev->rx_napi, gether_poll, GETHER_NAPI_WEIGHT); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); @@ -1137,7 +1113,6 @@ void gether_disconnect(struct gether *link) { struct eth_dev *dev = link->ioport; struct usb_request *req; - struct sk_buff *skb; WARN_ON(!dev); if (!dev) @@ -1164,12 +1139,6 @@ void gether_disconnect(struct gether *link) spin_lock(&dev->req_lock); } spin_unlock(&dev->req_lock); - - spin_lock(&dev->rx_frames.lock); - while ((skb = __skb_dequeue(&dev->rx_frames))) - dev_kfree_skb_any(skb); - spin_unlock(&dev->rx_frames.lock); - link->in_ep->driver_data = NULL; link->in_ep->desc = NULL; -- GitLab From 2656c9e28125e96bee212f146cc3f2419fd3ffef Mon Sep 17 00:00:00 2001 From: Macpaul Lin Date: Tue, 15 Apr 2014 16:09:33 +0800 Subject: [PATCH 558/797] usb: gadget: f_rndis: reduce NETTX irq caused by free skb header This patch reduce unecessary NETTX softirq call caused by free skb header. You will see this softirq comes twice while there is only one TX packet to be transmitted. So using dev_kfree_skb() instead of dev_kfree_skb_any() to avoid this problem. Cc: David S. Miller Cc: Stephen Hemminger Cc: Greg Kroah-Hartman Signed-off-by: Macpaul Lin Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index c11761ce5113..9a4f49dc6ac4 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -377,7 +377,7 @@ static struct sk_buff *rndis_add_header(struct gether *port, if (skb2) rndis_add_hdr(skb2); - dev_kfree_skb_any(skb); + dev_kfree_skb(skb); return skb2; } -- GitLab From a31a942a148e0083ce560ffeb54fb60e06ab7201 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Wed, 16 Apr 2014 17:11:16 +0200 Subject: [PATCH 559/797] usb: phy: am335x-control: wait 1ms after power-up transitions Tests have shown that when a power-up transition is followed by other PHY operations too quickly, the USB port appears dead. Waiting 1ms fixes this problem. Signed-off-by: Daniel Mack Cc: stable@vger.kernel.org [3.14] Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-am335x-control.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/usb/phy/phy-am335x-control.c b/drivers/usb/phy/phy-am335x-control.c index d75196ad5f2f..35b6083b7999 100644 --- a/drivers/usb/phy/phy-am335x-control.c +++ b/drivers/usb/phy/phy-am335x-control.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "am35x-phy-control.h" struct am335x_control_usb { @@ -86,6 +87,14 @@ static void am335x_phy_power(struct phy_control *phy_ctrl, u32 id, bool on) } writel(val, usb_ctrl->phy_reg + reg); + + /* + * Give the PHY ~1ms to complete the power up operation. + * Tests have shown unstable behaviour if other USB PHY related + * registers are written too shortly after such a transition. + */ + if (on) + mdelay(1); } static const struct phy_control ctrl_am335x = { -- GitLab From 75e4f206c97b7dbf1187c7b7b509bcb7a822767d Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 7 Apr 2014 15:16:54 +0200 Subject: [PATCH 560/797] tools/power/acpi: Minor bugfixes - bindir is created, but sbindir is used -> fix that - the debug parts are there twice (copy paste bug?). Remove one of the exact same parts Signed-off-by: Thomas Renninger Signed-off-by: Rafael J. Wysocki --- tools/power/acpi/Makefile | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tools/power/acpi/Makefile b/tools/power/acpi/Makefile index d9186a2fdf06..c2c0f20067a5 100644 --- a/tools/power/acpi/Makefile +++ b/tools/power/acpi/Makefile @@ -89,15 +89,6 @@ else STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif -# if DEBUG is enabled, then we do not strip or optimize -ifeq ($(strip $(DEBUG)),true) - CFLAGS += -O1 -g -DDEBUG - STRIPCMD = /bin/true -Since_we_are_debugging -else - CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer - STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment -endif - # --- ACPIDUMP BEGIN --- vpath %.c \ @@ -128,7 +119,7 @@ clean: -rm -f $(OUTPUT)acpidump install-tools: - $(INSTALL) -d $(DESTDIR)${bindir} + $(INSTALL) -d $(DESTDIR)${sbindir} $(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir} install-man: -- GitLab From 6273f00e6ecbd60494a979033b7e5271a29a0436 Mon Sep 17 00:00:00 2001 From: Lv Zheng Date: Wed, 16 Apr 2014 21:24:34 +0800 Subject: [PATCH 561/797] ACPICA: Fix buffer allocation issue for generic_serial_bus region accesses. The size of the buffer allocated for generic_serial_bus region access is not correct. This patch introduces acpi_ex_get_serial_access_length() to be invoked to obtain correct data buffer length. Signed-off-by: Lv Zheng Reported by: Lan Tianyu Acked-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpica/exfield.c | 104 +++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 68d97441432c..12878e1982f7 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -45,10 +45,71 @@ #include "accommon.h" #include "acdispat.h" #include "acinterp.h" +#include "amlcode.h" #define _COMPONENT ACPI_EXECUTER ACPI_MODULE_NAME("exfield") +/* Local prototypes */ +static u32 +acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length); + +/******************************************************************************* + * + * FUNCTION: acpi_get_serial_access_bytes + * + * PARAMETERS: accessor_type - The type of the protocol indicated by region + * field access attributes + * access_length - The access length of the region field + * + * RETURN: Decoded access length + * + * DESCRIPTION: This routine returns the length of the generic_serial_bus + * protocol bytes + * + ******************************************************************************/ + +static u32 +acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length) +{ + u32 length; + + switch (accessor_type) { + case AML_FIELD_ATTRIB_QUICK: + + length = 0; + break; + + case AML_FIELD_ATTRIB_SEND_RCV: + case AML_FIELD_ATTRIB_BYTE: + + length = 1; + break; + + case AML_FIELD_ATTRIB_WORD: + case AML_FIELD_ATTRIB_WORD_CALL: + + length = 2; + break; + + case AML_FIELD_ATTRIB_MULTIBYTE: + case AML_FIELD_ATTRIB_RAW_BYTES: + case AML_FIELD_ATTRIB_RAW_PROCESS: + + length = access_length; + break; + + case AML_FIELD_ATTRIB_BLOCK: + case AML_FIELD_ATTRIB_BLOCK_CALL: + default: + + length = ACPI_GSBUS_BUFFER_SIZE; + break; + } + + return (length); +} + /******************************************************************************* * * FUNCTION: acpi_ex_read_data_from_field @@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield") * Buffer, depending on the size of the field. * ******************************************************************************/ + acpi_status -acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, +acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, union acpi_operand_object *obj_desc, union acpi_operand_object **ret_buffer_desc) { @@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, acpi_size length; void *buffer; u32 function; + u16 accessor_type; ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); @@ -116,9 +179,22 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ACPI_READ | (obj_desc->field.attribute << 16); } else if (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) { - length = ACPI_GSBUS_BUFFER_SIZE; - function = - ACPI_READ | (obj_desc->field.attribute << 16); + accessor_type = obj_desc->field.attribute; + length = acpi_ex_get_serial_access_length(accessor_type, + obj_desc-> + field. + access_length); + + /* + * Add additional 2 bytes for modeled generic_serial_bus data buffer: + * typedef struct { + * BYTEStatus; // Byte 0 of the data buffer + * BYTELength; // Byte 1 of the data buffer + * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, + * } + */ + length += 2; + function = ACPI_READ | (accessor_type << 16); } else { /* IPMI */ length = ACPI_IPMI_BUFFER_SIZE; @@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, void *buffer; union acpi_operand_object *buffer_desc; u32 function; + u16 accessor_type; ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); @@ -284,9 +361,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ACPI_WRITE | (obj_desc->field.attribute << 16); } else if (obj_desc->field.region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) { - length = ACPI_GSBUS_BUFFER_SIZE; - function = - ACPI_WRITE | (obj_desc->field.attribute << 16); + accessor_type = obj_desc->field.attribute; + length = acpi_ex_get_serial_access_length(accessor_type, + obj_desc-> + field. + access_length); + + /* + * Add additional 2 bytes for modeled generic_serial_bus data buffer: + * typedef struct { + * BYTEStatus; // Byte 0 of the data buffer + * BYTELength; // Byte 1 of the data buffer + * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, + * } + */ + length += 2; + function = ACPI_WRITE | (accessor_type << 16); } else { /* IPMI */ length = ACPI_IPMI_BUFFER_SIZE; -- GitLab From d555a2abf3481f81303d835046a5ec2c4fb3ca8e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 28 Mar 2014 10:50:17 -0700 Subject: [PATCH 562/797] [SCSI] Fix spurious request sense in error handling We unconditionally execute scsi_eh_get_sense() to make sure all failed commands that should have sense attached, do. However, the routine forgets that some commands, because of the way they fail, will not have any sense code ... we should not bother them with a REQUEST_SENSE command. Fix this by testing to see if we actually got a CHECK_CONDITION return and skip asking for sense if we don't. Tested-by: Alan Stern Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 771c16bfdbac..d020149ea8d4 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -1157,6 +1157,15 @@ int scsi_eh_get_sense(struct list_head *work_q, __func__)); break; } + if (status_byte(scmd->result) != CHECK_CONDITION) + /* + * don't request sense if there's no check condition + * status because the error we're processing isn't one + * that has a sense code (and some devices get + * confused by sense requests out of the blue) + */ + continue; + SCSI_LOG_ERROR_RECOVERY(2, scmd_printk(KERN_INFO, scmd, "%s: requesting sense\n", current->comm)); -- GitLab From 644373a4219add42123df69c8b7ce6a918475ccd Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 28 Mar 2014 10:51:15 -0700 Subject: [PATCH 563/797] [SCSI] Fix command result state propagation We're seeing a case where the contents of scmd->result isn't being reset after a SCSI command encounters an error, is resubmitted, times out and then gets handled. The error handler acts on the stale result of the previous error instead of the timeout. Fix this by properly zeroing the scmd->status before the command is resubmitted. Signed-off-by: Alan Stern Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 1 + drivers/scsi/scsi_lib.c | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index d020149ea8d4..2953bfa92da7 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -924,6 +924,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(&scmd->sdb, 0, sizeof(scmd->sdb)); scmd->request->next_rq = NULL; + scmd->result = 0; if (sense_bytes) { scmd->sdb.length = min_t(unsigned, SCSI_SENSE_BUFFERSIZE, diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7fa54fe51f63..9db097a28a74 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -137,6 +137,7 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy) * lock such that the kblockd_schedule_work() call happens * before blk_cleanup_queue() finishes. */ + cmd->result = 0; spin_lock_irqsave(q->queue_lock, flags); blk_requeue_request(q, cmd->request); kblockd_schedule_work(q, &device->requeue_work); -- GitLab From 7daf480483e60898f30e0a2a84fecada7a7cfac0 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 31 Mar 2014 16:37:34 +0200 Subject: [PATCH 564/797] [SCSI] Fix USB deadlock caused by SCSI error handling USB requires that every command be aborted first before we escalate to reset. In particular, USB will deadlock if we try to reset first before aborting the command. Unfortunately, the flag we use to tell if a command has already been aborted: SCSI_EH_ABORT_SCHEDULED is not cleared properly leading to cases where we can requeue a command with the flag set and proceed immediately to reset if it fails (thus causing USB to deadlock). Fix by clearing the SCSI_EH_ABORT_SCHEDULED flag if it has been set. Which means this will be the second time scsi_abort_command() has been called for the same command. IE the first abort went out, did its thing, but now the same command has timed out again. So this flag gets cleared, and scsi_abort_command() returns FAILED, and _no_ asynchronous abort is being scheduled. scsi_times_out() will then proceed to call scsi_eh_scmd_add(). But as we've cleared the SCSI_EH_ABORT_SCHEDULED flag the SCSI_EH_CANCEL_CMD flag will continue to be set, and the command will be aborted with the main SCSI EH routine. Reported-by: Alan Stern Tested-by: Andreas Reis Signed-off-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 2953bfa92da7..ad064d2d730b 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -189,6 +189,7 @@ scsi_abort_command(struct scsi_cmnd *scmd) /* * Retry after abort failed, escalate to next level. */ + scmd->eh_eflags &= ~SCSI_EH_ABORT_SCHEDULED; SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd, "scmd %p previous abort failed\n", scmd)); -- GitLab From c69e6f812bab0d5442b40e2f1bfbca48d40bc50b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 10 Apr 2014 13:36:11 -0700 Subject: [PATCH 565/797] [SCSI] More USB deadlock fixes This patch fixes a corner case in the previous USB Deadlock fix patch (12023e7 [SCSI] Fix USB deadlock caused by SCSI error handling). The scenario is abort command, set flag, abort completes, send TUR, TUR doesn't return, so we now try to abort the TUR, but scsi_abort_eh_cmnd() will skip the abort because the flag is set and move straight to reset. Reviewed-by: Hannes Reinecke Signed-off-by: James Bottomley --- drivers/scsi/scsi_error.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index ad064d2d730b..f17aa7aa7879 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -921,6 +921,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, ses->prot_op = scmd->prot_op; scmd->prot_op = SCSI_PROT_NORMAL; + scmd->eh_eflags = 0; scmd->cmnd = ses->eh_cmnd; memset(scmd->cmnd, 0, BLK_MAX_CDB); memset(&scmd->sdb, 0, sizeof(scmd->sdb)); -- GitLab From d27dca4217eb4cbdc3d33ad8c07799dd184873b9 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Sat, 12 Apr 2014 19:57:30 +0200 Subject: [PATCH 566/797] intel_idle: fix IVT idle state table setting Ivy Town idle state table will not be set as intended. Fix it. Picked up by Coverity - CID 1201420/1201421. Fixes: 0138d8f075 ("intel_idle: fine-tune IVT residency targets") Signed-off-by: Christoph Jaeger Signed-off-by: Rafael J. Wysocki --- drivers/idle/intel_idle.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index a43220c2e3d9..4d140bbbe100 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -750,9 +750,10 @@ void intel_idle_state_table_update(void) if (package_num + 1 > num_sockets) { num_sockets = package_num + 1; - if (num_sockets > 4) + if (num_sockets > 4) { cpuidle_state_table = ivt_cstates_8s; return; + } } } -- GitLab From f3f125324fc1b8500cd20a2907628f7e5d88a708 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 20 Apr 2014 23:43:01 +0200 Subject: [PATCH 567/797] PM / suspend: Make cpuidle work in the "freeze" state The "freeze" system sleep state introduced by commit 7e73c5ae6e79 (PM: Introduce suspend state PM_SUSPEND_FREEZE) requires cpuidle to be functional when freeze_enter() is executed to work correctly (that is, to be able to save any more energy than runtime idle), but that is impossible after commit 8651f97bd951d (PM / cpuidle: System resume hang fix with cpuidle) which caused cpuidle to be paused in dpm_suspend_noirq() and resumed in dpm_resume_noirq(). To avoid that problem, add cpuidle_resume() and cpuidle_pause() to the beginning and the end of freeze_enter(), respectively. Reported-by: Zhang Rui Signed-off-by: Rafael J. Wysocki Reviewed-by: Preeti U Murthy --- kernel/power/suspend.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index c3ad9cafe930..8233cd4047d7 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,9 @@ static void freeze_begin(void) static void freeze_enter(void) { + cpuidle_resume(); wait_event(suspend_freeze_wait_head, suspend_freeze_wake); + cpuidle_pause(); } void freeze_wake(void) -- GitLab From 8ab4e2b30a0921d819b196d34ce58f19c3e0270b Mon Sep 17 00:00:00 2001 From: Duan Jiong Date: Fri, 11 Apr 2014 15:59:38 +0800 Subject: [PATCH 568/797] cpufreq: unicore32: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO This patch fixes coccinelle error regarding usage of IS_ERR and PTR_ERR instead of PTR_ERR_OR_ZERO. Signed-off-by: Duan Jiong Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/unicore2-cpufreq.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/cpufreq/unicore2-cpufreq.c b/drivers/cpufreq/unicore2-cpufreq.c index 8d045afa7fb4..6f9dfa80563a 100644 --- a/drivers/cpufreq/unicore2-cpufreq.c +++ b/drivers/cpufreq/unicore2-cpufreq.c @@ -60,9 +60,7 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy) policy->max = policy->cpuinfo.max_freq = 1000000; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->clk = clk_get(NULL, "MAIN_CLK"); - if (IS_ERR(policy->clk)) - return PTR_ERR(policy->clk); - return 0; + return PTR_ERR_OR_ZERO(policy->clk); } static struct cpufreq_driver ucv2_driver = { -- GitLab From f3cae355a962784101478504ef7f6a389ad62979 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Wed, 16 Apr 2014 11:35:38 +0530 Subject: [PATCH 569/797] cpufreq, powernv: Fix build failure on UP Paul Gortmaker reported the following build failure of the powernv cpufreq driver on UP configs: drivers/cpufreq/powernv-cpufreq.c:241:2: error: implicit declaration of function 'cpu_sibling_mask' [-Werror=implicit-function-declaration] cc1: some warnings being treated as errors make[3]: *** [drivers/cpufreq/powernv-cpufreq.o] Error 1 make[2]: *** [drivers/cpufreq] Error 2 make[1]: *** [drivers] Error 2 make: *** [sub-make] Error 2 The trouble here is that cpu_sibling_mask is defined only in , and includes only in SMP builds. So fix this build failure by explicitly including in the driver, so that we get the definition of cpu_sibling_mask even in UP configurations. Reported-by: Paul Gortmaker Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernv-cpufreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 9edccc63245d..af4968813e76 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -29,6 +29,7 @@ #include #include +#include /* Required for cpu_sibling_mask() in UP configs */ #define POWERNV_MAX_PSTATES 256 -- GitLab From 1612343a264b2791f4602f4b47dac853e0892ec0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 17 Apr 2014 11:53:26 +0200 Subject: [PATCH 570/797] cpufreq: ppc: Fix integer overflow in expression On 32-bit, "12 * NSEC_PER_SEC" doesn't fit in "unsigned long" (NSEC_PER_SEC is a "long" constant), causing an integer overflow: drivers/cpufreq/ppc-corenet-cpufreq.c: In function 'corenet_cpufreq_cpu_init': drivers/cpufreq/ppc-corenet-cpufreq.c:211:9: warning: integer overflow in expression [-Woverflow] Force the intermediate to be 64-bit by adding an "ULL" suffix to the constant multiplier to fix this. Signed-off-by: Geert Uytterhoeven Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/ppc-corenet-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index b7e677be1df0..a1ca3dd04a8e 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -206,7 +206,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) per_cpu(cpu_data, i) = data; policy->cpuinfo.transition_latency = - (12 * NSEC_PER_SEC) / fsl_get_sys_freq(); + (12ULL * NSEC_PER_SEC) / fsl_get_sys_freq(); of_node_put(np); return 0; -- GitLab From d76ae2eabca5ff112bb58de8a7d52b70f8bb0608 Mon Sep 17 00:00:00 2001 From: Kefeng Wang Date: Wed, 9 Apr 2014 10:34:33 +0800 Subject: [PATCH 571/797] cpufreq: highbank: fix ARM_HIGHBANK_CPUFREQ dependency warning When make ARCH=arm multi_v7_defconfig, we get the following warnings: warning: (ARM_HIGHBANK_CPUFREQ) selects GENERIC_CPUFREQ_CPU0 which has unmet direct dependencies (ARCH_HAS_CPUFREQ && CPU_FREQ && HAVE_CLK && REGULATOR && OF && THERMAL && CPU_THERMAL) To fix this, make ARM_HIGHBANK_CPUFREQ depend on ARCH_HAS_CPUFREQ and REGULATOR instead of selecting them, PM_OPP will be selected by ARCH_HAS_CPUFREQ. Signed-off-by: Kefeng Wang Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Kconfig.arm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 0e9cce82844b..580503513f0f 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -92,11 +92,7 @@ config ARM_EXYNOS_CPU_FREQ_BOOST_SW config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" - depends on ARCH_HIGHBANK - select GENERIC_CPUFREQ_CPU0 - select PM_OPP - select REGULATOR - + depends on ARCH_HIGHBANK && GENERIC_CPUFREQ_CPU0 && REGULATOR default m help This adds the CPUFreq driver for Calxeda Highbank SoC -- GitLab From efe8072316a899294212055c147d3d9adca940a4 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 21 Apr 2014 19:26:13 -0700 Subject: [PATCH 572/797] ARM: OMAP2+: Fix oops for GPMC free If gpmc_cs_remap() fails we will get an error because we are calling release_resource() on an uninitialized resource. Let's fix that by checking the resource flags. And while at it, let's also make gpmc_cs_delete_mem() use the res pointer that we already have to avoid confusion. Without this patch we can get the following error: omap-gpmc 6e000000.gpmc: cannot remap GPMC CS 1 to 0x01000300 Unable to handle kernel NULL pointer dereference at virtual address 00000018 ... (gpmc_cs_free+0x94/0xc8) (gpmc_probe_generic_child+0x178/0x1ec) (gpmc_probe_dt+0x1bc/0x2cc) (gpmc_probe+0x250/0x44c) (platform_drv_probe+0x3c/0x6c) (really_probe+0x74/0x208) (driver_probe_device+0x34/0x50) (bus_for_each_drv+0x60/0x8c) (device_attach+0x80/0xa4) (bus_probe_device+0x88/0xb0) (device_add+0x320/0x450) (of_platform_device_create_pdata+0x80/0x9c) (of_platform_bus_create+0xd0/0x170) (of_platform_bus_create+0x12c/0x170) (of_platform_populate+0x60/0x98) (pdata_quirks_init+0x30/0x48) (customize_machine+0x20/0x48) (do_one_initcall+0x2c/0x14c) (do_basic_setup+0x98/0xd8) (kernel_init_freeable+0x12c/0x1e0) (kernel_init+0x8/0xf0) (ret_from_fork+0x14/0x2c) Code: e1a04000 e59f0070 eb195136 e5942010 (e5923018) Cc: Pekon Gupta Reviewed-by: Javier Martinez Canillas Signed-off-by: tony Lindgren --- arch/arm/mach-omap2/gpmc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index ab43755364f5..84e57e6fbc26 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -501,7 +501,7 @@ static int gpmc_cs_delete_mem(int cs) int r; spin_lock(&gpmc_mem_lock); - r = release_resource(&gpmc_cs_mem[cs]); + r = release_resource(res); res->start = 0; res->end = 0; spin_unlock(&gpmc_mem_lock); @@ -586,6 +586,8 @@ EXPORT_SYMBOL(gpmc_cs_request); void gpmc_cs_free(int cs) { + struct resource *res = &gpmc_cs_mem[cs]; + spin_lock(&gpmc_mem_lock); if (cs >= gpmc_cs_num || cs < 0 || !gpmc_cs_reserved(cs)) { printk(KERN_ERR "Trying to free non-reserved GPMC CS%d\n", cs); @@ -594,7 +596,8 @@ void gpmc_cs_free(int cs) return; } gpmc_cs_disable_mem(cs); - release_resource(&gpmc_cs_mem[cs]); + if (res->flags) + release_resource(res); gpmc_cs_set_reserved(cs, 0); spin_unlock(&gpmc_mem_lock); } -- GitLab From b2bf5d484848450e7aa3332e268c5e874d9dc523 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Fri, 4 Apr 2014 16:14:12 -0700 Subject: [PATCH 573/797] ARM: zynq: DT: Add 'clock-latency' property Specify the 'clock-latency' property to avoid certain cpufreq governors from refusing to work with the following error: ondemand governor failed, too long transition latency of HW, fallback to performance governor Reported-by: Mike Looijmans Signed-off-by: Soren Brinkmann Tested-by: Mike Looijmans Signed-off-by: Michal Simek --- arch/arm/boot/dts/zynq-7000.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index 511180769af5..c39baefcfd76 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -24,6 +24,7 @@ device_type = "cpu"; reg = <0>; clocks = <&clkc 3>; + clock-latency = <1000>; operating-points = < /* kHz uV */ 666667 1000000 -- GitLab From 0f6faa3fc909482c2b40161de9bcf0d5460e54c5 Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Fri, 4 Apr 2014 14:27:56 -0700 Subject: [PATCH 574/797] ARM: zynq: dt: Add I2C nodes to Zynq device tree Signed-off-by: Soren Brinkmann Tested-by: Michal Simek Signed-off-by: Michal Simek --- arch/arm/boot/dts/zynq-7000.dtsi | 22 +++++++++ arch/arm/boot/dts/zynq-zc702.dts | 76 ++++++++++++++++++++++++++++++++ arch/arm/boot/dts/zynq-zc706.dts | 68 ++++++++++++++++++++++++++++ 3 files changed, 166 insertions(+) diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index c39baefcfd76..c1176abc34d9 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi @@ -55,6 +55,28 @@ interrupt-parent = <&intc>; ranges; + i2c0: zynq-i2c@e0004000 { + compatible = "cdns,i2c-r1p10"; + status = "disabled"; + clocks = <&clkc 38>; + interrupt-parent = <&intc>; + interrupts = <0 25 4>; + reg = <0xe0004000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: zynq-i2c@e0005000 { + compatible = "cdns,i2c-r1p10"; + status = "disabled"; + clocks = <&clkc 39>; + interrupt-parent = <&intc>; + interrupts = <0 48 4>; + reg = <0xe0005000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + }; + intc: interrupt-controller@f8f01000 { compatible = "arm,cortex-a9-gic"; #interrupt-cells = <3>; diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index c913f77a21eb..5e09cee33d42 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts @@ -34,6 +34,82 @@ phy-mode = "rgmii"; }; +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + i2cswitch@74 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + si570: clock-generator@5d { + #clock-cells = <0>; + compatible = "silabs,si570"; + temperature-stability = <50>; + reg = <0x5d>; + factory-fout = <156250000>; + clock-frequency = <148500000>; + }; + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + eeprom@54 { + compatible = "at,24c08"; + reg = <0x54>; + }; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + gpio@21 { + compatible = "ti,tca6416"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + }; + + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + hwmon@52 { + compatible = "ti,ucd9248"; + reg = <52>; + }; + hwmon@53 { + compatible = "ti,ucd9248"; + reg = <53>; + }; + hwmon@54 { + compatible = "ti,ucd9248"; + reg = <54>; + }; + }; + }; +}; + &sdhci0 { status = "okay"; }; diff --git a/arch/arm/boot/dts/zynq-zc706.dts b/arch/arm/boot/dts/zynq-zc706.dts index 88f62c50382e..4cc9913078cd 100644 --- a/arch/arm/boot/dts/zynq-zc706.dts +++ b/arch/arm/boot/dts/zynq-zc706.dts @@ -35,6 +35,74 @@ phy-mode = "rgmii"; }; +&i2c0 { + status = "okay"; + clock-frequency = <400000>; + + i2cswitch@74 { + compatible = "nxp,pca9548"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x74>; + + i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + si570: clock-generator@5d { + #clock-cells = <0>; + compatible = "silabs,si570"; + temperature-stability = <50>; + reg = <0x5d>; + factory-fout = <156250000>; + clock-frequency = <148500000>; + }; + }; + + i2c@2 { + #address-cells = <1>; + #size-cells = <0>; + reg = <2>; + eeprom@54 { + compatible = "at,24c08"; + reg = <0x54>; + }; + }; + + i2c@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + gpio@21 { + compatible = "ti,tca6416"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + }; + }; + + i2c@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <4>; + rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; + }; + + i2c@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <7>; + ucd90120@65 { + compatible = "ti,ucd90120"; + reg = <0x65>; + }; + }; + }; +}; + &sdhci0 { status = "okay"; }; -- GitLab From ad47b8fa5a679b7acaae831635e40d2e4887e9e7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 22 Apr 2014 02:02:06 -0400 Subject: [PATCH 575/797] drm/radeon/aux: fix hpd assignment for aux bus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hpd (hot plug detect) pin assignment got lost in the conversion to to the common i2c over aux code. Without this information, aux transactions do not work properly. Fixes DP failures. Signed-off-by: Alex Deucher Signed-off-by: Christian König --- drivers/gpu/drm/radeon/atombios_dp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 15936524f226..bc0119fb6c12 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c @@ -209,6 +209,7 @@ void radeon_dp_aux_init(struct radeon_connector *radeon_connector) { int ret; + radeon_connector->ddc_bus->rec.hpd = radeon_connector->hpd.hpd; radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev; radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer; ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux); -- GitLab From 8f2dd677bec68fb55904799a82674c9e64b23be3 Mon Sep 17 00:00:00 2001 From: Behan Webster Date: Mon, 21 Apr 2014 22:40:27 -0700 Subject: [PATCH 576/797] x86: LLVMLinux: Wrap -mno-80387 with cc-option Wrap -mno-80387 gcc options with cc-option so they don't break clang. Signed-off-by: Behan Webster Cc: torvalds@linux-foundation.org Cc: dwmw2@infradead.org Cc: pageexec@freemail.hu Link: http://lkml.kernel.org/r/1398145227-25053-1-git-send-email-behanw@converseincode.com Signed-off-by: Ingo Molnar --- arch/x86/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index d1b7c377a234..ce6ad7e6a7d7 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -83,7 +83,9 @@ else KBUILD_CFLAGS += -m64 # Don't autogenerate traditional x87, MMX or SSE instructions - KBUILD_CFLAGS += -mno-mmx -mno-sse -mno-80387 -mno-fp-ret-in-387 + KBUILD_CFLAGS += -mno-mmx -mno-sse + KBUILD_CFLAGS += $(call cc-option,-mno-80387) + KBUILD_CFLAGS += $(call cc-option,-mno-fp-ret-in-387) # Use -mpreferred-stack-boundary=3 if supported. KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3) -- GitLab From 40478455fefdc0bde24ae872c3f88d58a1b0e435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 27 Mar 2014 11:08:45 +0200 Subject: [PATCH 577/797] drm/i915: Allow user modes to exceed DVI 165MHz limit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit commit 6375b768a9850b6154478993e5fb566fa4614a9c Author: Ville Syrjälä Date: Mon Mar 3 11:33:36 2014 +0200 drm/i915: Reject >165MHz modes w/ DVI monitors the driver started to filter out display modes which exceed the single-link DVI 165Mz dotclock limits when the monitor doesn't report itself as being HDMI compliant. The intent was to filter out all EDID derived modes that require dual-link DVI to operate since we don't support dual-link. However the patch went a bit too far and also causes the driver to reject such modes even when specified by the user. Normally we don't check the sink limitations when setting a mode from the user. This allows the user to specify any mode whether the sink reports to support it or not. This can be useful since often the sinks support more modes than they report in the EDID. So relax the checks a bit, and apply the single-link DVI dotclock limit only when filtering the mode list, and ignore the limit when setting a user specified mode. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=72961 Tested-by: Nicholas Vinson Cc: stable@vger.kernel.org [3.14] Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_hdmi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index b0413e190625..157267aa3561 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -821,11 +821,11 @@ static void intel_disable_hdmi(struct intel_encoder *encoder) } } -static int hdmi_portclock_limit(struct intel_hdmi *hdmi) +static int hdmi_portclock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit) { struct drm_device *dev = intel_hdmi_to_dev(hdmi); - if (!hdmi->has_hdmi_sink || IS_G4X(dev)) + if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev)) return 165000; else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) return 300000; @@ -837,7 +837,8 @@ static enum drm_mode_status intel_hdmi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { - if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector))) + if (mode->clock > hdmi_portclock_limit(intel_attached_hdmi(connector), + true)) return MODE_CLOCK_HIGH; if (mode->clock < 20000) return MODE_CLOCK_LOW; @@ -879,7 +880,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder, struct drm_device *dev = encoder->base.dev; struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode; int clock_12bpc = pipe_config->adjusted_mode.crtc_clock * 3 / 2; - int portclock_limit = hdmi_portclock_limit(intel_hdmi); + int portclock_limit = hdmi_portclock_limit(intel_hdmi, false); int desired_bpp; if (intel_hdmi->color_range_auto) { -- GitLab From 0d3f7a2dd2f5cf9642982515e020c1aee2cf7af6 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 22 Apr 2014 08:23:58 -0400 Subject: [PATCH 578/797] locks: rename file-private locks to "open file description locks" File-private locks have been merged into Linux for v3.15, and *now* people are commenting that the name and macro definitions for the new file-private locks suck. ...and I can't even disagree. The names and command macros do suck. We're going to have to live with these for a long time, so it's important that we be happy with the names before we're stuck with them. The consensus on the lists so far is that they should be rechristened as "open file description locks". The name isn't a big deal for the kernel, but the command macros are not visually distinct enough from the traditional POSIX lock macros. The glibc and documentation folks are recommending that we change them to look like F_OFD_{GETLK|SETLK|SETLKW}. That lessens the chance that a programmer will typo one of the commands wrong, and also makes it easier to spot this difference when reading code. This patch makes the following changes that I think are necessary before v3.15 ships: 1) rename the command macros to their new names. These end up in the uapi headers and so are part of the external-facing API. It turns out that glibc doesn't actually use the fcntl.h uapi header, but it's hard to be sure that something else won't. Changing it now is safest. 2) make the the /proc/locks output display these as type "OFDLCK" Cc: Michael Kerrisk Cc: Christoph Hellwig Cc: Carlos O'Donell Cc: Stefan Metzmacher Cc: Andy Lutomirski Cc: Frank Filz Cc: Theodore Ts'o Signed-off-by: Jeff Layton --- arch/arm/kernel/sys_oabi-compat.c | 6 +++--- fs/compat.c | 14 +++++++------- fs/fcntl.c | 12 ++++++------ fs/locks.c | 14 +++++++------- include/uapi/asm-generic/fcntl.h | 20 ++++++++++---------- security/selinux/hooks.c | 6 +++--- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index 702bd329d9d0..e90a3148f385 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -203,9 +203,9 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, int ret; switch (cmd) { - case F_GETLKP: - case F_SETLKP: - case F_SETLKPW: + case F_OFD_GETLK: + case F_OFD_SETLK: + case F_OFD_SETLKW: case F_GETLK64: case F_SETLK64: case F_SETLKW64: diff --git a/fs/compat.c b/fs/compat.c index ca926ad0430c..66d3d3c6b4b2 100644 --- a/fs/compat.c +++ b/fs/compat.c @@ -457,9 +457,9 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, case F_GETLK64: case F_SETLK64: case F_SETLKW64: - case F_GETLKP: - case F_SETLKP: - case F_SETLKPW: + case F_OFD_GETLK: + case F_OFD_SETLK: + case F_OFD_SETLKW: ret = get_compat_flock64(&f, compat_ptr(arg)); if (ret != 0) break; @@ -468,7 +468,7 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, conv_cmd = convert_fcntl_cmd(cmd); ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f); set_fs(old_fs); - if ((conv_cmd == F_GETLK || conv_cmd == F_GETLKP) && ret == 0) { + if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) { /* need to return lock information - see above for commentary */ if (f.l_start > COMPAT_LOFF_T_MAX) ret = -EOVERFLOW; @@ -493,9 +493,9 @@ COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, case F_GETLK64: case F_SETLK64: case F_SETLKW64: - case F_GETLKP: - case F_SETLKP: - case F_SETLKPW: + case F_OFD_GETLK: + case F_OFD_SETLK: + case F_OFD_SETLKW: return -EINVAL; } return compat_sys_fcntl64(fd, cmd, arg); diff --git a/fs/fcntl.c b/fs/fcntl.c index 9ead1596399a..72c82f69b01b 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -274,15 +274,15 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, break; #if BITS_PER_LONG != 32 /* 32-bit arches must use fcntl64() */ - case F_GETLKP: + case F_OFD_GETLK: #endif case F_GETLK: err = fcntl_getlk(filp, cmd, (struct flock __user *) arg); break; #if BITS_PER_LONG != 32 /* 32-bit arches must use fcntl64() */ - case F_SETLKP: - case F_SETLKPW: + case F_OFD_SETLK: + case F_OFD_SETLKW: #endif /* Fallthrough */ case F_SETLK: @@ -399,13 +399,13 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, switch (cmd) { case F_GETLK64: - case F_GETLKP: + case F_OFD_GETLK: err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg); break; case F_SETLK64: case F_SETLKW64: - case F_SETLKP: - case F_SETLKPW: + case F_OFD_SETLK: + case F_OFD_SETLKW: err = fcntl_setlk64(fd, f.file, cmd, (struct flock64 __user *) arg); break; diff --git a/fs/locks.c b/fs/locks.c index b380f5543614..e1023b504279 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1941,7 +1941,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) if (error) goto out; - if (cmd == F_GETLKP) { + if (cmd == F_OFD_GETLK) { error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2076,7 +2076,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, * FL_FILE_PVT flag and override the owner. */ switch (cmd) { - case F_SETLKP: + case F_OFD_SETLK: error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2085,7 +2085,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, file_lock->fl_flags |= FL_FILE_PVT; file_lock->fl_owner = (fl_owner_t)filp; break; - case F_SETLKPW: + case F_OFD_SETLKW: error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2143,7 +2143,7 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) if (error) goto out; - if (cmd == F_GETLKP) { + if (cmd == F_OFD_GETLK) { error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2211,7 +2211,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, * FL_FILE_PVT flag and override the owner. */ switch (cmd) { - case F_SETLKP: + case F_OFD_SETLK: error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2220,7 +2220,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, file_lock->fl_flags |= FL_FILE_PVT; file_lock->fl_owner = (fl_owner_t)filp; break; - case F_SETLKPW: + case F_OFD_SETLKW: error = -EINVAL; if (flock.l_pid != 0) goto out; @@ -2413,7 +2413,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, if (fl->fl_flags & FL_ACCESS) seq_printf(f, "ACCESS"); else if (IS_FILE_PVT(fl)) - seq_printf(f, "FLPVT "); + seq_printf(f, "OFDLCK"); else seq_printf(f, "POSIX "); diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h index a9b13f8b3595..7543b3e51331 100644 --- a/include/uapi/asm-generic/fcntl.h +++ b/include/uapi/asm-generic/fcntl.h @@ -133,20 +133,20 @@ #endif /* - * fd "private" POSIX locks. + * Open File Description Locks * - * Usually POSIX locks held by a process are released on *any* close and are + * Usually record locks held by a process are released on *any* close and are * not inherited across a fork(). * - * These cmd values will set locks that conflict with normal POSIX locks, but - * are "owned" by the opened file, not the process. This means that they are - * inherited across fork() like BSD (flock) locks, and they are only released - * automatically when the last reference to the the open file against which - * they were acquired is put. + * These cmd values will set locks that conflict with process-associated + * record locks, but are "owned" by the open file description, not the + * process. This means that they are inherited across fork() like BSD (flock) + * locks, and they are only released automatically when the last reference to + * the the open file against which they were acquired is put. */ -#define F_GETLKP 36 -#define F_SETLKP 37 -#define F_SETLKPW 38 +#define F_OFD_GETLK 36 +#define F_OFD_SETLK 37 +#define F_OFD_SETLKW 38 #define F_OWNER_TID 0 #define F_OWNER_PID 1 diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b4beb77967b1..2c7341dbc5d6 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3317,9 +3317,9 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, case F_GETLK: case F_SETLK: case F_SETLKW: - case F_GETLKP: - case F_SETLKP: - case F_SETLKPW: + case F_OFD_GETLK: + case F_OFD_SETLK: + case F_OFD_SETLKW: #if BITS_PER_LONG == 32 case F_GETLK64: case F_SETLK64: -- GitLab From 7e95cfb0b797678cd3493ca0322ef2675547a0bc Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 22 Apr 2014 08:17:18 -0400 Subject: [PATCH 579/797] drm/radeon: fix count in cik_sdma_ring_test() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Should be 5 rather than 4. Noticed-by: Mathias Fröhlich Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Signed-off-by: Christian König --- drivers/gpu/drm/radeon/cik_sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index 89b4afa5041c..f7e46cf682af 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c @@ -597,7 +597,7 @@ int cik_sdma_ring_test(struct radeon_device *rdev, tmp = 0xCAFEDEAD; writel(tmp, ptr); - r = radeon_ring_lock(rdev, ring, 4); + r = radeon_ring_lock(rdev, ring, 5); if (r) { DRM_ERROR("radeon: dma failed to lock ring %d (%d).\n", ring->idx, r); return r; -- GitLab From 4c5fba3d4ae3a7aae2c4a56d4a234aa556b7caca Mon Sep 17 00:00:00 2001 From: Christian Ruppert Date: Fri, 11 Apr 2014 16:46:04 +0200 Subject: [PATCH 580/797] pinctrl/TB10x: Fix signedness bug In the TB10x pin database, a port index of -1 is used to indicate unmuxed GPIO pin groups. This bug fixes a 'cast to unsigned' bug of this value. Thanks to Dan Carpenter for highlighting this. CC: Dan Carpenter Signed-off-by: Christian Ruppert Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-tb10x.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index c5e0f6973a3b..26ca6855f478 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c @@ -629,9 +629,8 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl, */ for (i = 0; i < state->pinfuncgrpcnt; i++) { const struct tb10x_pinfuncgrp *pfg = &state->pingroups[i]; - unsigned int port = pfg->port; unsigned int mode = pfg->mode; - int j; + int j, port = pfg->port; /* * Skip pin groups which are always mapped and don't need -- GitLab From cb3e4e7c59e4b43ac378631f6101f5c8de3a27a5 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Apr 2014 12:44:32 -0400 Subject: [PATCH 581/797] drm/radeon: properly unregister hwmon interface (v2) Need to properly unregister the hwmon device on driver unload. v2: minor clean up bug: https://bugzilla.kernel.org/show_bug.cgi?id=73931 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_pm.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 0c4473db8501..d79895aebc59 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -603,7 +603,6 @@ static const struct attribute_group *hwmon_groups[] = { static int radeon_hwmon_init(struct radeon_device *rdev) { int err = 0; - struct device *hwmon_dev; switch (rdev->pm.int_thermal_type) { case THERMAL_TYPE_RV6XX: @@ -616,11 +615,11 @@ static int radeon_hwmon_init(struct radeon_device *rdev) case THERMAL_TYPE_KV: if (rdev->asic->pm.get_temperature == NULL) return err; - hwmon_dev = hwmon_device_register_with_groups(rdev->dev, - "radeon", rdev, - hwmon_groups); - if (IS_ERR(hwmon_dev)) { - err = PTR_ERR(hwmon_dev); + rdev->pm.int_hwmon_dev = hwmon_device_register_with_groups(rdev->dev, + "radeon", rdev, + hwmon_groups); + if (IS_ERR(rdev->pm.int_hwmon_dev)) { + err = PTR_ERR(rdev->pm.int_hwmon_dev); dev_err(rdev->dev, "Unable to register hwmon device: %d\n", err); } @@ -632,6 +631,12 @@ static int radeon_hwmon_init(struct radeon_device *rdev) return err; } +static void radeon_hwmon_fini(struct radeon_device *rdev) +{ + if (rdev->pm.int_hwmon_dev) + hwmon_device_unregister(rdev->pm.int_hwmon_dev); +} + static void radeon_dpm_thermal_work_handler(struct work_struct *work) { struct radeon_device *rdev = @@ -1353,6 +1358,8 @@ static void radeon_pm_fini_old(struct radeon_device *rdev) device_remove_file(rdev->dev, &dev_attr_power_method); } + radeon_hwmon_fini(rdev); + if (rdev->pm.power_state) kfree(rdev->pm.power_state); } @@ -1372,6 +1379,8 @@ static void radeon_pm_fini_dpm(struct radeon_device *rdev) } radeon_dpm_fini(rdev); + radeon_hwmon_fini(rdev); + if (rdev->pm.power_state) kfree(rdev->pm.power_state); } -- GitLab From 3ed9a335cfc64b2c83545f341cdddf2347b12b97 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Apr 2014 12:44:33 -0400 Subject: [PATCH 582/797] drm/radeon/pm: don't walk the crtc list before it has been initialized (v2) Avoids a crash in certain cases when thermal irqs are generated before the display structures have been initialized. v2: fix the vblank and vrefresh helpers as well bug: https://bugzilla.kernel.org/show_bug.cgi?id=73931 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/r600_dpm.c | 35 ++++++++++++++++-------------- drivers/gpu/drm/radeon/radeon_pm.c | 28 ++++++++++++++---------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index cbf7e3269f84..9c61b74ef441 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -158,16 +158,18 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev) u32 line_time_us, vblank_lines; u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { - line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / - radeon_crtc->hw_mode.clock; - vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - - radeon_crtc->hw_mode.crtc_vdisplay + - (radeon_crtc->v_border * 2); - vblank_time_us = vblank_lines * line_time_us; - break; + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { + line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) / + radeon_crtc->hw_mode.clock; + vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end - + radeon_crtc->hw_mode.crtc_vdisplay + + (radeon_crtc->v_border * 2); + vblank_time_us = vblank_lines * line_time_us; + break; + } } } @@ -181,14 +183,15 @@ u32 r600_dpm_get_vrefresh(struct radeon_device *rdev) struct radeon_crtc *radeon_crtc; u32 vrefresh = 0; - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { - vrefresh = radeon_crtc->hw_mode.vrefresh; - break; + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) { + vrefresh = radeon_crtc->hw_mode.vrefresh; + break; + } } } - return vrefresh; } diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index d79895aebc59..6fac8efe8340 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -1406,12 +1406,14 @@ static void radeon_pm_compute_clocks_old(struct radeon_device *rdev) rdev->pm.active_crtcs = 0; rdev->pm.active_crtc_count = 0; - list_for_each_entry(crtc, - &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (radeon_crtc->enabled) { - rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); - rdev->pm.active_crtc_count++; + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, + &ddev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (radeon_crtc->enabled) { + rdev->pm.active_crtcs |= (1 << radeon_crtc->crtc_id); + rdev->pm.active_crtc_count++; + } } } @@ -1478,12 +1480,14 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev) /* update active crtc counts */ rdev->pm.dpm.new_active_crtcs = 0; rdev->pm.dpm.new_active_crtc_count = 0; - list_for_each_entry(crtc, - &ddev->mode_config.crtc_list, head) { - radeon_crtc = to_radeon_crtc(crtc); - if (crtc->enabled) { - rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); - rdev->pm.dpm.new_active_crtc_count++; + if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) { + list_for_each_entry(crtc, + &ddev->mode_config.crtc_list, head) { + radeon_crtc = to_radeon_crtc(crtc); + if (crtc->enabled) { + rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id); + rdev->pm.dpm.new_active_crtc_count++; + } } } -- GitLab From e9a4099a59cc598a44006059dd775c25e422b772 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Apr 2014 12:44:34 -0400 Subject: [PATCH 583/797] drm/radeon: fix ATPX detection on non-VGA GPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some newer PX laptops have the pci device class set to DISPLAY_OTHER rather than DISPLAY_VGA. This properly detects ATPX on those laptops. Based on a patch from: Pali Rohár Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org Cc: airlied@gmail.com --- drivers/gpu/drm/radeon/radeon_atpx_handler.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index dedea72f48c4..a9fb0d016d38 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c @@ -528,6 +528,13 @@ static bool radeon_atpx_detect(void) has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); } + /* some newer PX laptops mark the dGPU as a non-VGA display device */ + while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) { + vga_count++; + + has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true); + } + if (has_atpx && vga_count == 2) { acpi_get_name(radeon_atpx_priv.atpx.handle, ACPI_FULL_PATHNAME, &buffer); printk(KERN_INFO "VGA switcheroo: detected switching method %s handle\n", -- GitLab From 73acacc7397fe854ed2ab75f1c940fa00faaf15e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 15 Apr 2014 12:44:35 -0400 Subject: [PATCH 584/797] drm/radeon: don't allow runpm=1 on systems with out ATPX vgaswitcheroo and the ATPX ACPI methods are required to power down the dGPU. bug: https://bugzilla.kernel.org/show_bug.cgi?id=73901 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_kms.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index fb3d13f693dd..0cc47f12d995 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -107,11 +107,9 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) flags |= RADEON_IS_PCI; } - if (radeon_runtime_pm == 1) - flags |= RADEON_IS_PX; - else if ((radeon_runtime_pm == -1) && - radeon_has_atpx() && - ((flags & RADEON_IS_IGP) == 0)) + if ((radeon_runtime_pm != 0) && + radeon_has_atpx() && + ((flags & RADEON_IS_IGP) == 0)) flags |= RADEON_IS_PX; /* radeon_device_init should report only fatal error -- GitLab From a73d2e30b46787d478275db36c19222020e29dc5 Mon Sep 17 00:00:00 2001 From: Andrew Bresticker Date: Wed, 16 Apr 2014 13:40:17 -0700 Subject: [PATCH 585/797] pinctrl: as3722: fix handling of GPIO invert bit The AS3722_GPIO_INV bit will always be blindly overwritten by as3722_pinctrl_gpio_set_direction() and will be ignored when setting the value of the GPIO in as3722_gpio_set() since the enable_gpio_invert flag is never set. This will cause an initially inverted GPIO to toggle when requested as an output, which could be problematic if, for example, the GPIO controls a critical regulator. Instead of setting up the enable_gpio_invert flag, just leave the invert bit alone and check it before setting the GPIO value. Cc: # v3.14+ Signed-off-by: Andrew Bresticker Reviewed-by: Stephen Warren Tested-by: Stephen Warren Acked-by: Laxman Dewangan Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-as3722.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/pinctrl/pinctrl-as3722.c b/drivers/pinctrl/pinctrl-as3722.c index 92ed4b2e3c07..c862f9c0e9ce 100644 --- a/drivers/pinctrl/pinctrl-as3722.c +++ b/drivers/pinctrl/pinctrl-as3722.c @@ -64,7 +64,6 @@ struct as3722_pin_function { }; struct as3722_gpio_pin_control { - bool enable_gpio_invert; unsigned mode_prop; int io_function; }; @@ -320,10 +319,8 @@ static int as3722_pinctrl_gpio_set_direction(struct pinctrl_dev *pctldev, return mode; } - if (as_pci->gpio_control[offset].enable_gpio_invert) - mode |= AS3722_GPIO_INV; - - return as3722_write(as3722, AS3722_GPIOn_CONTROL_REG(offset), mode); + return as3722_update_bits(as3722, AS3722_GPIOn_CONTROL_REG(offset), + AS3722_GPIO_MODE_MASK, mode); } static const struct pinmux_ops as3722_pinmux_ops = { @@ -496,10 +493,18 @@ static void as3722_gpio_set(struct gpio_chip *chip, unsigned offset, { struct as3722_pctrl_info *as_pci = to_as_pci(chip); struct as3722 *as3722 = as_pci->as3722; - int en_invert = as_pci->gpio_control[offset].enable_gpio_invert; + int en_invert; u32 val; int ret; + ret = as3722_read(as3722, AS3722_GPIOn_CONTROL_REG(offset), &val); + if (ret < 0) { + dev_err(as_pci->dev, + "GPIO_CONTROL%d_REG read failed: %d\n", offset, ret); + return; + } + en_invert = !!(val & AS3722_GPIO_INV); + if (value) val = (en_invert) ? 0 : AS3722_GPIOn_SIGNAL(offset); else -- GitLab From 838977f0178334bf3d7f3e974ea3154b68979be0 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 11 Apr 2014 11:25:40 +0100 Subject: [PATCH 586/797] arm64: __NR_compat_syscalls fix This fixes commit 6290b53de025 (arm64: compat: Wire up new AArch32 syscalls) which did not update __NR_compat_syscalls accordingly. Signed-off-by: Miklos Szeredi Cc: # 3.14+ Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/unistd32.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index bb8eb8a78e67..faa0e1ce59df 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -404,7 +404,7 @@ __SYSCALL(379, sys_finit_module) __SYSCALL(380, sys_sched_setattr) __SYSCALL(381, sys_sched_getattr) -#define __NR_compat_syscalls 379 +#define __NR_compat_syscalls 382 /* * Compat syscall numbers used by the AArch64 kernel. -- GitLab From 40732b369a715e2d17e7c0c9997a5b89ad666168 Mon Sep 17 00:00:00 2001 From: Hanjun Guo Date: Thu, 3 Apr 2014 12:16:49 +0100 Subject: [PATCH 587/797] ARM64: Remove duplicated Kconfig entry for "kernel/power/Kconfig" There is a duplicated Kconfig entry for "kernel/power/Kconfig" in menu "Power management options" and "CPU Power Management", remove the one from menu "CPU Power Management" suggested by Viresh. Signed-off-by: Hanjun Guo Reviewed-by: Viresh Kumar Signed-off-by: Catalin Marinas --- arch/arm64/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index e6e4d3749a6e..e759af5d7098 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -323,8 +323,6 @@ menu "CPU Power Management" source "drivers/cpuidle/Kconfig" -source "kernel/power/Kconfig" - source "drivers/cpufreq/Kconfig" endmenu -- GitLab From 95e9ee92e20162681e9f65c25962e0606db9d149 Mon Sep 17 00:00:00 2001 From: Wenkai Du Date: Tue, 22 Apr 2014 16:38:54 +0300 Subject: [PATCH 588/797] ASoC: Intel: Fix audio crash due to negative address offset There were occasional ADSP crash during reboot testing: [ 11.883364] BUG: unable to handle kernel paging request at ffffc90121700000 [ 11.883380] IP: [] sst_module_insert_fixed_block+0x24f/0x26d [snd_soc_sst_dsp] [ 11.883397] PGD 7800b067 PUD 0 [ 11.883405] Oops: 0002 [#1] SMP [ 11.886418] gsmi: Log Shutdown Reason 0x03 The virtual address, ffffc90121700000, was out of range. The virtual address is calculated by adding LPE base address with an offset: sst_memcpy32(dsp->addr.lpe + data->offset, data->data, data->size); The offset is calculated in sst_byt_parse_module, by subtraction of two virtual addresses dsp->addr.fw_ext and dsp->addr.lpe: block_data.offset = block->ram_offset + (dsp->addr.fw_ext - dsp->addr.lpe); These virtual addresses are assigned by kernel from ioremap: sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size); sst->addr.fw_ext = ioremap(pdata->fw_base, pdata->fw_size); In current driver code, offset is defined as unsigned int32: struct sst_module_data { ... u32 offset; /* offset in FW file */ }; Most of the time kernel assigned virtual addresses with addr.fw_ext greater than addr.lpe. But sometimes it was the other way round. Fix the problem by declaring offset as signed int32_t. Signed-off-by: Wenkai Du Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/intel/sst-dsp-priv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h index fe8e81aad646..30ca14a6a835 100644 --- a/sound/soc/intel/sst-dsp-priv.h +++ b/sound/soc/intel/sst-dsp-priv.h @@ -136,7 +136,7 @@ struct sst_module_data { enum sst_data_type data_type; /* type of module data */ u32 size; /* size in bytes */ - u32 offset; /* offset in FW file */ + int32_t offset; /* offset in FW file */ u32 data_offset; /* offset in ADSP memory space */ void *data; /* module data */ }; -- GitLab From 1b17844b29ae042576bea588164f2f1e9590a8bc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 22 Apr 2014 13:49:40 -0700 Subject: [PATCH 589/797] mm: make fixup_user_fault() check the vma access rights too fixup_user_fault() is used by the futex code when the direct user access fails, and the futex code wants it to either map in the page in a usable form or return an error. It relied on handle_mm_fault() to map the page, and correctly checked the error return from that, but while that does map the page, it doesn't actually guarantee that the page will be mapped with sufficient permissions to be then accessed. So do the appropriate tests of the vma access rights by hand. [ Side note: arguably handle_mm_fault() could just do that itself, but we have traditionally done it in the caller, because some callers - notably get_user_pages() - have been able to access pages even when they are mapped with PROT_NONE. Maybe we should re-visit that design decision, but in the meantime this is the minimal patch. ] Found by Dave Jones running his trinity tool. Reported-by: Dave Jones Acked-by: Hugh Dickins Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds --- mm/memory.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/memory.c b/mm/memory.c index d0f0bef3be48..93e332d5ed77 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1955,12 +1955,17 @@ int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, unsigned long address, unsigned int fault_flags) { struct vm_area_struct *vma; + vm_flags_t vm_flags; int ret; vma = find_extend_vma(mm, address); if (!vma || address < vma->vm_start) return -EFAULT; + vm_flags = (fault_flags & FAULT_FLAG_WRITE) ? VM_WRITE : VM_READ; + if (!(vm_flags & vma->vm_flags)) + return -EFAULT; + ret = handle_mm_fault(mm, vma, address, fault_flags); if (ret & VM_FAULT_ERROR) { if (ret & VM_FAULT_OOM) -- GitLab From eebdec044e82a4c694b7c1f4996e3ab82d64482c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 22 Apr 2014 22:46:31 +0200 Subject: [PATCH 590/797] ASoC: jz4740: Remove Makefile entry for removed file Commit 0406a40a0 ("ASoC: jz4740: Use the generic dmaengine PCM driver") jz4740-pcm.c file, but neglected to remove the Makefile entries. Fixes: 0406a40a0 ("ASoC: jz4740: Use the generic dmaengine PCM driver") Reported-by: kbuild test robot Reported-by: Ralf Baechle Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/jz4740/Makefile | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/jz4740/Makefile b/sound/soc/jz4740/Makefile index be873c1b0c20..d32c540555c4 100644 --- a/sound/soc/jz4740/Makefile +++ b/sound/soc/jz4740/Makefile @@ -1,10 +1,8 @@ # # Jz4740 Platform Support # -snd-soc-jz4740-objs := jz4740-pcm.o snd-soc-jz4740-i2s-objs := jz4740-i2s.o -obj-$(CONFIG_SND_JZ4740_SOC) += snd-soc-jz4740.o obj-$(CONFIG_SND_JZ4740_SOC_I2S) += snd-soc-jz4740-i2s.o # Jz4740 Machine Support -- GitLab From 80bb3ef109ff40a7593d9481c17de9bbc4d7c0e2 Mon Sep 17 00:00:00 2001 From: Xiangyu Lu Date: Tue, 15 Apr 2014 09:38:17 +0100 Subject: [PATCH 591/797] ARM: 8027/1: fix do_div() bug in big-endian systems In big-endian systems, "%1" get the most significant part of the value, cause the instruction to get the wrong result. When viewing ftrace record in big-endian ARM systems, we found that the timestamp errors: swapper-0 [001] 1325.970000: 0:120:R ==> [001] 16:120:R events/1 events/1-16 [001] 1325.970000: 16:120:S ==> [001] 0:120:R swapper swapper-0 [000] 1325.1000000: 0:120:R + [000] 15:120:R events/0 swapper-0 [000] 1325.1000000: 0:120:R ==> [000] 15:120:R events/0 swapper-0 [000] 1326.030000: 0:120:R + [000] 1150:120:R sshd swapper-0 [000] 1326.030000: 0:120:R ==> [000] 1150:120:R sshd When viewed ftrace records, it will call the do_div(n, base) function, which achieved arch/arm/include/asm/div64.h in. When n = 10000000, base = 1000000, in do_div(n, base) will execute "umull %Q0, %R0, %1, %Q2". Reviewed-by: Dave Martin Reviewed-by: Nicolas Pitre Cc: # 2.6.20+ Signed-off-by: Alex Wu Signed-off-by: Xiangyu Lu Signed-off-by: Russell King --- arch/arm/include/asm/div64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h index 191ada6e4d2d..662c7bd06108 100644 --- a/arch/arm/include/asm/div64.h +++ b/arch/arm/include/asm/div64.h @@ -156,7 +156,7 @@ /* Select the best insn combination to perform the */ \ /* actual __m * __n / (__p << 64) operation. */ \ if (!__c) { \ - asm ( "umull %Q0, %R0, %1, %Q2\n\t" \ + asm ( "umull %Q0, %R0, %Q1, %Q2\n\t" \ "mov %Q0, #0" \ : "=&r" (__res) \ : "r" (__m), "r" (__n) \ -- GitLab From 56b700fd6f1e49149880fb1b6ffee0dca5be45fb Mon Sep 17 00:00:00 2001 From: Liu Hua Date: Fri, 18 Apr 2014 07:45:36 +0100 Subject: [PATCH 592/797] ARM: 8030/1: ARM : kdump : add arch_crash_save_vmcoreinfo For vmcore generated by LPAE enabled kernel, user space utility such as crash needs additional infomation to parse. So this patch add arch_crash_save_vmcoreinfo as what PAE enabled i386 linux does. Cc: Reviewed-by: Will Deacon Signed-off-by: Liu Hua Signed-off-by: Russell King --- arch/arm/kernel/machine_kexec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index f0d180d8b29f..8cf0996aa1a8 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -184,3 +184,10 @@ void machine_kexec(struct kimage *image) soft_restart(reboot_entry_phys); } + +void arch_crash_save_vmcoreinfo(void) +{ +#ifdef CONFIG_ARM_LPAE + VMCOREINFO_CONFIG(ARM_LPAE); +#endif +} -- GitLab From 4530e4b6a450af14973c2b0703edfb02d66cbd41 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Tue, 22 Apr 2014 00:25:35 +0100 Subject: [PATCH 593/797] ARM: 8032/1: bL_switcher: fix validation check before its activation The switcher should not depend on MAX_CLUSTER to determine ifit should be activated or not. In a multiplatform kernel binary it is possible to have dual-cluster and quad-cluster platforms configured in. In that case MAX_CLUSTER which is a build time limit should be 4 and that shouldn't prevent the switcher from working if the kernel is booted on a b.L dual-cluster system. In bL_switcher_halve_cpus() we already have a runtime validation check to make sure we're dealing with only two clusters, so booting on a quad cluster system will be caught and switcher activation aborted. However, the b.L switcher must ensure the MCPM layer is initialized on the booted hardware before doing anything. The mcpm_is_available() function is added to that effect. Signed-off-by: Nicolas Pitre Tested-by: Abhilash Kesavan Signed-off-by: Russell King --- arch/arm/common/bL_switcher.c | 6 ++---- arch/arm/common/mcpm_entry.c | 5 +++++ arch/arm/include/asm/mcpm.h | 7 +++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/arch/arm/common/bL_switcher.c b/arch/arm/common/bL_switcher.c index 5774b6ea7ad5..f01c0ee0c87e 100644 --- a/arch/arm/common/bL_switcher.c +++ b/arch/arm/common/bL_switcher.c @@ -797,10 +797,8 @@ static int __init bL_switcher_init(void) { int ret; - if (MAX_NR_CLUSTERS != 2) { - pr_err("%s: only dual cluster systems are supported\n", __func__); - return -EINVAL; - } + if (!mcpm_is_available()) + return -ENODEV; cpu_notifier(bL_switcher_hotplug_callback, 0); diff --git a/arch/arm/common/mcpm_entry.c b/arch/arm/common/mcpm_entry.c index 1e361abc29eb..86fd60fefbc9 100644 --- a/arch/arm/common/mcpm_entry.c +++ b/arch/arm/common/mcpm_entry.c @@ -48,6 +48,11 @@ int __init mcpm_platform_register(const struct mcpm_platform_ops *ops) return 0; } +bool mcpm_is_available(void) +{ + return (platform_ops) ? true : false; +} + int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster) { if (!platform_ops) diff --git a/arch/arm/include/asm/mcpm.h b/arch/arm/include/asm/mcpm.h index 608516ebabfe..a5ff410dcdb6 100644 --- a/arch/arm/include/asm/mcpm.h +++ b/arch/arm/include/asm/mcpm.h @@ -53,6 +53,13 @@ void mcpm_set_early_poke(unsigned cpu, unsigned cluster, * CPU/cluster power operations API for higher subsystems to use. */ +/** + * mcpm_is_available - returns whether MCPM is initialized and available + * + * This returns true or false accordingly. + */ +bool mcpm_is_available(void); + /** * mcpm_cpu_power_up - make given CPU in given cluster runable * -- GitLab From e3892e9160a6ae40abc45192df30f3e31b6dd0ff Mon Sep 17 00:00:00 2001 From: Victor Kamensky Date: Tue, 22 Apr 2014 02:25:36 +0100 Subject: [PATCH 594/797] ARM: 8033/1: fix big endian __pv_phys_pfn_offset size related issue Fix e26a9e00afc482b971afcaef1db8c9034d4d6d7c 'ARM: Better virt_to_page() handling' replaced __pv_phys_offset with __pv_phys_pfn_offset. Also note that size of __pv_phys_offset was quad but size of __pv_phys_pfn_offset is word. Instruction that used to update __pv_phys_offset which address is in r6 had to update low word of __pv_phys_offset so it used #LOW_OFFSET macro for store offset. Now when size of __pv_phys_pfn_offset is word, no difference between little endian and big endian should exist - i.e no offset should be used when __pv_phys_pfn_offset is stored. Note that for little endian image proposed change is noop, since in little endian case #LOW_OFFSET is defined 0 anyway. Reported-by: Taras Kondratiuk Signed-off-by: Victor Kamensky Acked-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/head.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index f8c08839edf3..591d6e4a6492 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -587,7 +587,7 @@ __fixup_pv_table: add r6, r6, r3 @ adjust __pv_phys_pfn_offset address add r7, r7, r3 @ adjust __pv_offset address mov r0, r8, lsr #12 @ convert to PFN - str r0, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset + str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits mov r6, r3, lsr #24 @ constant for add/sub instructions teq r3, r6, lsl #24 @ must be 16MiB aligned -- GitLab From 132e9a68a5794ad2e4a3d0c07dfb7133a70b1651 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 15 Apr 2014 11:05:16 -0400 Subject: [PATCH 595/797] Fix: tracing: use 'E' instead of 'X' for unsigned module tain flag In the following commit: commit 57673c2b0baa900dddae3b9eb3d7748ebf550eb3 Author: Rusty Russell Date: Mon Mar 31 14:39:57 2014 +1030 Use 'E' instead of 'X' for unsigned module taint flag. One site has been forgotten in trace events module.h. Signed-off-by: Mathieu Desnoyers CC: Steven Rostedt CC: Rusty Russell Signed-off-by: Rusty Russell --- include/trace/events/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/trace/events/module.h b/include/trace/events/module.h index 11fd51b413de..ed0b2c599a64 100644 --- a/include/trace/events/module.h +++ b/include/trace/events/module.h @@ -25,7 +25,7 @@ struct module; { (1UL << TAINT_OOT_MODULE), "O" }, \ { (1UL << TAINT_FORCED_MODULE), "F" }, \ { (1UL << TAINT_CRAP), "C" }, \ - { (1UL << TAINT_UNSIGNED_MODULE), "X" }) + { (1UL << TAINT_UNSIGNED_MODULE), "E" }) TRACE_EVENT(module_load, -- GitLab From 7740fc52105c9e6d2beac389a9ae0ce7138cf5ab Mon Sep 17 00:00:00 2001 From: Lejun Zhu Date: Tue, 22 Apr 2014 22:47:13 -0700 Subject: [PATCH 596/797] Input: soc_button_array - fix a crash during rmmod When the system has zero or one button available, trying to rmmod soc_button_array will cause crash. Fix this by properly handling -ENODEV in probe(). Signed-off-by: Lejun Zhu Signed-off-by: Dmitry Torokhov --- drivers/input/misc/soc_button_array.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 08ead2aaede5..20c80f543d5e 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -169,6 +169,7 @@ static int soc_button_pnp_probe(struct pnp_dev *pdev, soc_button_remove(pdev); return error; } + continue; } priv->children[i] = pd; -- GitLab From ae4bedf0679d99f0a9b80a7ea9b8dd205de05d06 Mon Sep 17 00:00:00 2001 From: Jordan Rife Date: Tue, 22 Apr 2014 17:44:51 -0700 Subject: [PATCH 597/797] Input: elantech - add support for newer elantech touchpads Newer elantech touchpads are not recognized by the current driver, since it fails to detect their firmware version number. This prevents more advanced touchpad features from being usable such as two-finger scrolling. This patch allows newer touchpads to be detected and be fully functional. Tested on Sony Vaio SVF13N17PXB. Signed-off-by: Jordan Rife Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elantech.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index ef1cf52f8bb9..088d3541c7d3 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1353,6 +1353,7 @@ static int elantech_set_properties(struct elantech_data *etd) case 6: case 7: case 8: + case 9: etd->hw_version = 4; break; default: -- GitLab From 9953599bc02dbc1d3330e6a0bfc6c50e9dffcac6 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 13 Apr 2014 12:00:33 +0200 Subject: [PATCH 598/797] drm/i915: Don't check gmch state on inherited configs ... our current modeset code isn't good enough yet to handle this. The scenario is: 1. BIOS sets up a cloned config with lvds+external screen on the same pipe, e.g. pipe B. 2. We read out that state for pipe B and assign the gmch_pfit state to it. 3. The initial modeset switches the lvds to pipe A but due to lack of atomic modeset we don't recompute the config of pipe B. -> both pipes now claim (in the sw pipe config structure) to use the gmch_pfit, which just won't work. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=74081 Tested-by: max Cc: Alan Stern Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_display.c | 23 ++++++++++++++++++----- drivers/gpu/drm/i915/intel_drv.h | 3 ++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index dae976f51d83..69bcc42a0e44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9654,11 +9654,22 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_I(pipe_src_w); PIPE_CONF_CHECK_I(pipe_src_h); - PIPE_CONF_CHECK_I(gmch_pfit.control); - /* pfit ratios are autocomputed by the hw on gen4+ */ - if (INTEL_INFO(dev)->gen < 4) - PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); - PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); + /* + * FIXME: BIOS likes to set up a cloned config with lvds+external + * screen. Since we don't yet re-compute the pipe config when moving + * just the lvds port away to another pipe the sw tracking won't match. + * + * Proper atomic modesets with recomputed global state will fix this. + * Until then just don't check gmch state for inherited modes. + */ + if (!PIPE_CONF_QUIRK(PIPE_CONFIG_QUIRK_INHERITED_MODE)) { + PIPE_CONF_CHECK_I(gmch_pfit.control); + /* pfit ratios are autocomputed by the hw on gen4+ */ + if (INTEL_INFO(dev)->gen < 4) + PIPE_CONF_CHECK_I(gmch_pfit.pgm_ratios); + PIPE_CONF_CHECK_I(gmch_pfit.lvds_border_bits); + } + PIPE_CONF_CHECK_I(pch_pfit.enabled); if (current_config->pch_pfit.enabled) { PIPE_CONF_CHECK_I(pch_pfit.pos); @@ -11616,6 +11627,8 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) base.head) { memset(&crtc->config, 0, sizeof(crtc->config)); + crtc->config.quirks |= PIPE_CONFIG_QUIRK_INHERITED_MODE; + crtc->active = dev_priv->display.get_pipe_config(crtc, &crtc->config); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0542de982260..328b1a70264b 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -236,7 +236,8 @@ struct intel_crtc_config { * tracked with quirk flags so that fastboot and state checker can act * accordingly. */ -#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ +#define PIPE_CONFIG_QUIRK_MODE_SYNC_FLAGS (1<<0) /* unreliable sync mode.flags */ +#define PIPE_CONFIG_QUIRK_INHERITED_MODE (1<<1) /* mode inherited from firmware */ unsigned long quirks; /* User requested mode, only valid as a starting point to -- GitLab From 636352173a0dd127636fe331c97b117a8004bf50 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 22 Apr 2014 19:55:42 -0300 Subject: [PATCH 599/797] drm/i915: get power domain in case the BIOS enabled eDP VDD If I unplug the eDP monitor, the BIOS of my machine will enable the VDD bit, then when the driver loads it will think VDD is enabled. It will detect that the eDP is not enabled and return false from intel_edp_init_connector. This will trigger a call to edp_panel_vdd_off_sync(), which trigger a WARN saying that the refcount of the power domain is less than zero. The problem happens because the driver gets a refcount whenever it enables the VDD bit, and puts the refcount whenever it disables the VDD bit. But on this case, the BIOS enabled VDD, so all we do is to call put() without calling get() first, so the code added is there to make sure we always have the get() in case the BIOS enabled the bit. This regression was introduced in commit e9cb81a22841908b1c075156b409a538d09c8466 Author: Paulo Zanoni Date: Thu Nov 21 13:47:23 2013 -0200 drm/i915: get a runtime PM reference when the panel VDD is on v2: - Rebase Tested-by: Chris Wilson (v1) Reviewed-by: Daniel Vetter Cc: stable@vger.kernel.org (v3.13+) Signed-off-by: Paulo Zanoni Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dp.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d2a55884ad52..dfa85289f28f 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -3619,7 +3619,8 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, { struct drm_connector *connector = &intel_connector->base; struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; + struct intel_encoder *intel_encoder = &intel_dig_port->base; + struct drm_device *dev = intel_encoder->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_display_mode *fixed_mode = NULL; bool has_dpcd; @@ -3629,6 +3630,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, if (!is_edp(intel_dp)) return true; + /* The VDD bit needs a power domain reference, so if the bit is already + * enabled when we boot, grab this reference. */ + if (edp_have_panel_vdd(intel_dp)) { + enum intel_display_power_domain power_domain; + power_domain = intel_display_port_power_domain(intel_encoder); + intel_display_power_get(dev_priv, power_domain); + } + /* Cache DPCD and EDID for edp. */ intel_edp_panel_vdd_on(intel_dp); has_dpcd = intel_dp_get_dpcd(intel_dp); -- GitLab From 51aaf81fae8bf89b6bd277a244b5b43db9c730a0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 22 Apr 2014 22:26:27 +0100 Subject: [PATCH 600/797] ARM: keep arch/arm/Kconfig and arch/arm/mm/Kconfig select entries sorted Signed-off-by: Russell King --- arch/arm/Kconfig | 10 +++++----- arch/arm/mm/Kconfig | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ab438cb5af55..53e99eb543d9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -30,9 +30,9 @@ config ARM select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT) select HAVE_ARCH_TRACEHOOK select HAVE_BPF_JIT + select HAVE_CC_STACKPROTECTOR select HAVE_CONTEXT_TRACKING select HAVE_C_RECORDMCOUNT - select HAVE_CC_STACKPROTECTOR select HAVE_DEBUG_KMEMLEAK select HAVE_DMA_API_DEBUG select HAVE_DMA_ATTRS @@ -422,8 +422,8 @@ config ARCH_EFM32 bool "Energy Micro efm32" depends on !MMU select ARCH_REQUIRE_GPIOLIB - select AUTO_ZRELADDR select ARM_NVIC + select AUTO_ZRELADDR select CLKSRC_OF select COMMON_CLK select CPU_V7M @@ -511,8 +511,8 @@ config ARCH_IXP4XX bool "IXP4xx-based" depends on MMU select ARCH_HAS_DMA_SET_COHERENT_MASK - select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_REQUIRE_GPIOLIB + select ARCH_SUPPORTS_BIG_ENDIAN select CLKSRC_MMIO select CPU_XSCALE select DMABOUNCE if PCI @@ -1575,8 +1575,8 @@ config BIG_LITTLE config BL_SWITCHER bool "big.LITTLE switcher support" depends on BIG_LITTLE && MCPM && HOTPLUG_CPU - select CPU_PM select ARM_CPU_SUSPEND + select CPU_PM help The big.LITTLE "switcher" provides the core functionality to transparently handle transition between a cluster of A15's @@ -1920,9 +1920,9 @@ config XEN depends on CPU_V7 && !CPU_V6 depends on !GENERIC_ATOMIC64 depends on MMU + select ARCH_DMA_ADDR_T_64BIT select ARM_PSCI select SWIOTLB_XEN - select ARCH_DMA_ADDR_T_64BIT help Say Y if you want to run Linux in a Virtual Machine on Xen on ARM. diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index f5ad9ee70426..5bf7c3c3b301 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -420,29 +420,29 @@ config CPU_32v3 bool select CPU_USE_DOMAINS if MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP - select TLS_REG_EMUL if SMP || !MMU select NEED_KUSER_HELPERS + select TLS_REG_EMUL if SMP || !MMU config CPU_32v4 bool select CPU_USE_DOMAINS if MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP - select TLS_REG_EMUL if SMP || !MMU select NEED_KUSER_HELPERS + select TLS_REG_EMUL if SMP || !MMU config CPU_32v4T bool select CPU_USE_DOMAINS if MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP - select TLS_REG_EMUL if SMP || !MMU select NEED_KUSER_HELPERS + select TLS_REG_EMUL if SMP || !MMU config CPU_32v5 bool select CPU_USE_DOMAINS if MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP - select TLS_REG_EMUL if SMP || !MMU select NEED_KUSER_HELPERS + select TLS_REG_EMUL if SMP || !MMU config CPU_32v6 bool -- GitLab From c46a98ab1045565db6d858b628fbfde80f05281a Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 11 Apr 2014 11:25:41 +0100 Subject: [PATCH 601/797] arm64: add renameat2 compat syscall Wire up the renameat2 syscall for compat (AArch32) applications. Signed-off-by: Miklos Szeredi Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/unistd32.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/unistd32.h b/arch/arm64/include/asm/unistd32.h index faa0e1ce59df..c8d8fc17bd5a 100644 --- a/arch/arm64/include/asm/unistd32.h +++ b/arch/arm64/include/asm/unistd32.h @@ -403,8 +403,9 @@ __SYSCALL(378, sys_kcmp) __SYSCALL(379, sys_finit_module) __SYSCALL(380, sys_sched_setattr) __SYSCALL(381, sys_sched_getattr) +__SYSCALL(382, sys_renameat2) -#define __NR_compat_syscalls 382 +#define __NR_compat_syscalls 383 /* * Compat syscall numbers used by the AArch64 kernel. -- GitLab From 556d3f7f4d791cae54fd24ef28296e666f4c96a6 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 11 Apr 2014 12:25:39 +0200 Subject: [PATCH 602/797] ARM: add renameat2 syscall Signed-off-by: Miklos Szeredi [dropped arch/arm/include/asm/unistd.h changes --rmk] Signed-off-by: Russell King --- arch/arm/include/uapi/asm/unistd.h | 1 + arch/arm/kernel/calls.S | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h index fb5584d0cc05..ba94446c72d9 100644 --- a/arch/arm/include/uapi/asm/unistd.h +++ b/arch/arm/include/uapi/asm/unistd.h @@ -408,6 +408,7 @@ #define __NR_finit_module (__NR_SYSCALL_BASE+379) #define __NR_sched_setattr (__NR_SYSCALL_BASE+380) #define __NR_sched_getattr (__NR_SYSCALL_BASE+381) +#define __NR_renameat2 (__NR_SYSCALL_BASE+382) /* * This may need to be greater than __NR_last_syscall+1 in order to diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 166e945de832..8f51bdcdacbb 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -391,6 +391,7 @@ CALL(sys_finit_module) /* 380 */ CALL(sys_sched_setattr) CALL(sys_sched_getattr) + CALL(sys_renameat2) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted -- GitLab From 763d7f5f2718f085bab5a9e63308349728f3ad12 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Sun, 20 Apr 2014 00:16:41 +0900 Subject: [PATCH 603/797] perf tests x86: Fix memory leak in sample_ustack() The buf is not freed, when kernel failed to get stack map and return. Signed-off-by: Masanari Iida Link: http://lkml.kernel.org/r/1398091024-7901-1-git-send-email-standby24x7@gmail.com Signed-off-by: Jiri Olsa --- tools/perf/arch/x86/tests/dwarf-unwind.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index b602ad93ce63..b8c0102c70c8 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -26,6 +26,7 @@ static int sample_ustack(struct perf_sample *sample, map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp); if (!map) { pr_debug("failed to get stack map\n"); + free(buf); return -1; } -- GitLab From 4dc549e58b6ebf63554cd466d5ceb0e9c70ab859 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 20 Apr 2014 10:50:00 +0200 Subject: [PATCH 604/797] perf tools: Disable libdw unwind for all but x86 arch So far there's only x86 libdw unwind support merged in perf. Disable it on all other architectures in case libdw unwind support is detected in system. Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Josh Boyer Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1397988006-14158-1-git-send-email-jolsa@redhat.com Signed-off-by: Jiri Olsa --- tools/perf/config/Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index ee21fa95ebcf..a71fb395e38f 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -34,6 +34,14 @@ ifeq ($(ARCH),arm) LIBUNWIND_LIBS = -lunwind -lunwind-arm endif +# So far there's only x86 libdw unwind support merged in perf. +# Disable it on all other architectures in case libdw unwind +# support is detected in system. Add supported architectures +# to the check. +ifneq ($(ARCH),x86) + NO_LIBDW_DWARF_UNWIND := 1 +endif + ifeq ($(LIBUNWIND_LIBS),) NO_LIBUNWIND := 1 else -- GitLab From 4508793541140723ab862d83095f6b5141d24e49 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 21 Apr 2014 22:23:46 -0400 Subject: [PATCH 605/797] tools lib traceevent: Fix backward compatibility macros for pevent filter enums The return value for pevent_filter_match() is suppose to return FILTER_NONE if the event doesn't have a filter, and FILTER_NOEXIST if there is no filter at all. But the change 41e12e580a7 "tools lib traceevent: Refactor pevent_filter_match() to get rid of die()" replaced the return value with PEVENT_ERRNO__* values and added "backward compatibility" macros that used the old names. Unfortunately, the NOEXIST and NONE macros were swapped, and this broke users that use the old return names. Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20140421222346.0351ced4@gandalf.local.home Signed-off-by: Jiri Olsa --- tools/lib/traceevent/event-parse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 791c539374c7..feab94281634 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -876,8 +876,8 @@ struct event_filter { struct event_filter *pevent_filter_alloc(struct pevent *pevent); /* for backward compatibility */ -#define FILTER_NONE PEVENT_ERRNO__FILTER_NOT_FOUND -#define FILTER_NOEXIST PEVENT_ERRNO__NO_FILTER +#define FILTER_NONE PEVENT_ERRNO__NO_FILTER +#define FILTER_NOEXIST PEVENT_ERRNO__FILTER_NOT_FOUND #define FILTER_MISS PEVENT_ERRNO__FILTER_MISS #define FILTER_MATCH PEVENT_ERRNO__FILTER_MATCH -- GitLab From de04f8657de9d3351a2d5880f1f7080b23b798cf Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 22 Apr 2014 19:23:30 -0400 Subject: [PATCH 606/797] tools lib traceevent: Fix memory leak in pretty_print() Commit 12e55569a244 "tools lib traceevent: Use helper trace-seq in print functions like kernel does" added a extra trace_seq helper to process string arguments like the kernel does it. But the difference between the kernel and the userspace library is that the kernel's trace_seq structure has a static allocated buffer. The userspace one has a dynamically allocated one. It requires a trace_seq_destroy(), otherwise it produces a nasty memory leak. Cc: stable@vger.kernel.org # 3.14+ Signed-off-by: Steven Rostedt Link: http://lkml.kernel.org/r/20140422192330.6bb09bf8@gandalf.local.home Signed-off-by: Jiri Olsa --- tools/lib/traceevent/event-parse.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index baec7d887da4..b83184f2d484 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -4344,6 +4344,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event format, len_arg, arg); trace_seq_terminate(&p); trace_seq_puts(s, p.buffer); + trace_seq_destroy(&p); arg = arg->next; break; default: -- GitLab From ae107d06137ce210ea21d1423443d3638599f297 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 22 Apr 2014 20:40:25 +0200 Subject: [PATCH 607/797] dt: Fix binding typos in clock-names and interrupt-names s/interrupts-names/interrupt-names/g s/clocks-names/clock-names/g Some of the binding files and device tree files get this wrong and the kernel won't be able to pick it up. Fix them up now so that they don't get widely used. Signed-off-by: Geert Uytterhoeven Acked-by : Patrice Chotard Signed-off-by: Grant Likely --- .../devicetree/bindings/net/socfpga-dwmac.txt | 2 +- Documentation/devicetree/bindings/net/stmmac.txt | 2 +- .../devicetree/bindings/pinctrl/pinctrl-st.txt | 4 ++-- .../devicetree/bindings/sound/davinci-mcasp-audio.txt | 2 +- arch/arm/boot/dts/am33xx.dtsi | 4 ++-- arch/arm/boot/dts/am4372.dtsi | 4 ++-- arch/arm/boot/dts/stih415-pinctrl.dtsi | 10 +++++----- arch/arm/boot/dts/stih416-pinctrl.dtsi | 10 +++++----- drivers/of/irq.c | 2 +- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt index 636f0ac4e223..2a60cd3e8d5d 100644 --- a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt +++ b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt @@ -23,5 +23,5 @@ gmac0: ethernet@ff700000 { interrupt-names = "macirq"; mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */ clocks = <&emac_0_clk>; - clocks-names = "stmmaceth"; + clock-names = "stmmaceth"; }; diff --git a/Documentation/devicetree/bindings/net/stmmac.txt b/Documentation/devicetree/bindings/net/stmmac.txt index 80c1fb8bfbb8..a2acd2b26baf 100644 --- a/Documentation/devicetree/bindings/net/stmmac.txt +++ b/Documentation/devicetree/bindings/net/stmmac.txt @@ -33,7 +33,7 @@ Optional properties: - max-frame-size: See ethernet.txt file in the same directory - clocks: If present, the first clock should be the GMAC main clock, further clocks may be specified in derived bindings. -- clocks-names: One name for each entry in the clocks property, the +- clock-names: One name for each entry in the clocks property, the first one should be "stmmaceth". Examples: diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt index 4bd5be0e5e7d..26bcb18f4e60 100644 --- a/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt +++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt @@ -83,7 +83,7 @@ Example: reg = <0xfe61f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfe610000 0x5000>; PIO0: gpio@fe610000 { @@ -165,7 +165,7 @@ sdhci0:sdhci@fe810000{ interrupt-parent = <&PIO3>; #interrupt-cells = <2>; interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */ - interrupts-names = "card-detect"; + interrupt-names = "card-detect"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mmc>; }; diff --git a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt index 569b26c4a81e..60ca07996458 100644 --- a/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt +++ b/Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt @@ -47,7 +47,7 @@ mcasp0: mcasp0@1d00000 { reg = <0x100000 0x3000>; reg-names "mpu"; interrupts = <82>, <83>; - interrupts-names = "tx", "rx"; + interrupt-names = "tx", "rx"; op-mode = <0>; /* MCASP_IIS_MODE */ tdm-slots = <2>; serial-dir = < diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index 9770e35f2536..3bce3c9dbd24 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -802,7 +802,7 @@ <0x46000000 0x400000>; reg-names = "mpu", "dat"; interrupts = <80>, <81>; - interrupts-names = "tx", "rx"; + interrupt-names = "tx", "rx"; status = "disabled"; dmas = <&edma 8>, <&edma 9>; @@ -816,7 +816,7 @@ <0x46400000 0x400000>; reg-names = "mpu", "dat"; interrupts = <82>, <83>; - interrupts-names = "tx", "rx"; + interrupt-names = "tx", "rx"; status = "disabled"; dmas = <&edma 10>, <&edma 11>; diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index 36d523a26831..d1f8707ff1df 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -691,7 +691,7 @@ <0x46000000 0x400000>; reg-names = "mpu", "dat"; interrupts = <80>, <81>; - interrupts-names = "tx", "rx"; + interrupt-names = "tx", "rx"; status = "disabled"; dmas = <&edma 8>, <&edma 9>; @@ -705,7 +705,7 @@ <0x46400000 0x400000>; reg-names = "mpu", "dat"; interrupts = <82>, <83>; - interrupts-names = "tx", "rx"; + interrupt-names = "tx", "rx"; status = "disabled"; dmas = <&edma 10>, <&edma 11>; diff --git a/arch/arm/boot/dts/stih415-pinctrl.dtsi b/arch/arm/boot/dts/stih415-pinctrl.dtsi index f09fb10a3791..81df870e5ee6 100644 --- a/arch/arm/boot/dts/stih415-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih415-pinctrl.dtsi @@ -49,7 +49,7 @@ reg = <0xfe61f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfe610000 0x5000>; PIO0: gpio@fe610000 { @@ -187,7 +187,7 @@ reg = <0xfee0f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfee00000 0x8000>; PIO5: gpio@fee00000 { @@ -282,7 +282,7 @@ reg = <0xfe82f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfe820000 0x8000>; PIO13: gpio@fe820000 { @@ -423,7 +423,7 @@ reg = <0xfd6bf080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfd6b0000 0x3000>; PIO100: gpio@fd6b0000 { @@ -460,7 +460,7 @@ reg = <0xfd33f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfd330000 0x5000>; PIO103: gpio@fd330000 { diff --git a/arch/arm/boot/dts/stih416-pinctrl.dtsi b/arch/arm/boot/dts/stih416-pinctrl.dtsi index aeea304086eb..250d5ecc951e 100644 --- a/arch/arm/boot/dts/stih416-pinctrl.dtsi +++ b/arch/arm/boot/dts/stih416-pinctrl.dtsi @@ -53,7 +53,7 @@ reg = <0xfe61f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfe610000 0x6000>; PIO0: gpio@fe610000 { @@ -201,7 +201,7 @@ reg = <0xfee0f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfee00000 0x10000>; PIO5: gpio@fee00000 { @@ -333,7 +333,7 @@ reg = <0xfe82f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfe820000 0x6000>; PIO13: gpio@fe820000 { @@ -461,7 +461,7 @@ reg = <0xfd6bf080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfd6b0000 0x3000>; PIO100: gpio@fd6b0000 { @@ -498,7 +498,7 @@ reg = <0xfd33f080 0x4>; reg-names = "irqmux"; interrupts = ; - interrupts-names = "irqmux"; + interrupt-names = "irqmux"; ranges = <0 0xfd330000 0x5000>; PIO103: gpio@fd330000 { diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 9bcf2cf19357..e2e4c548a42f 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -364,7 +364,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) memset(r, 0, sizeof(*r)); /* - * Get optional "interrupts-names" property to add a name + * Get optional "interrupt-names" property to add a name * to the resource. */ of_property_read_string_index(dev, "interrupt-names", index, -- GitLab From 59f0f119e85cfb173db518328b55efbac4087c9f Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Mon, 21 Apr 2014 12:17:27 +0530 Subject: [PATCH 608/797] arm: dma-mapping: Fix mapping size value 68efd7d2fb("arm: dma-mapping: remove order parameter from arm_iommu_create_mapping()") is causing kernel panic because it wrongly sets the value of mapping->size: Unable to handle kernel NULL pointer dereference at virtual address 000000a0 pgd = e7a84000 [000000a0] *pgd=00000000 ... PC is at bitmap_clear+0x48/0xd0 LR is at __iommu_remove_mapping+0x130/0x164 Fix it by correcting mapping->size value. Signed-off-by: Ritesh Harjani Acked-by: Laurent Pinchart Signed-off-by: Marek Szyprowski --- arch/arm/mm/dma-mapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f62aa0677e5c..6b00be1f971e 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size) mapping->nr_bitmaps = 1; mapping->extensions = extensions; mapping->base = base; - mapping->size = bitmap_size << PAGE_SHIFT; mapping->bits = BITS_PER_BYTE * bitmap_size; + mapping->size = mapping->bits << PAGE_SHIFT; spin_lock_init(&mapping->lock); -- GitLab From 58968625c496c2e39545781915dbb848b38bd249 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 10 Apr 2014 16:47:19 -0700 Subject: [PATCH 609/797] pinctrl: single: Clear pin interrupts enabled by bootloader Since we set up device wake-up interrupts as pinctrl-single interrupts, we now must use the standard request_irq and related functions to manage them. If the pin interrupts are enabled for some pins at boot, the wake-up events can show up as constantly pending at least on omaps and will hang the system unless the related device driver clears the event at the device. To fix this, let's clear the interrupt flags during init, and print out a warning so the board maintainers can update their drivers to do proper request_irq for the driver specific wake-up events. Cc: Haojian Zhuang Cc: Linus Walleij Signed-off-by: Tony Lindgren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-single.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 81075f2a1d3f..2960557bfed9 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -810,6 +810,7 @@ static const struct pinconf_ops pcs_pinconf_ops = { static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, unsigned pin_pos) { + struct pcs_soc_data *pcs_soc = &pcs->socdata; struct pinctrl_pin_desc *pin; struct pcs_name *pn; int i; @@ -821,6 +822,18 @@ static int pcs_add_pin(struct pcs_device *pcs, unsigned offset, return -ENOMEM; } + if (pcs_soc->irq_enable_mask) { + unsigned val; + + val = pcs->read(pcs->base + offset); + if (val & pcs_soc->irq_enable_mask) { + dev_dbg(pcs->dev, "irq enabled at boot for pin at %lx (%x), clearing\n", + (unsigned long)pcs->res->start + offset, val); + val &= ~pcs_soc->irq_enable_mask; + pcs->write(val, pcs->base + offset); + } + } + pin = &pcs->pins.pa[i]; pn = &pcs->names[i]; sprintf(pn->name, "%lx.%d", -- GitLab From 34ce57e9df7d14b52c7613bb2c190e411ca99186 Mon Sep 17 00:00:00 2001 From: Guido Piasenza Date: Tue, 22 Apr 2014 16:28:03 +0100 Subject: [PATCH 610/797] sh-pfc: r8a7790: Fix definition of IPSR5 The extra entry in the table makes SCIFA0_B, and all peripherals after it, fail. Signed-off-by: Phil Edworthy Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c index 48093719167a..f5cd3f961808 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c @@ -4794,8 +4794,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { FN_MSIOF0_SCK_B, 0, /* IP5_23_21 [3] */ FN_WE1_N, FN_IERX, FN_CAN1_RX, FN_VI1_G4, - FN_VI1_G4_B, FN_VI2_R6, FN_SCIFA0_CTS_N_B, - FN_IERX_C, 0, + FN_VI1_G4_B, FN_VI2_R6, FN_SCIFA0_CTS_N_B, FN_IERX_C, /* IP5_20_18 [3] */ FN_WE0_N, FN_IECLK, FN_CAN_CLK, FN_VI2_VSYNC_N, FN_SCIFA0_TXD_B, FN_VI2_VSYNC_N_B, 0, 0, -- GitLab From 0c66c5628bbb5e96360032440f53a6cb6f8973d0 Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Tue, 22 Apr 2014 17:38:05 +0100 Subject: [PATCH 611/797] sh-pfc: r8a7791: Fix definition of MOD_SEL3 There is a missing 0 entry from the MOD_SEL3 table. Signed-off-by: Phil Edworthy Acked-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 5186d70c49d4..7868bf3a0f91 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c @@ -5288,7 +5288,7 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { /* SEL_SCIF3 [2] */ FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, /* SEL_IEB [2] */ - FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, + FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, 0, /* SEL_MMC [1] */ FN_SEL_MMC_0, FN_SEL_MMC_1, /* SEL_SCIF5 [1] */ -- GitLab From fb677ef70b65e22cd4401d31b700a8b4041efae1 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 21 Apr 2014 19:26:13 -0700 Subject: [PATCH 612/797] ARM: OMAP2+: Fix GPMC remap for devices using an offset At least the smc91x driver expects the device to be at 0x300 offset from bus base address. This does not work currently for GPMC when booted in device tree mode as it attempts to remap the the allocated GPMC partition to the address configured by the device tree plus the device offset. Note that this works just fine when booted with legacy mode. Let's fix the issue by just ignoring any device specific offset while remapping. And let's make sure the remap address confirms to the GPMC 16MB minimum granularity as listed in the TRM for GPMC_CONFIG7 BASEADDRESS bits. Otherwise we can get something like this: omap-gpmc 6e000000.gpmc: cannot remap GPMC CS 1 to 0x01000300 Cc: Pekon Gupta Reviewed-by: Javier Martinez Canillas Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/gpmc.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 84e57e6fbc26..9fe8c949305c 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -527,6 +527,14 @@ static int gpmc_cs_remap(int cs, u32 base) pr_err("%s: requested chip-select is disabled\n", __func__); return -ENODEV; } + + /* + * Make sure we ignore any device offsets from the GPMC partition + * allocated for the chip select and that the new base confirms + * to the GPMC 16MB minimum granularity. + */ + base &= ~(SZ_16M - 1); + gpmc_cs_get_memconf(cs, &old_base, &size); if (base == old_base) return 0; -- GitLab From cff2fce58b2b0f59089e7edcdc38803d65057b9f Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 22 Apr 2014 08:24:32 -0400 Subject: [PATCH 613/797] locks: rename FL_FILE_PVT and IS_FILE_PVT to use "*_OFDLCK" instead File-private locks have been re-christened as "open file description" locks. Finish the symbol name cleanup in the internal implementation. Signed-off-by: Jeff Layton --- fs/locks.c | 34 +++++++++++++++++----------------- include/linux/fs.h | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index e1023b504279..e663aeac579e 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -135,7 +135,7 @@ #define IS_POSIX(fl) (fl->fl_flags & FL_POSIX) #define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) #define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG)) -#define IS_FILE_PVT(fl) (fl->fl_flags & FL_FILE_PVT) +#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK) static bool lease_breaking(struct file_lock *fl) { @@ -564,7 +564,7 @@ static void __locks_insert_block(struct file_lock *blocker, BUG_ON(!list_empty(&waiter->fl_block)); waiter->fl_next = blocker; list_add_tail(&waiter->fl_block, &blocker->fl_block); - if (IS_POSIX(blocker) && !IS_FILE_PVT(blocker)) + if (IS_POSIX(blocker) && !IS_OFDLCK(blocker)) locks_insert_global_blocked(waiter); } @@ -759,12 +759,12 @@ EXPORT_SYMBOL(posix_test_lock); * of tasks (such as posix threads) sharing the same open file table. * To handle those cases, we just bail out after a few iterations. * - * For FL_FILE_PVT locks, the owner is the filp, not the files_struct. + * For FL_OFDLCK locks, the owner is the filp, not the files_struct. * Because the owner is not even nominally tied to a thread of * execution, the deadlock detection below can't reasonably work well. Just * skip it for those. * - * In principle, we could do a more limited deadlock detection on FL_FILE_PVT + * In principle, we could do a more limited deadlock detection on FL_OFDLCK * locks that just checks for the case where two tasks are attempting to * upgrade from read to write locks on the same inode. */ @@ -791,9 +791,9 @@ static int posix_locks_deadlock(struct file_lock *caller_fl, /* * This deadlock detector can't reasonably detect deadlocks with - * FL_FILE_PVT locks, since they aren't owned by a process, per-se. + * FL_OFDLCK locks, since they aren't owned by a process, per-se. */ - if (IS_FILE_PVT(caller_fl)) + if (IS_OFDLCK(caller_fl)) return 0; while ((block_fl = what_owner_is_waiting_for(block_fl))) { @@ -1890,7 +1890,7 @@ EXPORT_SYMBOL_GPL(vfs_test_lock); static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) { - flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid; + flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid; #if BITS_PER_LONG == 32 /* * Make sure we can represent the posix lock via @@ -1912,7 +1912,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) #if BITS_PER_LONG == 32 static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) { - flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid; + flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid; flock->l_start = fl->fl_start; flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : fl->fl_end - fl->fl_start + 1; @@ -1947,7 +1947,7 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l) goto out; cmd = F_GETLK; - file_lock.fl_flags |= FL_FILE_PVT; + file_lock.fl_flags |= FL_OFDLCK; file_lock.fl_owner = (fl_owner_t)filp; } @@ -2073,7 +2073,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, /* * If the cmd is requesting file-private locks, then set the - * FL_FILE_PVT flag and override the owner. + * FL_OFDLCK flag and override the owner. */ switch (cmd) { case F_OFD_SETLK: @@ -2082,7 +2082,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, goto out; cmd = F_SETLK; - file_lock->fl_flags |= FL_FILE_PVT; + file_lock->fl_flags |= FL_OFDLCK; file_lock->fl_owner = (fl_owner_t)filp; break; case F_OFD_SETLKW: @@ -2091,7 +2091,7 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, goto out; cmd = F_SETLKW; - file_lock->fl_flags |= FL_FILE_PVT; + file_lock->fl_flags |= FL_OFDLCK; file_lock->fl_owner = (fl_owner_t)filp; /* Fallthrough */ case F_SETLKW: @@ -2149,7 +2149,7 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) goto out; cmd = F_GETLK64; - file_lock.fl_flags |= FL_FILE_PVT; + file_lock.fl_flags |= FL_OFDLCK; file_lock.fl_owner = (fl_owner_t)filp; } @@ -2208,7 +2208,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, /* * If the cmd is requesting file-private locks, then set the - * FL_FILE_PVT flag and override the owner. + * FL_OFDLCK flag and override the owner. */ switch (cmd) { case F_OFD_SETLK: @@ -2217,7 +2217,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, goto out; cmd = F_SETLK64; - file_lock->fl_flags |= FL_FILE_PVT; + file_lock->fl_flags |= FL_OFDLCK; file_lock->fl_owner = (fl_owner_t)filp; break; case F_OFD_SETLKW: @@ -2226,7 +2226,7 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, goto out; cmd = F_SETLKW64; - file_lock->fl_flags |= FL_FILE_PVT; + file_lock->fl_flags |= FL_OFDLCK; file_lock->fl_owner = (fl_owner_t)filp; /* Fallthrough */ case F_SETLKW64: @@ -2412,7 +2412,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, if (IS_POSIX(fl)) { if (fl->fl_flags & FL_ACCESS) seq_printf(f, "ACCESS"); - else if (IS_FILE_PVT(fl)) + else if (IS_OFDLCK(fl)) seq_printf(f, "OFDLCK"); else seq_printf(f, "POSIX "); diff --git a/include/linux/fs.h b/include/linux/fs.h index 7a9c5bca2b76..878031227c57 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -815,7 +815,7 @@ static inline struct file *get_file(struct file *f) #define FL_SLEEP 128 /* A blocking lock */ #define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */ #define FL_UNLOCK_PENDING 512 /* Lease is being broken */ -#define FL_FILE_PVT 1024 /* lock is private to the file */ +#define FL_OFDLCK 1024 /* lock is "owned" by struct file */ /* * Special return value from posix_lock_file() and vfs_lock_file() for -- GitLab From 2704f807f9498054b8153002bafa3e818079e9a5 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 28 Mar 2014 09:20:58 -0700 Subject: [PATCH 614/797] staging: comedi: usbdux: bug fix for accessing 'ao_chanlist' in private data In usbdux_ao_cmd(), the channels for the command are transfered from the cmd->chanlist and stored in the private data 'ao_chanlist'. The channel numbers are bit-shifted when stored so that they become the "command" that is transfered to the device. The channel to command conversion results in the 'ao_chanlist' having these values for the channels: channel 0 -> ao_chanlist = 0x00 channel 1 -> ao_chanlist = 0x40 channel 2 -> ao_chanlist = 0x80 channel 3 -> ao_chanlist = 0xc0 The problem is, the usbduxsub_ao_isoc_irq() function uses the 'chan' value from 'ao_chanlist' to access the 'ao_readback' array in the private data. So instead of accessing the array as 0, 1, 2, 3, it accesses it as 0x00, 0x40, 0x80, 0xc0. Fix this by storing the raw channel number in 'ao_chanlist' and doing the bit-shift when creating the command. Fixes: a998a3db530bff80 "staging: comedi: usbdux: cleanup the private data 'outBuffer'" Cc: stable # 3.12 Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Acked-by: Bernd Porr Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 71db683098d6..b59af0303581 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -493,7 +493,7 @@ static void usbduxsub_ao_isoc_irq(struct urb *urb) /* pointer to the DA */ *datap++ = val & 0xff; *datap++ = (val >> 8) & 0xff; - *datap++ = chan; + *datap++ = chan << 6; devpriv->ao_readback[chan] = val; s->async->events |= COMEDI_CB_BLOCK; @@ -1040,11 +1040,8 @@ static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) /* set current channel of the running acquisition to zero */ s->async->cur_chan = 0; - for (i = 0; i < cmd->chanlist_len; ++i) { - unsigned int chan = CR_CHAN(cmd->chanlist[i]); - - devpriv->ao_chanlist[i] = chan << 6; - } + for (i = 0; i < cmd->chanlist_len; ++i) + devpriv->ao_chanlist[i] = CR_CHAN(cmd->chanlist[i]); /* we count in steps of 1ms (125us) */ /* 125us mode not used yet */ -- GitLab From cb171f7abb9a1a250fb41d088b81799f75bd1357 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 23 Apr 2014 10:21:06 -0600 Subject: [PATCH 615/797] PNP: Work around BIOS defects in Intel MCH area reporting Work around BIOSes that don't report the entire Intel MCH area. MCHBAR is not an architected PCI BAR, so MCH space is usually reported as a PNP0C02 resource. The MCH space was once 16KB, but is 32KB in newer parts. Some BIOSes still report a PNP0C02 resource that is only 16KB, which means the rest of the MCH space is consumed but unreported. This can cause resource map sanity check warnings or (theoretically) a device conflict if we assigned the unreported space to another device. The Intel perf event uncore driver tripped over this when it claimed the MCH region: resource map sanity check conflict: 0xfed10000 0xfed15fff 0xfed10000 0xfed13fff pnp 00:01 Info: mapping multiple BARs. Your kernel is fine. To prevent this, if we find a PNP0C02 resource that covers part of the MCH space, extend it to cover the entire space. References: http://lkml.kernel.org/r/20140224162400.GE16457@pd.tnic Reported-and-tested-by: Borislav Petkov Signed-off-by: Bjorn Helgaas Acked-by: Borislav Petkov Acked-by: Stephane Eranian Signed-off-by: Rafael J. Wysocki --- drivers/pnp/quirks.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 258fef272ea7..3736bc408adb 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -334,6 +335,81 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev) } #endif +#ifdef CONFIG_X86 +/* Device IDs of parts that have 32KB MCH space */ +static const unsigned int mch_quirk_devices[] = { + 0x0154, /* Ivy Bridge */ + 0x0c00, /* Haswell */ +}; + +static struct pci_dev *get_intel_host(void) +{ + int i; + struct pci_dev *host; + + for (i = 0; i < ARRAY_SIZE(mch_quirk_devices); i++) { + host = pci_get_device(PCI_VENDOR_ID_INTEL, mch_quirk_devices[i], + NULL); + if (host) + return host; + } + return NULL; +} + +static void quirk_intel_mch(struct pnp_dev *dev) +{ + struct pci_dev *host; + u32 addr_lo, addr_hi; + struct pci_bus_region region; + struct resource mch; + struct pnp_resource *pnp_res; + struct resource *res; + + host = get_intel_host(); + if (!host) + return; + + /* + * MCHBAR is not an architected PCI BAR, so MCH space is usually + * reported as a PNP0C02 resource. The MCH space was originally + * 16KB, but is 32KB in newer parts. Some BIOSes still report a + * PNP0C02 resource that is only 16KB, which means the rest of the + * MCH space is consumed but unreported. + */ + + /* + * Read MCHBAR for Host Member Mapped Register Range Base + * https://www-ssl.intel.com/content/www/us/en/processors/core/4th-gen-core-family-desktop-vol-2-datasheet + * Sec 3.1.12. + */ + pci_read_config_dword(host, 0x48, &addr_lo); + region.start = addr_lo & ~0x7fff; + pci_read_config_dword(host, 0x4c, &addr_hi); + region.start |= (u64) addr_hi << 32; + region.end = region.start + 32*1024 - 1; + + memset(&mch, 0, sizeof(mch)); + mch.flags = IORESOURCE_MEM; + pcibios_bus_to_resource(host->bus, &mch, ®ion); + + list_for_each_entry(pnp_res, &dev->resources, list) { + res = &pnp_res->res; + if (res->end < mch.start || res->start > mch.end) + continue; /* no overlap */ + if (res->start == mch.start && res->end == mch.end) + continue; /* exact match */ + + dev_info(&dev->dev, FW_BUG "PNP resource %pR covers only part of %s Intel MCH; extending to %pR\n", + res, pci_name(host), &mch); + res->start = mch.start; + res->end = mch.end; + break; + } + + pci_dev_put(host); +} +#endif + /* * PnP Quirks * Cards or devices that need some tweaking due to incomplete resource info @@ -363,6 +439,9 @@ static struct pnp_fixup pnp_fixups[] = { {"PNP0c02", quirk_system_pci_resources}, #ifdef CONFIG_AMD_NB {"PNP0c01", quirk_amd_mmconfig_area}, +#endif +#ifdef CONFIG_X86 + {"PNP0c02", quirk_intel_mch}, #endif {""} }; -- GitLab From 9f7ff8931e3c5ddc8535476971ec9501e9555c05 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Wed, 23 Apr 2014 19:04:19 +0200 Subject: [PATCH 616/797] perf/x86: Fix RAPL rdmsrl_safe() usage This patch fixes a bug introduced by: 24223657806a ("perf/x86/intel: Use rdmsrl_safe() when initializing RAPL PMU") The rdmsrl_safe() function returns 0 on success. The current code was failing to detect the RAPL PMU on real hardware (missing /sys/devices/power) because the return value of rdmsrl_safe() was misinterpreted. Signed-off-by: Stephane Eranian Acked-by: Borislav Petkov Acked-by: Venkatesh Srinivas Cc: peterz@infradead.org Cc: zheng.z.yan@intel.com Link: http://lkml.kernel.org/r/20140423170418.GA12767@quad Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_rapl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 7c87424d4140..619f7699487a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c @@ -543,7 +543,8 @@ static int rapl_cpu_prepare(int cpu) if (phys_id < 0) return -1; - if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) + /* protect rdmsrl() to handle virtualization */ + if (rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits)) return -1; pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu)); -- GitLab From cbd75e97a525e3819c02dc18bc2d67aa544c9e45 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 15 Apr 2014 18:25:48 +0200 Subject: [PATCH 617/797] drm/vmwgfx: Make sure user-space can't DMA across buffer object boundaries v2 We already check that the buffer object we're accessing is registered with the file. Now also make sure that we can't DMA across buffer object boundaries. v2: Code commenting update. Cc: stable@vger.kernel.org Signed-off-by: Thomas Hellstrom Reviewed-by: Jakob Bornecrantz --- drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 931490b9cfed..87df0b3674fd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -1214,14 +1214,36 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv, SVGA3dCmdSurfaceDMA dma; } *cmd; int ret; + SVGA3dCmdSurfaceDMASuffix *suffix; + uint32_t bo_size; cmd = container_of(header, struct vmw_dma_cmd, header); + suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->dma + + header->size - sizeof(*suffix)); + + /* Make sure device and verifier stays in sync. */ + if (unlikely(suffix->suffixSize != sizeof(*suffix))) { + DRM_ERROR("Invalid DMA suffix size.\n"); + return -EINVAL; + } + ret = vmw_translate_guest_ptr(dev_priv, sw_context, &cmd->dma.guest.ptr, &vmw_bo); if (unlikely(ret != 0)) return ret; + /* Make sure DMA doesn't cross BO boundaries. */ + bo_size = vmw_bo->base.num_pages * PAGE_SIZE; + if (unlikely(cmd->dma.guest.ptr.offset > bo_size)) { + DRM_ERROR("Invalid DMA offset.\n"); + return -EINVAL; + } + + bo_size -= cmd->dma.guest.ptr.offset; + if (unlikely(suffix->maximumOffset > bo_size)) + suffix->maximumOffset = bo_size; + ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, user_surface_converter, &cmd->dma.host.sid, NULL); -- GitLab From edd586fe705e819bc711b5ed7194a0b6f9f1a7e1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 23 Apr 2014 08:54:31 +0100 Subject: [PATCH 618/797] drm/i915: Discard BIOS framebuffers too small to accommodate chosen mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the inherited BIOS framebuffer is smaller than the mode selected for fbdev, then if we continue to use it then we cause display corruption as we do not setup the panel fitter to upscale. Regression from commit d978ef14456a38034f6c0e94a794129501f89200 Author: Jesse Barnes Date: Fri Mar 7 08:57:51 2014 -0800 drm/i915: Wrap the preallocated BIOS framebuffer and preserve for KMS fbcon v12 v2: Add a debug message to track the discard of the BIOS fb. v3: Ville pointed out the difference between ref/unref Reported-by: Knut Petersen Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77767 Signed-off-by: Chris Wilson Cc: Jesse Barnes Reviewed-by: Daniel Vetter Reviewed-by: Ville Syrjälä Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_fbdev.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index b4d44e62f0c7..fce4a0d93c0b 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -132,6 +132,16 @@ static int intelfb_create(struct drm_fb_helper *helper, mutex_lock(&dev->struct_mutex); + if (intel_fb && + (sizes->fb_width > intel_fb->base.width || + sizes->fb_height > intel_fb->base.height)) { + DRM_DEBUG_KMS("BIOS fb too small (%dx%d), we require (%dx%d)," + " releasing it\n", + intel_fb->base.width, intel_fb->base.height, + sizes->fb_width, sizes->fb_height); + drm_framebuffer_unreference(&intel_fb->base); + intel_fb = ifbdev->fb = NULL; + } if (!intel_fb || WARN_ON(!intel_fb->obj)) { DRM_DEBUG_KMS("no BIOS fb, allocating a new one\n"); ret = intelfb_alloc(helper, sizes); -- GitLab From 0f9dc59db6abc475dc23afc077fabbc606b8830f Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 24 Mar 2014 18:06:00 -0700 Subject: [PATCH 619/797] drm/i915: Allow full PPGTT with param override When PPGTT was disabled by default, the patch also prevented the user from overriding this behavior via module parameter. Being able to test this on arbitrary kernels is extremely beneficial to track down the remaining bugs. The patch that prevented this was: commit 93a25a9e2d67765c3092bfaac9b855d95e39df97 Author: Daniel Vetter Date: Thu Mar 6 09:40:43 2014 +0100 drm/i915: Disable full ppgtt by default By default PPGTT is set to -1. 0 means off, 1 means aliasing only, 2 means full, all other values are reserved. Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index ab5e93c30aa2..62a5c3627b90 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -50,7 +50,7 @@ bool intel_enable_ppgtt(struct drm_device *dev, bool full) /* Full ppgtt disabled by default for now due to issues. */ if (full) - return false; /* HAS_PPGTT(dev) */ + return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2); else return HAS_ALIASING_PPGTT(dev); } -- GitLab From 6b4ed8b00e93bd31f24a25f59ed8d1b808d0cc00 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 7 Nov 2013 08:08:44 +0000 Subject: [PATCH 620/797] clk: vexpress: NULL dereference on error path If the allocation fails then we dereference the NULL in the error path. Just return directly. Fixes: ed27ff1db869 ('clk: Versatile Express clock generators ("osc") driver') Signed-off-by: Dan Carpenter Signed-off-by: Pawel Moll --- drivers/clk/versatile/clk-vexpress-osc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 2dc8b41a339d..a535c7bf8574 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -102,7 +102,7 @@ void __init vexpress_osc_of_setup(struct device_node *node) osc = kzalloc(sizeof(*osc), GFP_KERNEL); if (!osc) - goto error; + return; osc->func = vexpress_config_func_get_by_node(node); if (!osc->func) { -- GitLab From bb6dd5757c12e9f3f25da971f1ea45c777ae79ab Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 14 Apr 2014 08:42:01 +0100 Subject: [PATCH 621/797] arm/mach-vexpress: array accessed out of bounds dcscb_allcpus_mask is an array of size 2. The index variable cluster has to be checked against this limit before accessing the array. Signed-off-by: Heinrich Schuchardt Acked-by: Nicolas Pitre Signed-off-by: Pawel Moll --- arch/arm/mach-vexpress/dcscb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-vexpress/dcscb.c b/arch/arm/mach-vexpress/dcscb.c index 788495d35cf9..30b993399ed7 100644 --- a/arch/arm/mach-vexpress/dcscb.c +++ b/arch/arm/mach-vexpress/dcscb.c @@ -51,12 +51,14 @@ static int dcscb_allcpus_mask[2]; static int dcscb_power_up(unsigned int cpu, unsigned int cluster) { unsigned int rst_hold, cpumask = (1 << cpu); - unsigned int all_mask = dcscb_allcpus_mask[cluster]; + unsigned int all_mask; pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); if (cpu >= 4 || cluster >= 2) return -EINVAL; + all_mask = dcscb_allcpus_mask[cluster]; + /* * Since this is called with IRQs enabled, and no arch_spin_lock_irq * variant exists, we need to disable IRQs manually here. @@ -101,11 +103,12 @@ static void dcscb_power_down(void) cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); cpumask = (1 << cpu); - all_mask = dcscb_allcpus_mask[cluster]; pr_debug("%s: cpu %u cluster %u\n", __func__, cpu, cluster); BUG_ON(cpu >= 4 || cluster >= 2); + all_mask = dcscb_allcpus_mask[cluster]; + __mcpm_cpu_going_down(cpu, cluster); arch_spin_lock(&dcscb_lock); -- GitLab From 52feaca5d685c07a4bc9812d16d84f5f7991bfe7 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Wed, 23 Apr 2014 18:27:04 +0100 Subject: [PATCH 622/797] hwmon: (vexpress) Use legal hwmon device names The driver used to directly us a DT 'compatible' property for the 'name' attribute of the hwmon devices. Unfortunately it contains '-' which is illegal in this context. It messes up libsensors and thus every application using it. Fixed by providing equivalent (and simpler) name strings. Reported-by: Guenter Roeck Signed-off-by: Pawel Moll Signed-off-by: Guenter Roeck --- drivers/hwmon/vexpress.c | 61 ++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c index d867e6bb2be1..7f9690560f40 100644 --- a/drivers/hwmon/vexpress.c +++ b/drivers/hwmon/vexpress.c @@ -27,15 +27,15 @@ struct vexpress_hwmon_data { struct device *hwmon_dev; struct vexpress_config_func *func; + const char *name; }; static ssize_t vexpress_hwmon_name_show(struct device *dev, struct device_attribute *dev_attr, char *buffer) { - const char *compatible = of_get_property(dev->of_node, "compatible", - NULL); + struct vexpress_hwmon_data *data = dev_get_drvdata(dev); - return sprintf(buffer, "%s\n", compatible); + return sprintf(buffer, "%s\n", data->name); } static ssize_t vexpress_hwmon_label_show(struct device *dev, @@ -94,6 +94,11 @@ struct attribute *vexpress_hwmon_attrs_##_name[] = { \ NULL \ } +struct vexpress_hwmon_type { + const char *name; + const struct attribute_group **attr_groups; +}; + #if !defined(CONFIG_REGULATOR_VEXPRESS) static DEVICE_ATTR(in1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show, @@ -102,6 +107,13 @@ static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input); static struct attribute_group vexpress_hwmon_group_volt = { .attrs = vexpress_hwmon_attrs_volt, }; +static struct vexpress_hwmon_type vexpress_hwmon_volt = { + .name = "vexpress_volt", + .attr_groups = (const struct attribute_group *[]) { + &vexpress_hwmon_group_volt, + NULL, + }, +}; #endif static DEVICE_ATTR(curr1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); @@ -111,6 +123,13 @@ static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input); static struct attribute_group vexpress_hwmon_group_amp = { .attrs = vexpress_hwmon_attrs_amp, }; +static struct vexpress_hwmon_type vexpress_hwmon_amp = { + .name = "vexpress_amp", + .attr_groups = (const struct attribute_group *[]) { + &vexpress_hwmon_group_amp, + NULL + }, +}; static DEVICE_ATTR(temp1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show, @@ -119,6 +138,13 @@ static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input); static struct attribute_group vexpress_hwmon_group_temp = { .attrs = vexpress_hwmon_attrs_temp, }; +static struct vexpress_hwmon_type vexpress_hwmon_temp = { + .name = "vexpress_temp", + .attr_groups = (const struct attribute_group *[]) { + &vexpress_hwmon_group_temp, + NULL + }, +}; static DEVICE_ATTR(power1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show, @@ -127,6 +153,13 @@ static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input); static struct attribute_group vexpress_hwmon_group_power = { .attrs = vexpress_hwmon_attrs_power, }; +static struct vexpress_hwmon_type vexpress_hwmon_power = { + .name = "vexpress_power", + .attr_groups = (const struct attribute_group *[]) { + &vexpress_hwmon_group_power, + NULL + }, +}; static DEVICE_ATTR(energy1_label, S_IRUGO, vexpress_hwmon_label_show, NULL); static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show, @@ -135,26 +168,33 @@ static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input); static struct attribute_group vexpress_hwmon_group_energy = { .attrs = vexpress_hwmon_attrs_energy, }; +static struct vexpress_hwmon_type vexpress_hwmon_energy = { + .name = "vexpress_energy", + .attr_groups = (const struct attribute_group *[]) { + &vexpress_hwmon_group_energy, + NULL + }, +}; static struct of_device_id vexpress_hwmon_of_match[] = { #if !defined(CONFIG_REGULATOR_VEXPRESS) { .compatible = "arm,vexpress-volt", - .data = &vexpress_hwmon_group_volt, + .data = &vexpress_hwmon_volt, }, #endif { .compatible = "arm,vexpress-amp", - .data = &vexpress_hwmon_group_amp, + .data = &vexpress_hwmon_amp, }, { .compatible = "arm,vexpress-temp", - .data = &vexpress_hwmon_group_temp, + .data = &vexpress_hwmon_temp, }, { .compatible = "arm,vexpress-power", - .data = &vexpress_hwmon_group_power, + .data = &vexpress_hwmon_power, }, { .compatible = "arm,vexpress-energy", - .data = &vexpress_hwmon_group_energy, + .data = &vexpress_hwmon_energy, }, {} }; @@ -165,6 +205,7 @@ static int vexpress_hwmon_probe(struct platform_device *pdev) int err; const struct of_device_id *match; struct vexpress_hwmon_data *data; + const struct vexpress_hwmon_type *type; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) @@ -174,12 +215,14 @@ static int vexpress_hwmon_probe(struct platform_device *pdev) match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); if (!match) return -ENODEV; + type = match->data; + data->name = type->name; data->func = vexpress_config_func_get_by_dev(&pdev->dev); if (!data->func) return -ENODEV; - err = sysfs_create_group(&pdev->dev.kobj, match->data); + err = sysfs_create_groups(&pdev->dev.kobj, type->attr_groups); if (err) goto error; -- GitLab From b2e5411ee26bff1deefd0b2c7beec9c133632e65 Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Wed, 23 Apr 2014 18:27:05 +0100 Subject: [PATCH 623/797] hwmon: (vexpress) Avoid creating non-existing attributes The 'label' attribute was always created but returned -ENOENT if there is no label and such behaviour is undefined from libsensors' point of view. Fixed by providing is_visible method in the attributes group, so the attribute is not created at all when unnecessary. Reported-by: Guenter Roeck Signed-off-by: Pawel Moll Signed-off-by: Guenter Roeck --- drivers/hwmon/vexpress.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c index 7f9690560f40..8242b75d96c8 100644 --- a/drivers/hwmon/vexpress.c +++ b/drivers/hwmon/vexpress.c @@ -43,9 +43,6 @@ static ssize_t vexpress_hwmon_label_show(struct device *dev, { const char *label = of_get_property(dev->of_node, "label", NULL); - if (!label) - return -ENOENT; - return snprintf(buffer, PAGE_SIZE, "%s\n", label); } @@ -84,6 +81,20 @@ static ssize_t vexpress_hwmon_u64_show(struct device *dev, to_sensor_dev_attr(dev_attr)->index)); } +static umode_t vexpress_hwmon_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int index) +{ + struct device *dev = kobj_to_dev(kobj); + struct device_attribute *dev_attr = container_of(attr, + struct device_attribute, attr); + + if (dev_attr->show == vexpress_hwmon_label_show && + !of_get_property(dev->of_node, "label", NULL)) + return 0; + + return attr->mode; +} + static DEVICE_ATTR(name, S_IRUGO, vexpress_hwmon_name_show, NULL); #define VEXPRESS_HWMON_ATTRS(_name, _label_attr, _input_attr) \ @@ -105,6 +116,7 @@ static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, vexpress_hwmon_u32_show, NULL, 1000); static VEXPRESS_HWMON_ATTRS(volt, in1_label, in1_input); static struct attribute_group vexpress_hwmon_group_volt = { + .is_visible = vexpress_hwmon_attr_is_visible, .attrs = vexpress_hwmon_attrs_volt, }; static struct vexpress_hwmon_type vexpress_hwmon_volt = { @@ -121,6 +133,7 @@ static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, vexpress_hwmon_u32_show, NULL, 1000); static VEXPRESS_HWMON_ATTRS(amp, curr1_label, curr1_input); static struct attribute_group vexpress_hwmon_group_amp = { + .is_visible = vexpress_hwmon_attr_is_visible, .attrs = vexpress_hwmon_attrs_amp, }; static struct vexpress_hwmon_type vexpress_hwmon_amp = { @@ -136,6 +149,7 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, vexpress_hwmon_u32_show, NULL, 1000); static VEXPRESS_HWMON_ATTRS(temp, temp1_label, temp1_input); static struct attribute_group vexpress_hwmon_group_temp = { + .is_visible = vexpress_hwmon_attr_is_visible, .attrs = vexpress_hwmon_attrs_temp, }; static struct vexpress_hwmon_type vexpress_hwmon_temp = { @@ -151,6 +165,7 @@ static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, vexpress_hwmon_u32_show, NULL, 1); static VEXPRESS_HWMON_ATTRS(power, power1_label, power1_input); static struct attribute_group vexpress_hwmon_group_power = { + .is_visible = vexpress_hwmon_attr_is_visible, .attrs = vexpress_hwmon_attrs_power, }; static struct vexpress_hwmon_type vexpress_hwmon_power = { @@ -166,6 +181,7 @@ static SENSOR_DEVICE_ATTR(energy1_input, S_IRUGO, vexpress_hwmon_u64_show, NULL, 1); static VEXPRESS_HWMON_ATTRS(energy, energy1_label, energy1_input); static struct attribute_group vexpress_hwmon_group_energy = { + .is_visible = vexpress_hwmon_attr_is_visible, .attrs = vexpress_hwmon_attrs_energy, }; static struct vexpress_hwmon_type vexpress_hwmon_energy = { -- GitLab From 2b4c36612efac173397756398000921a7771fdda Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 23 Apr 2014 15:15:32 +0200 Subject: [PATCH 624/797] drm/tegra: restrict plane loops to legacy planes In Matt Ropers primary plane series a set of prep patches like commit af2b653bfb4ef40931b4d101ca842ce0c5da57ef Author: Matt Roper Date: Tue Apr 1 15:22:32 2014 -0700 drm/i915: Restrict plane loops to only operate on overlay planes (v2) ensured that all exisiting users of the mode_config->plane_list wouldn't change behaviour. Unfortunately tegra seems to have fallen through the cracks. Fix it. This regression was introduced in commit e13161af80c185ecd8dc4641d0f5df58f9e3e0af Author: Matt Roper Date: Tue Apr 1 15:22:38 2014 -0700 drm: Add drm_crtc_init_with_planes() (v2) The result was that we've unref'ed the fb for the primary plane twice, leading to a use-after free bug. This is because the drm core will already set crtc->primary->fb to NULL and do the unref for us, and the crtc disable hook is called by the drm crtc helpers for exactly this case. Aside: Now that the fbdev helpers clean up planes there's no longer a need to do this in drivers. So this could probably be nuked entirely in linux-next. Signed-off-by: Daniel Vetter Reviewed-by: Matt Roper Tested-by: Stephen Warren Signed-off-by: Thierry Reding --- drivers/gpu/drm/tegra/dc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 36c717af6cf9..edb871d7d395 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -312,7 +312,7 @@ static void tegra_crtc_disable(struct drm_crtc *crtc) struct drm_device *drm = crtc->dev; struct drm_plane *plane; - list_for_each_entry(plane, &drm->mode_config.plane_list, head) { + drm_for_each_legacy_plane(plane, &drm->mode_config.plane_list) { if (plane->crtc == crtc) { tegra_plane_disable(plane); plane->crtc = NULL; -- GitLab From f75d72309192e52ef9a3efb390b1c4f408c142df Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Mon, 21 Apr 2014 10:38:08 -0700 Subject: [PATCH 625/797] hwmon: (ltc2945) Don't crash the kernel unnecessarily An implementation error should not crash the kernel if it is avoidable. Replace BUG() with WARN_ONCE(). Signed-off-by: Guenter Roeck --- drivers/hwmon/ltc2945.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hwmon/ltc2945.c b/drivers/hwmon/ltc2945.c index c104cc32989d..c9cddf5f056b 100644 --- a/drivers/hwmon/ltc2945.c +++ b/drivers/hwmon/ltc2945.c @@ -1,4 +1,4 @@ -/* + /* * Driver for Linear Technology LTC2945 I2C Power Monitor * * Copyright (c) 2014 Guenter Roeck @@ -314,8 +314,8 @@ static ssize_t ltc2945_reset_history(struct device *dev, reg = LTC2945_MAX_ADIN_H; break; default: - BUG(); - break; + WARN_ONCE(1, "Bad register: 0x%x\n", reg); + return -EINVAL; } /* Reset maximum */ ret = regmap_bulk_write(regmap, reg, buf_max, num_regs); -- GitLab From c02b50e90be9f41d6802049a1a08246e9eb1a22c Mon Sep 17 00:00:00 2001 From: Andrea Adami Date: Tue, 8 Apr 2014 14:53:44 +0200 Subject: [PATCH 626/797] ARM: pxa: hx4700.h: include "irqs.h" for PXA_NR_BUILTIN_GPIO hx4700 needs the same fix as in 9705e74671f0e4f994d86b00cecf441917c64a66 "ARM: pxa: fix various compilation problems" Fix build errors. Initial one is: /linux/arch/arm/mach-pxa/include/mach/hx4700.h:18:32: error: 'PXA_NR_BUILTIN_GPIO' undeclared here (not in a function) | #define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO Cc: stable@vger.kernel.org # v3.13+ Signed-off-by: Andrea Adami Signed-off-by: Linus Walleij Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/include/mach/hx4700.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/include/mach/hx4700.h b/arch/arm/mach-pxa/include/mach/hx4700.h index 8bc02913517c..0e1bb46264f9 100644 --- a/arch/arm/mach-pxa/include/mach/hx4700.h +++ b/arch/arm/mach-pxa/include/mach/hx4700.h @@ -14,6 +14,7 @@ #include #include +#include "irqs.h" /* PXA_NR_BUILTIN_GPIO */ #define HX4700_ASIC3_GPIO_BASE PXA_NR_BUILTIN_GPIO #define HX4700_EGPIO_BASE (HX4700_ASIC3_GPIO_BASE + ASIC3_NUM_GPIOS) -- GitLab From 1be5f69216a20b3ed7ef8b0392ca97385bdca959 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Wed, 9 Apr 2014 09:01:12 -0500 Subject: [PATCH 627/797] ARM: spear: add __init to spear_clocksource_init() I get a build warning because spear_clocksource_init() calls clocksource_mmio_init(), but it doesn't have an __init annotation. Fix that. Signed-off-by: Alex Elder Acked-by: Viresh Kumar Signed-off-by: Arnd Bergmann --- arch/arm/mach-spear/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c index 218ba5b67d92..c4d0931fc6ee 100644 --- a/arch/arm/mach-spear/time.c +++ b/arch/arm/mach-spear/time.c @@ -71,7 +71,7 @@ static void clockevent_set_mode(enum clock_event_mode mode, static int clockevent_next_event(unsigned long evt, struct clock_event_device *clk_event_dev); -static void spear_clocksource_init(void) +static void __init spear_clocksource_init(void) { u32 tick_rate; u16 val; -- GitLab From 6d0add405a6665e743fddf9c117fd6778f7a428e Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 16 Apr 2014 08:42:13 -0500 Subject: [PATCH 628/797] ARM: fix missing CLKSRC_OF on multi-platform In commit ddb902cc34593e (ARM: centralize common multi-platform kconfig options), CLKSRC_OF was removed from some platforms, but not added to ARCH_MULTIPLATFORM. Fix this. Reported-by: Lauri Hintsala Signed-off-by: Rob Herring Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ab438cb5af55..a48712ed0444 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -311,6 +311,7 @@ config ARCH_MULTIPLATFORM select ARM_HAS_SG_CHAIN select ARM_PATCH_PHYS_VIRT select AUTO_ZRELADDR + select CLKSRC_OF select COMMON_CLK select GENERIC_CLOCKEVENTS select MULTI_IRQ_HANDLER -- GitLab From af81c08c281bbc1dfc7b1fbf85f240fb7072724e Mon Sep 17 00:00:00 2001 From: Domenico Andreoli Date: Mon, 14 Apr 2014 11:55:01 +0200 Subject: [PATCH 629/797] ARM: Tidy up DTB Makefile entries Few things were out of order: - removed ARCH_BCM2835 duplicate - shuffled ARCH_BCM_5301X, ARCH_U8500 and ARCH_U300 around so to keep the list sorted Cc: Arnd Bergmann Cc: Olof Johansson Signed-by: Domenico Andreoli Signed-off-by: Arnd Bergmann --- arch/arm/boot/dts/Makefile | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 35c146f31e46..c2d97b998f69 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -51,10 +51,9 @@ dtb-$(CONFIG_ARCH_AT91) += sama5d36ek.dtb dtb-$(CONFIG_ARCH_ATLAS6) += atlas6-evb.dtb dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb +dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm28155-ap.dtb \ bcm21664-garnet.dtb -dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb -dtb-$(CONFIG_ARCH_BCM_5301X) += bcm4708-netgear-r6250.dtb dtb-$(CONFIG_ARCH_BERLIN) += \ berlin2-sony-nsz-gs7.dtb \ berlin2cd-google-chromecast.dtb @@ -294,13 +293,6 @@ dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb dtb-$(CONFIG_ARCH_QCOM) += qcom-msm8660-surf.dtb \ qcom-msm8960-cdp.dtb \ qcom-apq8074-dragonboard.dtb -dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ - ste-hrefprev60-stuib.dtb \ - ste-hrefprev60-tvk.dtb \ - ste-hrefv60plus-stuib.dtb \ - ste-hrefv60plus-tvk.dtb \ - ste-ccu8540.dtb \ - ste-ccu9540.dtb dtb-$(CONFIG_ARCH_S3C24XX) += s3c2416-smdk2416.dtb dtb-$(CONFIG_ARCH_S3C64XX) += s3c6410-mini6410.dtb \ s3c6410-smdk6410.dtb @@ -369,9 +361,16 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra30-cardhu-a04.dtb \ tegra114-dalmore.dtb \ tegra124-venice2.dtb +dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb +dtb-$(CONFIG_ARCH_U8500) += ste-snowball.dtb \ + ste-hrefprev60-stuib.dtb \ + ste-hrefprev60-tvk.dtb \ + ste-hrefv60plus-stuib.dtb \ + ste-hrefv60plus-tvk.dtb \ + ste-ccu8540.dtb \ + ste-ccu9540.dtb dtb-$(CONFIG_ARCH_VERSATILE) += versatile-ab.dtb \ versatile-pb.dtb -dtb-$(CONFIG_ARCH_U300) += ste-u300.dtb dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2p-ca5s.dtb \ vexpress-v2p-ca9.dtb \ vexpress-v2p-ca15-tc1.dtb \ -- GitLab From cab4d50389c6b23fc3d7184d794856186bdc6651 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 7 Apr 2014 10:52:23 -0600 Subject: [PATCH 630/797] ARM: tegra: remove TEGRA_EMC_SCALING_ENABLE Commit a7cbe92cef27 ("ARM: tegra: remove tegra EMC scaling driver") removed the only user of TEGRA_EMC_SCALING_ENABLE. Remove its Kconfig entry too. Signed-off-by: Paul Bolle Signed-off-by: Stephen Warren Signed-off-by: Arnd Bergmann --- arch/arm/mach-tegra/Kconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 92d660f9610f..55b305d51669 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -70,7 +70,4 @@ config TEGRA_AHB which controls AHB bus master arbitration and some performance parameters(priority, prefech size). -config TEGRA_EMC_SCALING_ENABLE - bool "Enable scaling the memory frequency" - endmenu -- GitLab From 862f0eea38409ff0d7f226c1245b787e3f0e2607 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 1 Apr 2014 14:13:15 -0600 Subject: [PATCH 631/797] ARM: tegra: remove UART5/UARTE from tegra124.dtsi Tegra124 only has 4 UARTs. Parts of the documentation hint at a fifth UART, but this appears to be left-over from earlier SoC documentation. Remove the non-existent DT node for UART5. Cc: Signed-off-by: Stephen Warren Signed-off-by: Arnd Bergmann --- arch/arm/boot/dts/tegra124.dtsi | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi index cf45a1a39483..6d540a025148 100644 --- a/arch/arm/boot/dts/tegra124.dtsi +++ b/arch/arm/boot/dts/tegra124.dtsi @@ -233,19 +233,6 @@ status = "disabled"; }; - serial@0,70006400 { - compatible = "nvidia,tegra124-uart", "nvidia,tegra20-uart"; - reg = <0x0 0x70006400 0x0 0x40>; - reg-shift = <2>; - interrupts = ; - clocks = <&tegra_car TEGRA124_CLK_UARTE>; - resets = <&tegra_car 66>; - reset-names = "serial"; - dmas = <&apbdma 20>, <&apbdma 20>; - dma-names = "rx", "tx"; - status = "disabled"; - }; - pwm@0,7000a000 { compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm"; reg = <0x0 0x7000a000 0x0 0x100>; -- GitLab From 9ba71705706aa83bcd7f9b74ae2d167da934c951 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 1 Apr 2014 14:13:16 -0600 Subject: [PATCH 632/797] clk: tegra: remove non-existent clocks The Tegra124 clock driver currently provides 3 clocks that don't actually exist; 2 for NAND and one for UART5/UARTE. Delete these. Cc: Signed-off-by: Stephen Warren Signed-off-by: Arnd Bergmann --- drivers/clk/tegra/clk-tegra124.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c index 166e02f16c8a..cc37c342c4cb 100644 --- a/drivers/clk/tegra/clk-tegra124.c +++ b/drivers/clk/tegra/clk-tegra124.c @@ -764,7 +764,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_sdmmc2_8] = { .dt_id = TEGRA124_CLK_SDMMC2, .present = true }, [tegra_clk_i2s1] = { .dt_id = TEGRA124_CLK_I2S1, .present = true }, [tegra_clk_i2c1] = { .dt_id = TEGRA124_CLK_I2C1, .present = true }, - [tegra_clk_ndflash] = { .dt_id = TEGRA124_CLK_NDFLASH, .present = true }, [tegra_clk_sdmmc1_8] = { .dt_id = TEGRA124_CLK_SDMMC1, .present = true }, [tegra_clk_sdmmc4_8] = { .dt_id = TEGRA124_CLK_SDMMC4, .present = true }, [tegra_clk_pwm] = { .dt_id = TEGRA124_CLK_PWM, .present = true }, @@ -809,7 +808,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_trace] = { .dt_id = TEGRA124_CLK_TRACE, .present = true }, [tegra_clk_soc_therm] = { .dt_id = TEGRA124_CLK_SOC_THERM, .present = true }, [tegra_clk_dtv] = { .dt_id = TEGRA124_CLK_DTV, .present = true }, - [tegra_clk_ndspeed] = { .dt_id = TEGRA124_CLK_NDSPEED, .present = true }, [tegra_clk_i2cslow] = { .dt_id = TEGRA124_CLK_I2CSLOW, .present = true }, [tegra_clk_dsib] = { .dt_id = TEGRA124_CLK_DSIB, .present = true }, [tegra_clk_tsec] = { .dt_id = TEGRA124_CLK_TSEC, .present = true }, @@ -952,7 +950,6 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = { [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, [tegra_clk_dsia_mux] = { .dt_id = TEGRA124_CLK_DSIA_MUX, .present = true }, [tegra_clk_dsib_mux] = { .dt_id = TEGRA124_CLK_DSIB_MUX, .present = true }, - [tegra_clk_uarte] = { .dt_id = TEGRA124_CLK_UARTE, .present = true }, }; static struct tegra_devclk devclks[] __initdata = { -- GitLab From 9ef1af9ea28c23d0eaed97f7f5142788b6cf570a Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 1 Apr 2014 14:13:17 -0600 Subject: [PATCH 633/797] dt: tegra: remove non-existent clock IDs The Tegra124 clock DT binding currently provides 3 clocks that don't actually exist; 2 for NAND and one for UART5/UARTE. Delete these. While this is technically an incompatible DT ABI change, nothing could have used these clock IDs for anything practical, since the HW doesn't exist. Cc: Signed-off-by: Stephen Warren Signed-off-by: Arnd Bergmann --- include/dt-bindings/clock/tegra124-car.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dt-bindings/clock/tegra124-car.h b/include/dt-bindings/clock/tegra124-car.h index 8c1603b10665..433528ab5161 100644 --- a/include/dt-bindings/clock/tegra124-car.h +++ b/include/dt-bindings/clock/tegra124-car.h @@ -29,7 +29,7 @@ /* 10 (register bit affects spdif_in and spdif_out) */ #define TEGRA124_CLK_I2S1 11 #define TEGRA124_CLK_I2C1 12 -#define TEGRA124_CLK_NDFLASH 13 +/* 13 */ #define TEGRA124_CLK_SDMMC1 14 #define TEGRA124_CLK_SDMMC4 15 /* 16 */ @@ -83,7 +83,7 @@ /* 64 */ #define TEGRA124_CLK_UARTD 65 -#define TEGRA124_CLK_UARTE 66 +/* 66 */ #define TEGRA124_CLK_I2C3 67 #define TEGRA124_CLK_SBC4 68 #define TEGRA124_CLK_SDMMC3 69 @@ -97,7 +97,7 @@ #define TEGRA124_CLK_TRACE 77 #define TEGRA124_CLK_SOC_THERM 78 #define TEGRA124_CLK_DTV 79 -#define TEGRA124_CLK_NDSPEED 80 +/* 80 */ #define TEGRA124_CLK_I2CSLOW 81 #define TEGRA124_CLK_DSIB 82 #define TEGRA124_CLK_TSEC 83 -- GitLab From 82c0f5897a8708dbf7abe08e49efd9a4a8d8cd3a Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 23 Apr 2014 17:57:40 -0500 Subject: [PATCH 634/797] of: selftest: add deferred probe interrupt test Signed-off-by: Rob Herring [grant.likely: fixed failure when root node specifies the interrupt parent] Signed-off-by: Grant Likely --- drivers/of/selftest.c | 32 +++++++++++++++++++ .../of/testcase-data/tests-interrupts.dtsi | 13 ++++++++ 2 files changed, 45 insertions(+) diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index ae4450070503..fe70b86bcffb 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -427,6 +428,36 @@ static void __init of_selftest_match_node(void) } } +static void __init of_selftest_platform_populate(void) +{ + int irq; + struct device_node *np; + struct platform_device *pdev; + + np = of_find_node_by_path("/testcase-data"); + of_platform_populate(np, of_default_bus_match_table, NULL, NULL); + + /* Test that a missing irq domain returns -EPROBE_DEFER */ + np = of_find_node_by_path("/testcase-data/testcase-device1"); + pdev = of_find_device_by_node(np); + if (!pdev) + selftest(0, "device 1 creation failed\n"); + irq = platform_get_irq(pdev, 0); + if (irq != -EPROBE_DEFER) + selftest(0, "device deferred probe failed - %d\n", irq); + + /* Test that a parsing failure does not return -EPROBE_DEFER */ + np = of_find_node_by_path("/testcase-data/testcase-device2"); + pdev = of_find_device_by_node(np); + if (!pdev) + selftest(0, "device 2 creation failed\n"); + irq = platform_get_irq(pdev, 0); + if (irq >= 0 || irq == -EPROBE_DEFER) + selftest(0, "device parsing error failed - %d\n", irq); + + selftest(1, "passed"); +} + static int __init of_selftest(void) { struct device_node *np; @@ -445,6 +476,7 @@ static int __init of_selftest(void) of_selftest_parse_interrupts(); of_selftest_parse_interrupts_extended(); of_selftest_match_node(); + of_selftest_platform_populate(); pr_info("end of selftest - %i passed, %i failed\n", selftest_results.passed, selftest_results.failed); return 0; diff --git a/drivers/of/testcase-data/tests-interrupts.dtsi b/drivers/of/testcase-data/tests-interrupts.dtsi index c843720bd3e5..da4695f60351 100644 --- a/drivers/of/testcase-data/tests-interrupts.dtsi +++ b/drivers/of/testcase-data/tests-interrupts.dtsi @@ -54,5 +54,18 @@ <&test_intmap1 1 2>; }; }; + + testcase-device1 { + compatible = "testcase-device"; + interrupt-parent = <&test_intc0>; + interrupts = <1>; + }; + + testcase-device2 { + compatible = "testcase-device"; + interrupt-parent = <&test_intc2>; + interrupts = <1>; /* invalid specifier - too short */ + }; }; + }; -- GitLab From d08b80373cbb76c9b485b60d49fd3ba82abdf77c Mon Sep 17 00:00:00 2001 From: Pawel Moll Date: Thu, 24 Apr 2014 17:19:30 +0100 Subject: [PATCH 635/797] power/reset: vexpress: Fix restart/power off operation The restart/power off implementation in the vexpress driver used to obtain the config function when necessary. This was wrong in two respects: 1. It required memory allocation with disabled interrupts (it worked, but lockdep - when enabled - reported warnings). 2. Used jiffies-based timeout, while jiffies are not running at this stage of system shutdown (therefore a config transaction error - if happened - would have never be reported). Fixed by pre-allocating the config function per device and using mdelay for timeout. Signed-off-by: Pawel Moll --- drivers/power/reset/vexpress-poweroff.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index 476aa495c110..b95cf71ed695 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c @@ -11,7 +11,7 @@ * Copyright (C) 2012 ARM Limited */ -#include +#include #include #include #include @@ -23,17 +23,12 @@ static void vexpress_reset_do(struct device *dev, const char *what) { int err = -ENOENT; - struct vexpress_config_func *func = - vexpress_config_func_get_by_dev(dev); + struct vexpress_config_func *func = dev_get_drvdata(dev); if (func) { - unsigned long timeout; - err = vexpress_config_write(func, 0, 0); - - timeout = jiffies + HZ; - while (time_before(jiffies, timeout)) - cpu_relax(); + if (!err) + mdelay(1000); } dev_emerg(dev, "Unable to %s (%d)\n", what, err); @@ -96,12 +91,18 @@ static int vexpress_reset_probe(struct platform_device *pdev) enum vexpress_reset_func func; const struct of_device_id *match = of_match_device(vexpress_reset_of_match, &pdev->dev); + struct vexpress_config_func *config_func; if (match) func = (enum vexpress_reset_func)match->data; else func = pdev->id_entry->driver_data; + config_func = vexpress_config_func_get_by_dev(&pdev->dev); + if (!config_func) + return -EINVAL; + dev_set_drvdata(&pdev->dev, config_func); + switch (func) { case FUNC_SHUTDOWN: vexpress_power_off_device = &pdev->dev; -- GitLab From cf2e0a73ca9ad376825c013ebaa145608abc27d7 Mon Sep 17 00:00:00 2001 From: Punit Agrawal Date: Wed, 19 Mar 2014 12:43:25 +0000 Subject: [PATCH 636/797] ARM: vexpress/TC2: Convert OPP voltage to uV before storing The SPC stores voltage in mV while the code assumes it was returning uV. Convert the returned voltage to uV before storing. Also fix the comment depicting voltage to uV. Signed-off-by: Punit Agrawal Reviewed-by: Sudeep Holla Signed-off-by: Pawel Moll --- arch/arm/mach-vexpress/spc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-vexpress/spc.c b/arch/arm/mach-vexpress/spc.c index c26ef5b92ca7..2c2754e79cb3 100644 --- a/arch/arm/mach-vexpress/spc.c +++ b/arch/arm/mach-vexpress/spc.c @@ -392,7 +392,7 @@ static irqreturn_t ve_spc_irq_handler(int irq, void *data) * +--------------------------+ * | 31 20 | 19 0 | * +--------------------------+ - * | u_volt | freq(kHz) | + * | m_volt | freq(kHz) | * +--------------------------+ */ #define MULT_FACTOR 20 @@ -414,7 +414,7 @@ static int ve_spc_populate_opps(uint32_t cluster) ret = ve_spc_read_sys_cfg(SYSCFG_SCC, off, &data); if (!ret) { opps->freq = (data & FREQ_MASK) * MULT_FACTOR; - opps->u_volt = data >> VOLT_SHIFT; + opps->u_volt = (data >> VOLT_SHIFT) * 1000; } else { break; } -- GitLab From f66abe92ce498672ac44d550f51a526597c731c4 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 24 Apr 2014 19:27:49 +0200 Subject: [PATCH 637/797] ACPI / notify: Do not block unknown type notifications in root handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 1a699476e258 "ACPI / hotplug / PCI: Hotplug notifications from acpi_bus_notify()" changed the root notify handler, acpi_bus_notify(), to block unknown type norifications, but it overlooked the fact that they might be propagated to drivers via the ->notify() callback. Fix the problem by allowing drivers to receive unknown type notifications via ->notify() as before. Fixes: 1a699476e258 (ACPI / hotplug / PCI: Hotplug notifications from acpi_bus_notify()) Reported-and-tested-by: Mantas Mikulėnas Reported-and-tested-by: Sitsofe Wheeler Signed-off-by: Rafael J. Wysocki --- drivers/acpi/bus.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e7e5844c87d0..cf925c4f36b7 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -380,9 +380,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) break; default: - acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); - ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY; - goto err; + acpi_handle_debug(handle, "Unknown event type 0x%x\n", type); + break; } adev = acpi_bus_get_acpi_device(handle); -- GitLab From cd84f009e98b3aa6109503f80f66ccf3e19e8fa9 Mon Sep 17 00:00:00 2001 From: Peter Chen Date: Thu, 24 Apr 2014 08:15:27 +0800 Subject: [PATCH 638/797] usb: chipidea: coordinate usb phy initialization for different phy type For internal PHY (like UTMI), the phy clock may from internal pll, it is on/off on the fly, the access PORTSC.PTS will hang without phy clock. So, the usb_phy_init which will open phy clock needs to be called before hw_phymode_configure. See: http://marc.info/?l=linux-arm-kernel&m=139350618732108&w=2 For external PHY (like ulpi), it needs to configure portsc.pts before visit viewport, or the viewport can't be visited. so phy_phymode_configure needs to be called before usb_phy_init. See: cd0b42c2a6d2a74244f0053f8960f5dad5842278 It may not the best solution, but it can work for all situations. Cc: Sascha Hauer Cc: Chris Ruehl Cc: shc_work@mail.ru Cc: denis@eukrea.com Cc: festevam@gmail.com Cc: stable # 3.14 Signed-off-by: Peter Chen Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index ca6831c5b763..1cd5d0ba587c 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -276,6 +276,39 @@ static void hw_phymode_configure(struct ci_hdrc *ci) } } +/** + * ci_usb_phy_init: initialize phy according to different phy type + * @ci: the controller + * + * This function returns an error code if usb_phy_init has failed + */ +static int ci_usb_phy_init(struct ci_hdrc *ci) +{ + int ret; + + switch (ci->platdata->phy_mode) { + case USBPHY_INTERFACE_MODE_UTMI: + case USBPHY_INTERFACE_MODE_UTMIW: + case USBPHY_INTERFACE_MODE_HSIC: + ret = usb_phy_init(ci->transceiver); + if (ret) + return ret; + hw_phymode_configure(ci); + break; + case USBPHY_INTERFACE_MODE_ULPI: + case USBPHY_INTERFACE_MODE_SERIAL: + hw_phymode_configure(ci); + ret = usb_phy_init(ci->transceiver); + if (ret) + return ret; + break; + default: + ret = usb_phy_init(ci->transceiver); + } + + return ret; +} + /** * hw_device_reset: resets chip (execute without interruption) * @ci: the controller @@ -543,8 +576,6 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -ENODEV; } - hw_phymode_configure(ci); - if (ci->platdata->phy) ci->transceiver = ci->platdata->phy; else @@ -564,7 +595,7 @@ static int ci_hdrc_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - ret = usb_phy_init(ci->transceiver); + ret = ci_usb_phy_init(ci); if (ret) { dev_err(dev, "unable to init phy: %d\n", ret); return ret; -- GitLab From c996b9379180ee578b9ea208bb4f197201bbb023 Mon Sep 17 00:00:00 2001 From: Thomas Pugliese Date: Wed, 23 Apr 2014 14:42:47 -0500 Subject: [PATCH 639/797] uwb: don't call spin_unlock_irq in a USB completion handler This patch converts the use of spin_lock_irq/spin_unlock_irq to spin_lock_irqsave/spin_unlock_irqrestore in uwb_rc_set_drp_cmd_done which is called from a USB completion handler. There are also whitespace cleanups to make checkpatch.pl happy. Signed-off-by: Thomas Pugliese Signed-off-by: Greg Kroah-Hartman --- drivers/uwb/drp.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c index 1a2fd9795367..468c89fb6a16 100644 --- a/drivers/uwb/drp.c +++ b/drivers/uwb/drp.c @@ -59,6 +59,7 @@ static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg, struct uwb_rceb *reply, ssize_t reply_size) { struct uwb_rc_evt_set_drp_ie *r = (struct uwb_rc_evt_set_drp_ie *)reply; + unsigned long flags; if (r != NULL) { if (r->bResultCode != UWB_RC_RES_SUCCESS) @@ -67,14 +68,14 @@ static void uwb_rc_set_drp_cmd_done(struct uwb_rc *rc, void *arg, } else dev_err(&rc->uwb_dev.dev, "SET-DRP-IE: timeout\n"); - spin_lock_irq(&rc->rsvs_lock); + spin_lock_irqsave(&rc->rsvs_lock, flags); if (rc->set_drp_ie_pending > 1) { rc->set_drp_ie_pending = 0; - uwb_rsv_queue_update(rc); + uwb_rsv_queue_update(rc); } else { - rc->set_drp_ie_pending = 0; + rc->set_drp_ie_pending = 0; } - spin_unlock_irq(&rc->rsvs_lock); + spin_unlock_irqrestore(&rc->rsvs_lock, flags); } /** -- GitLab From 7584f2ebc18b6355f21be5fb2f75afbf3f781ce5 Mon Sep 17 00:00:00 2001 From: Thomas Pugliese Date: Wed, 23 Apr 2014 14:32:27 -0500 Subject: [PATCH 640/797] usb: wusbcore: convert nested lock to use spin_lock instead of spin_lock_irq Nesting a spin_lock_irq/unlock_irq inside a lock that has already disabled interrupts will enable interrupts before we are ready when spin_unlock_irq is called. This patch converts the inner lock to use spin_lock and spin_unlock instead. Signed-off-by: Thomas Pugliese Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/wa-xfer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index c8e2a47d62a7..3e2e4ed20157 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -2390,10 +2390,10 @@ static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer, done) { dev_info(dev, "Control EP stall. Queue delayed work.\n"); - spin_lock_irq(&wa->xfer_list_lock); + spin_lock(&wa->xfer_list_lock); /* move xfer from xfer_list to xfer_errored_list. */ list_move_tail(&xfer->list_node, &wa->xfer_errored_list); - spin_unlock_irq(&wa->xfer_list_lock); + spin_unlock(&wa->xfer_list_lock); spin_unlock_irqrestore(&xfer->lock, flags); queue_work(wusbd, &wa->xfer_error_work); } else { -- GitLab From bd130adacaf8cea179f9a700fb694f5be3b05bf0 Mon Sep 17 00:00:00 2001 From: Thomas Pugliese Date: Wed, 23 Apr 2014 14:28:10 -0500 Subject: [PATCH 641/797] usb: wusbcore: fix panic in wusbhc_chid_set If no valid CHID value has previously been set on an HWA, writing a value of all zeros will cause a kernel panic in uwb_radio_stop because wusbhc->uwb_rc has not been set. This patch skips the call to uwb_radio_stop if wusbhc->uwb_rc has not been initialized. Signed-off-by: Thomas Pugliese Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/wusbcore/mmc.c b/drivers/usb/wusbcore/mmc.c index 44741267c917..3f485df96226 100644 --- a/drivers/usb/wusbcore/mmc.c +++ b/drivers/usb/wusbcore/mmc.c @@ -301,7 +301,7 @@ int wusbhc_chid_set(struct wusbhc *wusbhc, const struct wusb_ckhdid *chid) if (chid) result = uwb_radio_start(&wusbhc->pal); - else + else if (wusbhc->uwb_rc) uwb_radio_stop(&wusbhc->pal); return result; -- GitLab From 10164c2ad6d2c16809f6c09e278f946e47801b3a Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 23 Apr 2014 11:32:19 +0200 Subject: [PATCH 642/797] USB: serial: fix sysfs-attribute removal deadlock Fix driver new_id sysfs-attribute removal deadlock by making sure to not hold any locks that the attribute operations grab when removing the attribute. Specifically, usb_serial_deregister holds the table mutex when deregistering the driver, which includes removing the new_id attribute. This can lead to a deadlock as writing to new_id increments the attribute's active count before trying to grab the same mutex in usb_serial_probe. The deadlock can easily be triggered by inserting a sleep in usb_serial_deregister and writing the id of an unbound device to new_id during module unload. As the table mutex (in this case) is used to prevent subdriver unload during probe, it should be sufficient to only hold the lock while manipulating the usb-serial driver list during deregister. A racing probe will then either fail to find a matching subdriver or fail to get the corresponding module reference. Since v3.15-rc1 this also triggers the following lockdep warning: ====================================================== [ INFO: possible circular locking dependency detected ] 3.15.0-rc2 #123 Tainted: G W ------------------------------------------------------- modprobe/190 is trying to acquire lock: (s_active#4){++++.+}, at: [] kernfs_remove_by_name_ns+0x4c/0x94 but task is already holding lock: (table_lock){+.+.+.}, at: [] usb_serial_deregister+0x3c/0x78 [usbserial] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (table_lock){+.+.+.}: [] __lock_acquire+0x1694/0x1ce4 [] lock_acquire+0xb4/0x154 [] _raw_spin_lock+0x4c/0x5c [] usb_store_new_id+0x14c/0x1ac [] new_id_store+0x68/0x70 [usbserial] [] drv_attr_store+0x30/0x3c [] sysfs_kf_write+0x5c/0x60 [] kernfs_fop_write+0xd4/0x194 [] vfs_write+0xbc/0x198 [] SyS_write+0x4c/0xa0 [] ret_fast_syscall+0x0/0x48 -> #0 (s_active#4){++++.+}: [] print_circular_bug+0x68/0x2f8 [] __lock_acquire+0x1928/0x1ce4 [] lock_acquire+0xb4/0x154 [] __kernfs_remove+0x254/0x310 [] kernfs_remove_by_name_ns+0x4c/0x94 [] remove_files.isra.1+0x48/0x84 [] sysfs_remove_group+0x58/0xac [] sysfs_remove_groups+0x34/0x44 [] driver_remove_groups+0x1c/0x20 [] bus_remove_driver+0x3c/0xe4 [] driver_unregister+0x38/0x58 [] usb_serial_bus_deregister+0x84/0x88 [usbserial] [] usb_serial_deregister+0x6c/0x78 [usbserial] [] usb_serial_deregister_drivers+0x2c/0x4c [usbserial] [] usb_serial_module_exit+0x14/0x1c [sierra] [] SyS_delete_module+0x184/0x210 [] ret_fast_syscall+0x0/0x48 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(table_lock); lock(s_active#4); lock(table_lock); lock(s_active#4); *** DEADLOCK *** 1 lock held by modprobe/190: #0: (table_lock){+.+.+.}, at: [] usb_serial_deregister+0x3c/0x78 [usbserial] stack backtrace: CPU: 0 PID: 190 Comm: modprobe Tainted: G W 3.15.0-rc2 #123 [] (unwind_backtrace) from [] (show_stack+0x20/0x24) [] (show_stack) from [] (dump_stack+0x24/0x28) [] (dump_stack) from [] (print_circular_bug+0x2ec/0x2f8) [] (print_circular_bug) from [] (__lock_acquire+0x1928/0x1ce4) [] (__lock_acquire) from [] (lock_acquire+0xb4/0x154) [] (lock_acquire) from [] (__kernfs_remove+0x254/0x310) [] (__kernfs_remove) from [] (kernfs_remove_by_name_ns+0x4c/0x94) [] (kernfs_remove_by_name_ns) from [] (remove_files.isra.1+0x48/0x84) [] (remove_files.isra.1) from [] (sysfs_remove_group+0x58/0xac) [] (sysfs_remove_group) from [] (sysfs_remove_groups+0x34/0x44) [] (sysfs_remove_groups) from [] (driver_remove_groups+0x1c/0x20) [] (driver_remove_groups) from [] (bus_remove_driver+0x3c/0xe4) [] (bus_remove_driver) from [] (driver_unregister+0x38/0x58) [] (driver_unregister) from [] (usb_serial_bus_deregister+0x84/0x88 [usbserial]) [] (usb_serial_bus_deregister [usbserial]) from [] (usb_serial_deregister+0x6c/0x78 [usbserial]) [] (usb_serial_deregister [usbserial]) from [] (usb_serial_deregister_drivers+0x2c/0x4c [usbserial]) [] (usb_serial_deregister_drivers [usbserial]) from [] (usb_serial_module_exit+0x14/0x1c [sierra]) [] (usb_serial_module_exit [sierra]) from [] (SyS_delete_module+0x184/0x210) [] (SyS_delete_module) from [] (ret_fast_syscall+0x0/0x48) Signed-off-by: Johan Hovold Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 81fc0dfcfdcf..6d40d56378d7 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1347,10 +1347,12 @@ static int usb_serial_register(struct usb_serial_driver *driver) static void usb_serial_deregister(struct usb_serial_driver *device) { pr_info("USB Serial deregistering driver %s\n", device->description); + mutex_lock(&table_lock); list_del(&device->driver_list); - usb_serial_bus_deregister(device); mutex_unlock(&table_lock); + + usb_serial_bus_deregister(device); } /** -- GitLab From d1481832f1dbb9d10fab27269631a130fa082f03 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 19 Apr 2014 08:51:41 +0530 Subject: [PATCH 643/797] phy: exynos: fix building as a module The top-level phy-samsung-usb2 driver may be configured as a loadable module, which currently causes link errors because of the dependency on the exynos{5250,4x12,4210}_usb2_phy_config symbol. Solving this could be achieved by exporting these symbols, but as the SoC-specific parts of the driver are not currently built as modules, it seems better to just link everything into one module and avoid the need for the export. Signed-off-by: Arnd Bergmann Acked-by: Kamil Debski Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 2faf78edc864..7728518572a4 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -13,8 +13,9 @@ 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_SUN4I_USB) += phy-sun4i-usb.o -obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-samsung-usb2.o -obj-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o -obj-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o -obj-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o +obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o +phy-exynos-usb2-y += phy-samsung-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o +phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o obj-$(CONFIG_PHY_XGENE) += phy-xgene.o -- GitLab From 907aa3aa8dbb5437696776d40caeea245c8ba3bd Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 19 Apr 2014 08:51:42 +0530 Subject: [PATCH 644/797] phy: restore OMAP_CONTROL_PHY dependencies When OMAP_CONTROL_USB was renamed to OMAP_CONTROL_PHY (commit 14da699b), its dependencies were lost in the process. Nothing in the commit message indicates that this removal was intentional, so I think it was by accident and the dependencies should be restored. Signed-off-by: Jean Delvare Acked-by: Roger Quadros Cc: Felipe Balbi Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 3bb05f17b9b4..4906c27fa3bd 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -33,6 +33,7 @@ config PHY_MVEBU_SATA config OMAP_CONTROL_PHY tristate "OMAP CONTROL PHY Driver" + depends on ARCH_OMAP2PLUS || COMPILE_TEST help Enable this to add support for the PHY part present in the control module. This driver has API to power on the USB2 PHY and to write to -- GitLab From 743bb387a1edbf1ebbba6cf77c1af3e488886c39 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 19 Apr 2014 08:51:43 +0530 Subject: [PATCH 645/797] phy: fix kernel oops in phy_lookup() The kernel oopses in phy_lookup() due to 'phy->init_data' being NULL if we register PHYs from a device tree probing driver and then call phy_get() on a device that has no representation in the device tree (e.g. a PCI device). Checking the pointer before dereferening it and skipping an interation if it's NULL prevents this kernel oops. Signed-off-by: Sergei Shtylyov Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- drivers/phy/phy-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 623b71c54b3e..c64a2f3b2d62 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -64,6 +64,9 @@ static struct phy *phy_lookup(struct device *device, const char *port) class_dev_iter_init(&iter, phy_class, NULL, NULL); while ((dev = class_dev_iter_next(&iter))) { phy = to_phy(dev); + + if (!phy->init_data) + continue; count = phy->init_data->num_consumers; consumers = phy->init_data->consumers; while (count--) { -- GitLab From 2b97789fa289d531e767d994a77e34ec58f328c4 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Sat, 19 Apr 2014 08:51:44 +0530 Subject: [PATCH 646/797] phy: core: make NULL a valid phy reference if !CONFIG_GENERIC_PHY This fixes a regression on Keystone 2 platforms caused by patch 57303488cd37da58263e842de134dc65f7c626d5 "usb: dwc3: adapt dwc3 core to use Generic PHY Framework" which adds optional support of generic phy in DWC3 core. On Keystone 2 platforms the USB is not working now because CONFIG_GENERIC_PHY isn't set and, as result, Generic PHY APIs stubs return -ENOSYS always. The log shows: dwc3 2690000.dwc3: failed to initialize core dwc3: probe of 2690000.dwc3 failed with error -38 Hence, fix it by making NULL a valid phy reference in Generic PHY APIs stubs in the same way as it was done by the patch 04c2facad8fee66c981a51852806d8923336f362 "drivers: phy: Make NULL a valid phy reference". Acked-by: Felipe Balbi Acked-by: Santosh Shilimkar Signed-off-by: Grygorii Strashko Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Greg Kroah-Hartman --- include/linux/phy/phy.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index e2f5ca96cddc..2760744cb2a7 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -174,21 +174,29 @@ void devm_of_phy_provider_unregister(struct device *dev, #else static inline int phy_pm_runtime_get(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } static inline int phy_pm_runtime_get_sync(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } static inline int phy_pm_runtime_put(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } static inline int phy_pm_runtime_put_sync(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } @@ -204,21 +212,29 @@ static inline void phy_pm_runtime_forbid(struct phy *phy) static inline int phy_init(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } static inline int phy_exit(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } static inline int phy_power_on(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } static inline int phy_power_off(struct phy *phy) { + if (!phy) + return 0; return -ENOSYS; } -- GitLab From 9ec36cafe43bf835f8f29273597a5b0cbc8267ef Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Wed, 23 Apr 2014 17:57:41 -0500 Subject: [PATCH 647/797] of/irq: do irq resolution in platform_get_irq Currently we get the following kind of errors if we try to use interrupt phandles to irqchips that have not yet initialized: irq: no irq domain found for /ocp/pinmux@48002030 ! ------------[ cut here ]------------ WARNING: CPU: 0 PID: 1 at drivers/of/platform.c:171 of_device_alloc+0x144/0x184() Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.12.0-00038-g42a9708 #1012 (show_stack+0x14/0x1c) (dump_stack+0x6c/0xa0) (warn_slowpath_common+0x64/0x84) (warn_slowpath_null+0x1c/0x24) (of_device_alloc+0x144/0x184) (of_platform_device_create_pdata+0x44/0x9c) (of_platform_bus_create+0xd0/0x170) (of_platform_bus_create+0x12c/0x170) (of_platform_populate+0x60/0x98) This is because we're wrongly trying to populate resources that are not yet available. It's perfectly valid to create irqchips dynamically, so let's fix up the issue by resolving the interrupt resources when platform_get_irq is called. And then we also need to accept the fact that some irqdomains do not exist that early on, and only get initialized later on. So we can make the current WARN_ON into just into a pr_debug(). We still attempt to populate irq resources when we create the devices. This allows current drivers which don't use platform_get_irq to continue to function. Once all drivers are fixed, this code can be removed. Suggested-by: Russell King Signed-off-by: Rob Herring Signed-off-by: Tony Lindgren Tested-by: Tony Lindgren Cc: stable@vger.kernel.org # v3.10+ Signed-off-by: Grant Likely --- drivers/base/platform.c | 7 ++++++- drivers/of/irq.c | 26 ++++++++++++++++++++++++++ drivers/of/platform.c | 4 +++- include/linux/of_irq.h | 5 +++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index e714709704e4..5b47210889e0 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,11 @@ int platform_get_irq(struct platform_device *dev, unsigned int num) return -ENXIO; return dev->archdata.irqs[num]; #else - struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); + struct resource *r; + if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) + return of_irq_get(dev->dev.of_node, num); + + r = platform_get_resource(dev, IORESOURCE_IRQ, num); return r ? r->start : -ENXIO; #endif diff --git a/drivers/of/irq.c b/drivers/of/irq.c index e2e4c548a42f..5aeb89411350 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -379,6 +379,32 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) } EXPORT_SYMBOL_GPL(of_irq_to_resource); +/** + * of_irq_get - Decode a node's IRQ and return it as a Linux irq number + * @dev: pointer to device tree node + * @index: zero-based index of the irq + * + * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain + * is not yet created. + * + */ +int of_irq_get(struct device_node *dev, int index) +{ + int rc; + struct of_phandle_args oirq; + struct irq_domain *domain; + + rc = of_irq_parse_one(dev, index, &oirq); + if (rc) + return rc; + + domain = irq_find_host(oirq.np); + if (!domain) + return -EPROBE_DEFER; + + return irq_create_of_mapping(&oirq); +} + /** * of_irq_count - Count the number of IRQs a node uses * @dev: pointer to device tree node diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 404d1daebefa..bd47fbc53dc9 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -168,7 +168,9 @@ struct platform_device *of_device_alloc(struct device_node *np, rc = of_address_to_resource(np, i, res); WARN_ON(rc); } - WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); + if (of_irq_to_resource_table(np, res, num_irq) != num_irq) + pr_debug("not all legacy IRQ resources mapped for %s\n", + np->name); } dev->dev.of_node = of_node_get(np); diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h index 3f23b4472c31..6404253d810d 100644 --- a/include/linux/of_irq.h +++ b/include/linux/of_irq.h @@ -44,11 +44,16 @@ extern void of_irq_init(const struct of_device_id *matches); #ifdef CONFIG_OF_IRQ extern int of_irq_count(struct device_node *dev); +extern int of_irq_get(struct device_node *dev, int index); #else static inline int of_irq_count(struct device_node *dev) { return 0; } +static inline int of_irq_get(struct device_node *dev, int index) +{ + return 0; +} #endif #if defined(CONFIG_OF) -- GitLab From 6a20dbd6caa2358716136144bf524331d70b1e03 Mon Sep 17 00:00:00 2001 From: Manfred Schlaegl Date: Tue, 8 Apr 2014 14:42:04 +0200 Subject: [PATCH 648/797] tty: Fix race condition between __tty_buffer_request_room and flush_to_ldisc The race was introduced while development of linux-3.11 by e8437d7ecbc50198705331449367d401ebb3181f and e9975fdec0138f1b2a85b9624e41660abd9865d4. Originally it was found and reproduced on linux-3.12.15 and linux-3.12.15-rt25, by sending 500 byte blocks with 115kbaud to the target uart in a loop with 100 milliseconds delay. In short: 1. The consumer flush_to_ldisc is on to remove the head tty_buffer. 2. The producer adds a number of bytes, so that a new tty_buffer must be allocated and added by __tty_buffer_request_room. 3. The consumer removes the head tty_buffer element, without handling newly committed data. Detailed example: * Initial buffer: * Head, Tail -> 0: used=250; commit=250; read=240; next=NULL * Consumer: ''flush_to_ldisc'' * consumed 10 Byte * buffer: * Head, Tail -> 0: used=250; commit=250; read=250; next=NULL {{{ count = head->commit - head->read; // count = 0 if (!count) { // enter // INTERRUPTED BY PRODUCER -> if (head->next == NULL) break; buf->head = head->next; tty_buffer_free(port, head); continue; } }}} * Producer: tty_insert_flip_... 10 bytes + tty_flip_buffer_push * buffer: * Head, Tail -> 0: used=250; commit=250; read=250; next=NULL * added 6 bytes: head-element filled to maximum. * buffer: * Head, Tail -> 0: used=256; commit=250; read=250; next=NULL * added 4 bytes: __tty_buffer_request_room is called * buffer: * Head -> 0: used=256; commit=256; read=250; next=1 * Tail -> 1: used=4; commit=0; read=250 next=NULL * push (tty_flip_buffer_push) * buffer: * Head -> 0: used=256; commit=256; read=250; next=1 * Tail -> 1: used=4; commit=4; read=250 next=NULL * Consumer {{{ count = head->commit - head->read; if (!count) { // INTERRUPTED BY PRODUCER <- if (head->next == NULL) // -> no break break; buf->head = head->next; tty_buffer_free(port, head); // ERROR: tty_buffer head freed -> 6 bytes lost continue; } }}} This patch reintroduces a spin_lock to protect this case. Perhaps later a lock-less solution could be found. Signed-off-by: Manfred Schlaegl Cc: stable # 3.11 Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 16 ++++++++++++++-- include/linux/tty.h | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 8ebd9f88a6f6..f1d30f6945af 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -255,11 +255,16 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, if (change || left < size) { /* This is the slow path - looking for new buffers to use */ if ((n = tty_buffer_alloc(port, size)) != NULL) { + unsigned long iflags; + n->flags = flags; buf->tail = n; + + spin_lock_irqsave(&buf->flush_lock, iflags); b->commit = b->used; - smp_mb(); b->next = n; + spin_unlock_irqrestore(&buf->flush_lock, iflags); + } else if (change) size = 0; else @@ -443,6 +448,7 @@ static void flush_to_ldisc(struct work_struct *work) mutex_lock(&buf->lock); while (1) { + unsigned long flags; struct tty_buffer *head = buf->head; int count; @@ -450,14 +456,19 @@ static void flush_to_ldisc(struct work_struct *work) if (atomic_read(&buf->priority)) break; + spin_lock_irqsave(&buf->flush_lock, flags); count = head->commit - head->read; if (!count) { - if (head->next == NULL) + if (head->next == NULL) { + spin_unlock_irqrestore(&buf->flush_lock, flags); break; + } buf->head = head->next; + spin_unlock_irqrestore(&buf->flush_lock, flags); tty_buffer_free(port, head); continue; } + spin_unlock_irqrestore(&buf->flush_lock, flags); count = receive_buf(tty, head, count); if (!count) @@ -512,6 +523,7 @@ void tty_buffer_init(struct tty_port *port) struct tty_bufhead *buf = &port->buf; mutex_init(&buf->lock); + spin_lock_init(&buf->flush_lock); tty_buffer_reset(&buf->sentinel, 0); buf->head = &buf->sentinel; buf->tail = &buf->sentinel; diff --git a/include/linux/tty.h b/include/linux/tty.h index 1c3316a47d7e..036cccd80d9f 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -61,6 +61,7 @@ struct tty_bufhead { struct tty_buffer *head; /* Queue head */ struct work_struct work; struct mutex lock; + spinlock_t flush_lock; atomic_t priority; struct tty_buffer sentinel; struct llist_head free; /* Free queue head */ -- GitLab From b08c9c317e3f7764a91d522cd031639ba42b98cc Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Thu, 24 Apr 2014 11:38:56 +0200 Subject: [PATCH 649/797] 8250_core: Fix unwanted TX chars write On transmit-hold-register empty, serial8250_tx_chars should be called only if we don't use DMA. DMA has its own tx cycle. Signed-off-by: Loic Poulain Reviewed-by: Heikki Krogerus Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 81f909c2101f..0e1bf8858431 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -1520,7 +1520,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir) status = serial8250_rx_chars(up, status); } serial8250_modem_status(up); - if (status & UART_LSR_THRE) + if (!up->dma && (status & UART_LSR_THRE)) serial8250_tx_chars(up); spin_unlock_irqrestore(&port->lock, flags); -- GitLab From f8fd1b0350d3a4581125f5eda6528f5a2c5f9183 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Thu, 24 Apr 2014 11:34:48 +0200 Subject: [PATCH 650/797] serial: 8250: Fix thread unsafe __dma_tx_complete function __dma_tx_complete is not protected against concurrent call of serial8250_tx_dma. it can lead to circular tail index corruption or parallel call of serial_tx_dma on the same data portion. This patch fixes this issue by holding the port lock. Signed-off-by: Loic Poulain Reviewed-by: Heikki Krogerus Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dma.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c index 7046769608d4..ab9096dc3849 100644 --- a/drivers/tty/serial/8250/8250_dma.c +++ b/drivers/tty/serial/8250/8250_dma.c @@ -20,12 +20,15 @@ static void __dma_tx_complete(void *param) struct uart_8250_port *p = param; struct uart_8250_dma *dma = p->dma; struct circ_buf *xmit = &p->port.state->xmit; - - dma->tx_running = 0; + unsigned long flags; dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); + spin_lock_irqsave(&p->port.lock, flags); + + dma->tx_running = 0; + xmit->tail += dma->tx_size; xmit->tail &= UART_XMIT_SIZE - 1; p->port.icount.tx += dma->tx_size; @@ -35,6 +38,8 @@ static void __dma_tx_complete(void *param) if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) serial8250_tx_dma(p); + + spin_unlock_irqrestore(&p->port.lock, flags); } static void __dma_rx_complete(void *param) -- GitLab From bb7f09ba961dd43a2398975cc2d4ad0eb77ec865 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Mon, 21 Apr 2014 09:40:34 -0700 Subject: [PATCH 651/797] serial: samsung: Use the passed in "port", fixing kgdb w/ no console The two functions in the samsung serial driver used for writing characters out to the port were inconsistent about whether they used the passed in "port" or the global "cons_uart". There was no reason to use the global and the use of the global in s3c24xx_serial_put_poll_char() caused a crash in the case where you used the serial port for kgdboc but not for console. Fix it so we used the passed in variable. Note that this doesn't fix all problems with the samsung serial driver. Specifically: * s3c24xx_serial_console_putchar() is still 99% identical to s3c24xx_serial_put_poll_char() (the function signature is different, but that's about it). A future patch will make them slightly less identical and judging by other serial drivers we may need yet more differences eventually. * The samsung serial driver still doesn't allow you to have more than one console port since it still uses the global cons_uart in s3c24xx_serial_console_write(). Signed-off-by: Doug Anderson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 23f459600738..a8e8b796f4f7 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1446,8 +1446,8 @@ static int s3c24xx_serial_get_poll_char(struct uart_port *port) static void s3c24xx_serial_put_poll_char(struct uart_port *port, unsigned char c) { - unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); - unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); + unsigned int ufcon = rd_regl(port, S3C2410_UFCON); + unsigned int ucon = rd_regl(port, S3C2410_UCON); /* not possible to xmit on unconfigured port */ if (!s3c24xx_port_configured(ucon)) @@ -1455,7 +1455,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, while (!s3c24xx_serial_console_txrdy(port, ufcon)) cpu_relax(); - wr_regb(cons_uart, S3C2410_UTXH, c); + wr_regb(port, S3C2410_UTXH, c); } #endif /* CONFIG_CONSOLE_POLL */ @@ -1463,8 +1463,8 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port, static void s3c24xx_serial_console_putchar(struct uart_port *port, int ch) { - unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); - unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); + unsigned int ufcon = rd_regl(port, S3C2410_UFCON); + unsigned int ucon = rd_regl(port, S3C2410_UCON); /* not possible to xmit on unconfigured port */ if (!s3c24xx_port_configured(ucon)) @@ -1472,7 +1472,7 @@ s3c24xx_serial_console_putchar(struct uart_port *port, int ch) while (!s3c24xx_serial_console_txrdy(port, ufcon)) barrier(); - wr_regb(cons_uart, S3C2410_UTXH, ch); + wr_regb(port, S3C2410_UTXH, ch); } static void -- GitLab From ab88c8dc3bd667bcf21c8319165db92b930cf7e7 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Mon, 21 Apr 2014 09:40:35 -0700 Subject: [PATCH 652/797] serial: samsung: don't check config for every character The s3c24xx_serial_console_putchar() is _only_ ever used by s3c24xx_serial_console_write() and is called in a loop (indirectly through uart_console_write()). There's no reason to call s3c24xx_port_configured() for every iteration through the loop. Move it outside the loop. Signed-off-by: Doug Anderson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index a8e8b796f4f7..12442748d69f 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1464,11 +1464,6 @@ static void s3c24xx_serial_console_putchar(struct uart_port *port, int ch) { unsigned int ufcon = rd_regl(port, S3C2410_UFCON); - unsigned int ucon = rd_regl(port, S3C2410_UCON); - - /* not possible to xmit on unconfigured port */ - if (!s3c24xx_port_configured(ucon)) - return; while (!s3c24xx_serial_console_txrdy(port, ufcon)) barrier(); @@ -1479,6 +1474,12 @@ static void s3c24xx_serial_console_write(struct console *co, const char *s, unsigned int count) { + unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); + + /* not possible to xmit on unconfigured port */ + if (!s3c24xx_port_configured(ucon)) + return; + uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); } -- GitLab From f94b0572683716f727b25086f8d39671506593ab Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Mon, 21 Apr 2014 09:40:36 -0700 Subject: [PATCH 653/797] serial: samsung: Change barrier() to cpu_relax() in console output The two functions to write out to the console (one used in normal console mode and one in polling console mode) were slightly different. One used a barrier() in its loop and the other a cpu_relax(). The barrier() really doesn't do anything since we're using rd_regl() to read the port anyway. Switch it to cpu_relax() to make things consistent. No known bugs / issues are fixed by this change--it just makes things more consistent. Signed-off-by: Doug Anderson Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/samsung.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 12442748d69f..1f5505e7f90d 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1466,7 +1466,7 @@ s3c24xx_serial_console_putchar(struct uart_port *port, int ch) unsigned int ufcon = rd_regl(port, S3C2410_UFCON); while (!s3c24xx_serial_console_txrdy(port, ufcon)) - barrier(); + cpu_relax(); wr_regb(port, S3C2410_UTXH, ch); } -- GitLab From 7deb39ed8d9494ea541bcaa69b56036a94f79dc2 Mon Sep 17 00:00:00 2001 From: Thomas Pfaff Date: Wed, 23 Apr 2014 12:33:22 +0200 Subject: [PATCH 654/797] serial_core: fix uart PORT_UNKNOWN handling While porting a RS485 driver from 2.6.29 to 3.14, i noticed that the serial tty driver could break it by using uart ports that it does not own : 1. uart_change_pm ist called during uart_open and calls the uart pm function without checking for PORT_UNKNOWN. The fix is to move uart_change_pm from uart_open to uart_port_startup. 2. The return code from the uart request_port call in uart_set_info is not handled properly, leading to the situation that the serial driver also thinks it owns the uart ports. This can triggered by doing following actions : setserial /dev/ttyS0 uart none # release the uart ports modprobe lirc-serial # or any other device that uses the uart setserial /dev/ttyS0 uart 16550 # gives no error and the uart tty driver # can use the ports as well Signed-off-by: Thomas Pfaff Reviewed-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/serial_core.c | 39 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index f26834d262b3..b68550d95a40 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -136,6 +136,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, if (uport->type == PORT_UNKNOWN) return 1; + /* + * Make sure the device is in D0 state. + */ + uart_change_pm(state, UART_PM_STATE_ON); + /* * Initialise and allocate the transmit and temporary * buffer. @@ -825,25 +830,29 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, * If we fail to request resources for the * new port, try to restore the old settings. */ - if (retval && old_type != PORT_UNKNOWN) { + if (retval) { uport->iobase = old_iobase; uport->type = old_type; uport->hub6 = old_hub6; uport->iotype = old_iotype; uport->regshift = old_shift; uport->mapbase = old_mapbase; - retval = uport->ops->request_port(uport); - /* - * If we failed to restore the old settings, - * we fail like this. - */ - if (retval) - uport->type = PORT_UNKNOWN; - /* - * We failed anyway. - */ - retval = -EBUSY; + if (old_type != PORT_UNKNOWN) { + retval = uport->ops->request_port(uport); + /* + * If we failed to restore the old settings, + * we fail like this. + */ + if (retval) + uport->type = PORT_UNKNOWN; + + /* + * We failed anyway. + */ + retval = -EBUSY; + } + /* Added to return the correct error -Ram Gupta */ goto exit; } @@ -1570,12 +1579,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp) goto err_dec_count; } - /* - * Make sure the device is in D0 state. - */ - if (port->count == 1) - uart_change_pm(state, UART_PM_STATE_ON); - /* * Start up the serial port. */ -- GitLab From c5f7d0bb29df2e1848a236e58e201daf5b4e0f21 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 15 Apr 2014 10:41:00 +0800 Subject: [PATCH 655/797] btrfs: Change the hole range to a more accurate value. Commit 3ac0d7b96a268a98bd474cab8bce3a9f125aaccf fixed the btrfs expanding write problem but the hole punched is sometimes too large for some iovec, which has unmapped data ranges. This patch will change to hole range to a more accurate value using the counts checked by the write check routines. Reported-by: Al Viro Signed-off-by: Qu Wenruo Signed-off-by: Chris Mason --- fs/btrfs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 23f6a9d9f104..e7e78fa9085e 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1783,7 +1783,7 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, start_pos = round_down(pos, root->sectorsize); if (start_pos > i_size_read(inode)) { /* Expand hole size to cover write data, preventing empty gap */ - end_pos = round_up(pos + iov->iov_len, root->sectorsize); + end_pos = round_up(pos + count, root->sectorsize); err = btrfs_cont_expand(inode, i_size_read(inode), end_pos); if (err) { mutex_unlock(&inode->i_mutex); -- GitLab From 3f9e3df8da3c51649c15db249978a10f7374236a Mon Sep 17 00:00:00 2001 From: David Sterba Date: Tue, 15 Apr 2014 18:50:17 +0200 Subject: [PATCH 656/797] btrfs: replace error code from btrfs_drop_extents There's a case which clone does not handle and used to BUG_ON instead, (testcase xfstests/btrfs/035), now returns EINVAL. This error code is confusing to the ioctl caller, as it normally signifies errorneous arguments. Change it to ENOPNOTSUPP which allows a fall back to copy instead of clone. This does not affect the common reflink operation. Signed-off-by: David Sterba Signed-off-by: Chris Mason --- fs/btrfs/file.c | 6 +++--- fs/btrfs/ioctl.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e7e78fa9085e..1eee3f79d75f 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -805,7 +805,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans, if (start > key.offset && end < extent_end) { BUG_ON(del_nr > 0); if (extent_type == BTRFS_FILE_EXTENT_INLINE) { - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } @@ -851,7 +851,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans, */ if (start <= key.offset && end < extent_end) { if (extent_type == BTRFS_FILE_EXTENT_INLINE) { - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } @@ -877,7 +877,7 @@ int __btrfs_drop_extents(struct btrfs_trans_handle *trans, if (start > key.offset && end >= extent_end) { BUG_ON(del_nr > 0); if (extent_type == BTRFS_FILE_EXTENT_INLINE) { - ret = -EINVAL; + ret = -EOPNOTSUPP; break; } diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f2e8fcc279a3..7b001abc73c7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -3088,7 +3088,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, new_key.offset + datal, 1); if (ret) { - if (ret != -EINVAL) + if (ret != -EOPNOTSUPP) btrfs_abort_transaction(trans, root, ret); btrfs_end_transaction(trans, root); @@ -3163,7 +3163,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, new_key.offset + datal, 1); if (ret) { - if (ret != -EINVAL) + if (ret != -EOPNOTSUPP) btrfs_abort_transaction(trans, root, ret); btrfs_end_transaction(trans, root); -- GitLab From 9d89ce658718d9d21465666127a15ca2c82c4ea7 Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Wed, 23 Apr 2014 19:33:33 +0800 Subject: [PATCH 657/797] Btrfs: move btrfs_{set,clear}_and_info() to ctree.h Signed-off-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 14 ++++++++++++++ fs/btrfs/super.c | 14 -------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index ad1a5943a923..e7c9e1c540f4 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -2058,6 +2058,20 @@ struct btrfs_ioctl_defrag_range_args { #define btrfs_raw_test_opt(o, opt) ((o) & BTRFS_MOUNT_##opt) #define btrfs_test_opt(root, opt) ((root)->fs_info->mount_opt & \ BTRFS_MOUNT_##opt) +#define btrfs_set_and_info(root, opt, fmt, args...) \ +{ \ + if (!btrfs_test_opt(root, opt)) \ + btrfs_info(root->fs_info, fmt, ##args); \ + btrfs_set_opt(root->fs_info->mount_opt, opt); \ +} + +#define btrfs_clear_and_info(root, opt, fmt, args...) \ +{ \ + if (btrfs_test_opt(root, opt)) \ + btrfs_info(root->fs_info, fmt, ##args); \ + btrfs_clear_opt(root->fs_info->mount_opt, opt); \ +} + /* * Inode flags */ diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 53bc3733d483..363404b9713f 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -385,20 +385,6 @@ static match_table_t tokens = { {Opt_err, NULL}, }; -#define btrfs_set_and_info(root, opt, fmt, args...) \ -{ \ - if (!btrfs_test_opt(root, opt)) \ - btrfs_info(root->fs_info, fmt, ##args); \ - btrfs_set_opt(root->fs_info->mount_opt, opt); \ -} - -#define btrfs_clear_and_info(root, opt, fmt, args...) \ -{ \ - if (btrfs_test_opt(root, opt)) \ - btrfs_info(root->fs_info, fmt, ##args); \ - btrfs_clear_opt(root->fs_info->mount_opt, opt); \ -} - /* * Regular mount options parser. Everything that is needed only when * reading in a new superblock is parsed here. -- GitLab From e60efa84252c059bde5f65fccc6af94478d39e3b Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Wed, 23 Apr 2014 19:33:34 +0800 Subject: [PATCH 658/797] Btrfs: avoid triggering bug_on() when we fail to start inode caching task When running stress test(including snapshots,balance,fstress), we trigger the following BUG_ON() which is because we fail to start inode caching task. [ 181.131945] kernel BUG at fs/btrfs/inode-map.c:179! [ 181.137963] invalid opcode: 0000 [#1] SMP [ 181.217096] CPU: 11 PID: 2532 Comm: btrfs Not tainted 3.14.0 #1 [ 181.240521] task: ffff88013b621b30 ti: ffff8800b6ada000 task.ti: ffff8800b6ada000 [ 181.367506] Call Trace: [ 181.371107] [] btrfs_return_ino+0x9e/0x110 [btrfs] [ 181.379191] [] btrfs_evict_inode+0x46b/0x4c0 [btrfs] [ 181.387464] [] ? autoremove_wake_function+0x40/0x40 [ 181.395642] [] evict+0x9e/0x190 [ 181.401882] [] iput+0xf3/0x180 [ 181.408025] [] btrfs_orphan_cleanup+0x1ee/0x430 [btrfs] [ 181.416614] [] btrfs_mksubvol.isra.29+0x3bd/0x450 [btrfs] [ 181.425399] [] btrfs_ioctl_snap_create_transid+0x186/0x190 [btrfs] [ 181.435059] [] btrfs_ioctl_snap_create_v2+0xeb/0x130 [btrfs] [ 181.444148] [] btrfs_ioctl+0xf76/0x2b90 [btrfs] [ 181.451971] [] ? handle_mm_fault+0x475/0xe80 [ 181.459509] [] ? __do_page_fault+0x1ec/0x520 [ 181.467046] [] ? do_mmap_pgoff+0x2f5/0x3c0 [ 181.474393] [] do_vfs_ioctl+0x2d8/0x4b0 [ 181.481450] [] SyS_ioctl+0x81/0xa0 [ 181.488021] [] system_call_fastpath+0x16/0x1b We should avoid triggering BUG_ON() here, instead, we output warning messages and clear inode_cache option. Signed-off-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/inode-map.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index cc8ca193d830..8ad529e3e67e 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -176,7 +176,11 @@ static void start_caching(struct btrfs_root *root) tsk = kthread_run(caching_kthread, root, "btrfs-ino-cache-%llu\n", root->root_key.objectid); - BUG_ON(IS_ERR(tsk)); /* -ENOMEM */ + if (IS_ERR(tsk)) { + btrfs_warn(root->fs_info, "failed to start inode caching task"); + btrfs_clear_and_info(root, CHANGE_INODE_CACHE, + "disabling inode map caching"); + } } int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) -- GitLab From 28c16cbbc32781224309e50cc99c684f2498bc59 Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Wed, 23 Apr 2014 19:33:35 +0800 Subject: [PATCH 659/797] Btrfs: fix possible memory leaks in open_ctree() Fix possible memory leaks in the following error handling paths: read_tree_block() btrfs_recover_log_trees btrfs_commit_super() btrfs_find_orphan_roots() btrfs_cleanup_fs_roots() Signed-off-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/disk-io.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6d1ac7d46f81..0e4fb4a5c7f0 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2864,7 +2864,7 @@ int open_ctree(struct super_block *sb, printk(KERN_ERR "BTRFS: failed to read log tree\n"); free_extent_buffer(log_tree_root->node); kfree(log_tree_root); - goto fail_trans_kthread; + goto fail_qgroup; } /* returns with log_tree_root freed on success */ ret = btrfs_recover_log_trees(log_tree_root); @@ -2873,24 +2873,24 @@ int open_ctree(struct super_block *sb, "Failed to recover log tree"); free_extent_buffer(log_tree_root->node); kfree(log_tree_root); - goto fail_trans_kthread; + goto fail_qgroup; } if (sb->s_flags & MS_RDONLY) { ret = btrfs_commit_super(tree_root); if (ret) - goto fail_trans_kthread; + goto fail_qgroup; } } ret = btrfs_find_orphan_roots(tree_root); if (ret) - goto fail_trans_kthread; + goto fail_qgroup; if (!(sb->s_flags & MS_RDONLY)) { ret = btrfs_cleanup_fs_roots(fs_info); if (ret) - goto fail_trans_kthread; + goto fail_qgroup; ret = btrfs_recover_relocation(tree_root); if (ret < 0) { -- GitLab From 1c70d8fb4dfa95bee491816b2a6767b5ca1080e7 Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Wed, 23 Apr 2014 19:33:36 +0800 Subject: [PATCH 660/797] Btrfs: fix inode caching vs tree log Currently, with inode cache enabled, we will reuse its inode id immediately after unlinking file, we may hit something like following: |->iput inode |->return inode id into inode cache |->create dir,fsync |->power off An easy way to reproduce this problem is: mkfs.btrfs -f /dev/sdb mount /dev/sdb /mnt -o inode_cache,commit=100 dd if=/dev/zero of=/mnt/data bs=1M count=10 oflag=sync inode_id=`ls -i /mnt/data | awk '{print $1}'` rm -f /mnt/data i=1 while [ 1 ] do mkdir /mnt/dir_$i test1=`stat /mnt/dir_$i | grep Inode: | awk '{print $4}'` if [ $test1 -eq $inode_id ] then dd if=/dev/zero of=/mnt/dir_$i/data bs=1M count=1 oflag=sync echo b > /proc/sysrq-trigger fi sleep 1 i=$(($i+1)) done mount /dev/sdb /mnt umount /dev/sdb btrfs check /dev/sdb We fix this problem by adding unlinked inode's id into pinned tree, and we can not reuse them until committing transaction. Cc: stable@vger.kernel.org Signed-off-by: Miao Xie Signed-off-by: Wang Shilong Signed-off-by: Chris Mason --- fs/btrfs/inode-map.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 8ad529e3e67e..86935f5ae291 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c @@ -209,24 +209,14 @@ int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid) void btrfs_return_ino(struct btrfs_root *root, u64 objectid) { - struct btrfs_free_space_ctl *ctl = root->free_ino_ctl; struct btrfs_free_space_ctl *pinned = root->free_ino_pinned; if (!btrfs_test_opt(root, INODE_MAP_CACHE)) return; - again: if (root->cached == BTRFS_CACHE_FINISHED) { - __btrfs_add_free_space(ctl, objectid, 1); + __btrfs_add_free_space(pinned, objectid, 1); } else { - /* - * If we are in the process of caching free ino chunks, - * to avoid adding the same inode number to the free_ino - * tree twice due to cross transaction, we'll leave it - * in the pinned tree until a transaction is committed - * or the caching work is done. - */ - down_write(&root->fs_info->commit_root_sem); spin_lock(&root->cache_lock); if (root->cached == BTRFS_CACHE_FINISHED) { @@ -238,11 +228,7 @@ void btrfs_return_ino(struct btrfs_root *root, u64 objectid) start_caching(root); - if (objectid <= root->cache_progress || - objectid >= root->highest_objectid) - __btrfs_add_free_space(ctl, objectid, 1); - else - __btrfs_add_free_space(pinned, objectid, 1); + __btrfs_add_free_space(pinned, objectid, 1); up_write(&root->fs_info->commit_root_sem); } -- GitLab From 9ce49a0b4ff7f13961d8d106ffae959823d2e758 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 24 Apr 2014 15:15:28 +0100 Subject: [PATCH 661/797] Btrfs: use correct key when repeating search for extent item If skinny metadata is enabled and our first tree search fails to find a skinny extent item, we may repeat a tree search for a "fat" extent item (if the previous item in the leaf is not the "fat" extent we're looking for). However we were not setting the new key's objectid to the right value, as we previously used the same key variable to peek at the previous item in the leaf, which has a different objectid. So just set the right objectid to avoid modifying/deleting a wrong item if we repeat the tree search. Signed-off-by: Filipe David Borba Manana Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1306487c82cf..678cb352902c 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -1542,6 +1542,7 @@ int lookup_inline_extent_backref(struct btrfs_trans_handle *trans, ret = 0; } if (ret) { + key.objectid = bytenr; key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = num_bytes; btrfs_release_path(path); @@ -5719,6 +5720,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, if (ret > 0 && skinny_metadata) { skinny_metadata = false; + key.objectid = bytenr; key.type = BTRFS_EXTENT_ITEM_KEY; key.offset = num_bytes; btrfs_release_path(path); -- GitLab From f8213bdc89719bad895a02c62c4a85066ff76720 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 24 Apr 2014 15:15:29 +0100 Subject: [PATCH 662/797] Btrfs: correctly set profile flags on seqlock retry If we had to retry on the profiles seqlock (due to a concurrent write), we would set bits on the input flags that corresponded both to the current profile and to previous values of the profile. Signed-off-by: Filipe David Borba Manana Signed-off-by: Chris Mason --- fs/btrfs/extent-tree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 678cb352902c..5590af92094b 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -3543,11 +3543,13 @@ static u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) return extended_to_chunk(flags | tmp); } -static u64 get_alloc_profile(struct btrfs_root *root, u64 flags) +static u64 get_alloc_profile(struct btrfs_root *root, u64 orig_flags) { unsigned seq; + u64 flags; do { + flags = orig_flags; seq = read_seqbegin(&root->fs_info->profiles_lock); if (flags & BTRFS_BLOCK_GROUP_DATA) -- GitLab From c2f07fe64dc0da6d4ccc02d858695356bd685aeb Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Thu, 24 Apr 2014 22:54:58 +0100 Subject: [PATCH 663/797] ARM: 8038/1: iwmmxt: explicitly check for supported architectures iwmmxt.S requires special treatment of coprocessor access registers for PJ4 and XScale-based CPUs. It only checks for CPU_PJ4 and drops down to XScale-based treatment on all other architectures. As some PJ4B also come with iWMMXt and also need PJ4 treatment, rework the corresponding preprocessor directives to explicitly check for supported architectures and fail on unsupported ones. Signed-off-by: Sebastian Hesselbarth Tested-by: Thomas Petazzoni Tested-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/kernel/iwmmxt.S | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index a08783823b32..2452dd1bef53 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -19,12 +19,16 @@ #include #include -#if defined(CONFIG_CPU_PJ4) +#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) #define PJ4(code...) code #define XSC(code...) -#else +#elif defined(CONFIG_CPU_MOHAWK) || \ + defined(CONFIG_CPU_XSC3) || \ + defined(CONFIG_CPU_XSCALE) #define PJ4(code...) #define XSC(code...) code +#else +#error "Unsupported iWMMXt architecture" #endif #define MMX_WR0 (0x00) -- GitLab From 7d0656598924b2781fb96cdff566c9f844643fcd Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Thu, 24 Apr 2014 22:56:43 +0100 Subject: [PATCH 664/797] ARM: 8039/1: pj4: enable iWMMXt only if CONFIG_IWMMXT is set This fixes PJ4 coprocessor init to only expose iWMMXt capabilities, if the corresponding kernel support for iWMMXt is enabled. Signed-off-by: Sebastian Hesselbarth Tested-by: Thomas Petazzoni Tested-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/kernel/pj4-cp0.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c index fc7208636284..12352cd30ab2 100644 --- a/arch/arm/kernel/pj4-cp0.c +++ b/arch/arm/kernel/pj4-cp0.c @@ -45,7 +45,7 @@ static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t) return NOTIFY_DONE; } -static struct notifier_block iwmmxt_notifier_block = { +static struct notifier_block __maybe_unused iwmmxt_notifier_block = { .notifier_call = iwmmxt_do, }; @@ -79,17 +79,21 @@ static void __init pj4_cp_access_write(u32 value) */ static int __init pj4_cp0_init(void) { - u32 cp_access; + u32 __maybe_unused cp_access; if (!cpu_is_pj4()) return 0; +#ifndef CONFIG_IWMMXT + pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n"); +#else cp_access = pj4_cp_access_read() & ~0xf; pj4_cp_access_write(cp_access); printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n"); elf_hwcap |= HWCAP_IWMMXT; thread_register_notifier(&iwmmxt_notifier_block); +#endif return 0; } -- GitLab From e89f443b182c7a813a60d85dbf22d090231b5e6b Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Thu, 24 Apr 2014 22:57:25 +0100 Subject: [PATCH 665/797] ARM: 8040/1: pj4: properly detect existence of iWMMXt coprocessor commit fdb487f5c961b94486a78fa61fa28b8eff1954ab ("ARM: 8015/1: Add cpu_is_pj4 to distinguish PJ4 because it has some differences with V7") introduced a fix for checking PJ4 cpuid to not use PJ4 specific coprocessor access on non-PJ4 platforms. Unfortunately, this in turn broke Marvell Armada 370/XP, both comprising Marvell PJ4B CPUs without iWMMXt extension. Instead of only checking for cpuid, which may not be sufficient to determine iWMMXt support, the presence of iWMMXt coprocessors can be checked by enabling and reading the Coprocessor ID register (wCID, register 0 of CP1). Therefore this adds an explicit check for the presence and correct wCID value, before enabling iWMMXt capabilities. As a bonus, also print the iWMMXt version of a detected coprocessor. This has been tested to properly detect iWMMXt presence/absence on: - PJ4, CPUID 0x560f5815, wCID 0x56052001: Marvell Dove, iWMMXt v2 - PJ4B, CPUID 0x561f5811: Marvell Armada 370, no iWMMXt - PJ4B, CPUID 0x562f5841, wCID 0x56052001: Marvell Armada 1500, iWMMXt v2 - PJ4B, CPUID 0x562f5842: Marvell Armada XP, no iWMMXt Signed-off-by: Sebastian Hesselbarth Tested-by: Thomas Petazzoni Tested-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/kernel/pj4-cp0.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c index 12352cd30ab2..8153e36b2491 100644 --- a/arch/arm/kernel/pj4-cp0.c +++ b/arch/arm/kernel/pj4-cp0.c @@ -72,6 +72,33 @@ static void __init pj4_cp_access_write(u32 value) : "=r" (temp) : "r" (value)); } +static int __init pj4_get_iwmmxt_version(void) +{ + u32 cp_access, wcid; + + cp_access = pj4_cp_access_read(); + pj4_cp_access_write(cp_access | 0xf); + + /* check if coprocessor 0 and 1 are available */ + if ((pj4_cp_access_read() & 0xf) != 0xf) { + pj4_cp_access_write(cp_access); + return -ENODEV; + } + + /* read iWMMXt coprocessor id register p1, c0 */ + __asm__ __volatile__ ("mrc p1, 0, %0, c0, c0, 0\n" : "=r" (wcid)); + + pj4_cp_access_write(cp_access); + + /* iWMMXt v1 */ + if ((wcid & 0xffffff00) == 0x56051000) + return 1; + /* iWMMXt v2 */ + if ((wcid & 0xffffff00) == 0x56052000) + return 2; + + return -EINVAL; +} /* * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy @@ -80,17 +107,22 @@ static void __init pj4_cp_access_write(u32 value) static int __init pj4_cp0_init(void) { u32 __maybe_unused cp_access; + int vers; if (!cpu_is_pj4()) return 0; + vers = pj4_get_iwmmxt_version(); + if (vers < 0) + return 0; + #ifndef CONFIG_IWMMXT pr_info("PJ4 iWMMXt coprocessor detected, but kernel support is missing.\n"); #else cp_access = pj4_cp_access_read() & ~0xf; pj4_cp_access_write(cp_access); - printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n"); + pr_info("PJ4 iWMMXt v%d coprocessor enabled.\n", vers); elf_hwcap |= HWCAP_IWMMXT; thread_register_notifier(&iwmmxt_notifier_block); #endif -- GitLab From cd1711709fe98d3569e7f8215ba31adcfc3686ae Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Thu, 24 Apr 2014 22:58:00 +0100 Subject: [PATCH 666/797] ARM: 8041/1: pj4: fix cpu_is_pj4 check Commit fdb487f5c961b94486a78fa61fa28b8eff1954ab ("ARM: 8015/1: Add cpu_is_pj4 to distinguish PJ4 because it has some differences with V7") introduced a cpuid check for Marvell PJ4 processors to fix a regression caused by adding PJ4 based Marvell Dove into multi_v7. Unfortunately, this check is too narrow to catch PJ4 used on Dove itself and breaks iWMMXt support. This patch therefore relaxes the cpuid mask to match both PJ4 and PJ4B. Also, rework the given comment about PJ4/PJ4B modifications to be a little bit more specific about the differences. Signed-off-by: Sebastian Hesselbarth Tested-by: Thomas Petazzoni Tested-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/include/asm/cputype.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h index c651e3b26ec7..4764344367d4 100644 --- a/arch/arm/include/asm/cputype.h +++ b/arch/arm/include/asm/cputype.h @@ -222,22 +222,22 @@ static inline int cpu_is_xsc3(void) #endif /* - * Marvell's PJ4 core is based on V7 version. It has some modification - * for coprocessor setting. For this reason, we need a way to distinguish - * it. + * Marvell's PJ4 and PJ4B cores are based on V7 version, + * but require a specical sequence for enabling coprocessors. + * For this reason, we need a way to distinguish them. */ -#ifndef CONFIG_CPU_PJ4 -#define cpu_is_pj4() 0 -#else +#if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) static inline int cpu_is_pj4(void) { unsigned int id; id = read_cpuid_id(); - if ((id & 0xfffffff0) == 0x562f5840) + if ((id & 0xff0fff00) == 0x560f5800) return 1; return 0; } +#else +#define cpu_is_pj4() 0 #endif #endif -- GitLab From d93003e8e4e1fbbc8a06ec561a63f5aa105a4c45 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Thu, 24 Apr 2014 22:58:30 +0100 Subject: [PATCH 667/797] ARM: 8042/1: iwmmxt: allow to build iWMMXt on Marvell PJ4B Some Marvell PJ4B CPUs also implement iWMMXt extensions. With a proper check for iWMMXt coprocessors now in place, enable it by default on PJ4B. While at it, also allow to manually select the corresponding Kconfig option. Signed-off-by: Sebastian Hesselbarth Tested-by: Thomas Petazzoni Tested-by: Kevin Hilman Signed-off-by: Russell King --- arch/arm/Kconfig | 6 +++--- arch/arm/kernel/Makefile | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 53e99eb543d9..767a1aa4a360 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1110,9 +1110,9 @@ config ARM_NR_BANKS default 8 config IWMMXT - bool "Enable iWMMXt support" if !CPU_PJ4 - depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 - default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 + bool "Enable iWMMXt support" + depends on CPU_XSCALE || CPU_XSC3 || CPU_MOHAWK || CPU_PJ4 || CPU_PJ4B + default y if PXA27x || PXA3xx || ARCH_MMP || CPU_PJ4 || CPU_PJ4B help Enable support for iWMMXt context switching at run time if running on a CPU that supports it. diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index a766bcbaf8ad..040619c32d68 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o +obj-$(CONFIG_CPU_PJ4B) += pj4-cp0.o obj-$(CONFIG_IWMMXT) += iwmmxt.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o -- GitLab From 6e0de817594c61f3b392a9245deeb09609ec707d Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Fri, 25 Apr 2014 10:53:44 +0200 Subject: [PATCH 668/797] s390/bpf,jit: initialize A register if 1st insn is BPF_S_LDX_B_MSH The A register needs to be initialized to zero in the prolog if the first instruction of the BPF program is BPF_S_LDX_B_MSH to prevent leaking the content of %r5 to user space. Cc: Signed-off-by: Martin Schwidefsky --- arch/s390/net/bpf_jit_comp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 9c36dc398f90..452d3ebd9d0f 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -276,7 +276,6 @@ static void bpf_jit_noleaks(struct bpf_jit *jit, struct sock_filter *filter) case BPF_S_LD_W_IND: case BPF_S_LD_H_IND: case BPF_S_LD_B_IND: - case BPF_S_LDX_B_MSH: case BPF_S_LD_IMM: case BPF_S_LD_MEM: case BPF_S_MISC_TXA: -- GitLab From 1ffa2425bf7cc70f87d5cdbe12175fd4c661dd19 Mon Sep 17 00:00:00 2001 From: Micah Richert Date: Wed, 9 Apr 2014 14:11:31 -0700 Subject: [PATCH 669/797] drm/msm: fix memory leak Signed-off-by: Micah Richert Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 3da8264d3039..bb8026daebc9 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -118,8 +118,10 @@ static void put_pages(struct drm_gem_object *obj) if (iommu_present(&platform_bus_type)) drm_gem_put_pages(obj, msm_obj->pages, true, false); - else + else { drm_mm_remove_node(msm_obj->vram_node); + drm_free_large(msm_obj->pages); + } msm_obj->pages = NULL; } -- GitLab From 96673ecbd7f638c0865045377a44f53cd8606850 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 25 Apr 2014 08:50:08 -0400 Subject: [PATCH 670/797] drm/msm: default to XR24 rather than AR24 Since X11 is going to create an XR24 fb, if the pixel formats do not match then crtc helpers will think it is a full modeset even if mode is the same, which prevents smooth/flickerless handover from fbcon/plymouth to X11. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_fbdev.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 6c6d7d4c9b4e..a752ab83b810 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c @@ -62,11 +62,8 @@ static int msm_fbdev_create(struct drm_fb_helper *helper, dma_addr_t paddr; int ret, size; - /* only doing ARGB32 since this is what is needed to alpha-blend - * with video overlays: - */ sizes->surface_bpp = 32; - sizes->surface_depth = 32; + sizes->surface_depth = 24; DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width, sizes->surface_height, sizes->surface_bpp, -- GitLab From 7d8d9f670513593377cd1442f987ce03a64ba55d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 22 Apr 2014 12:27:28 -0400 Subject: [PATCH 671/797] drm/msm/mdp4: cure for the cursor blues (v2) The hw cursor is relatively adept at triggering underflows, which manifest as a "blue flash" (since blue is configured as the underflow color). Juggle a few things around to tighten up the timing for setting cursor registers in DONE irq. And most importantly, don't ever disable the hw cursor. Instead flip it to a blank/empty cursor. This seems far more reliable, as even simply clearing the cursor-enable bit (with no other updates in previous/ following frames) can in some cases cause underflow. v1: original v2: add missing locking spotted by Micah Cc: Micah Richert Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | 9 +++------ drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c | 4 ++-- drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | 21 +++++++++++++++++++++ drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | 4 ++++ drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c | 4 ++-- 5 files changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 3e6c0f3ed592..ef9957dbac94 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c @@ -510,9 +510,8 @@ static void update_cursor(struct drm_crtc *crtc) MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN); } else { /* disable cursor: */ - mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), 0); - mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma), - MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB)); + mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), + mdp4_kms->blank_cursor_iova); } /* and drop the iova ref + obj rev when done scanning out: */ @@ -574,11 +573,9 @@ static int mdp4_crtc_cursor_set(struct drm_crtc *crtc, if (old_bo) { /* drop our previous reference: */ - msm_gem_put_iova(old_bo, mdp4_kms->id); - drm_gem_object_unreference_unlocked(old_bo); + drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, old_bo); } - crtc_flush(crtc); request_pending(crtc, PENDING_CURSOR); return 0; diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c index c740ccd1cc67..8edd531cb621 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c @@ -70,12 +70,12 @@ irqreturn_t mdp4_irq(struct msm_kms *kms) VERB("status=%08x", status); + mdp_dispatch_irqs(mdp_kms, status); + for (id = 0; id < priv->num_crtcs; id++) if (status & mdp4_crtc_vblank(priv->crtcs[id])) drm_handle_vblank(dev, id); - mdp_dispatch_irqs(mdp_kms, status); - return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index 272e707c9487..0bb4faa17523 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c @@ -144,6 +144,10 @@ static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file) static void mdp4_destroy(struct msm_kms *kms) { struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); + if (mdp4_kms->blank_cursor_iova) + msm_gem_put_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id); + if (mdp4_kms->blank_cursor_bo) + drm_gem_object_unreference(mdp4_kms->blank_cursor_bo); kfree(mdp4_kms); } @@ -372,6 +376,23 @@ struct msm_kms *mdp4_kms_init(struct drm_device *dev) goto fail; } + mutex_lock(&dev->struct_mutex); + mdp4_kms->blank_cursor_bo = msm_gem_new(dev, SZ_16K, MSM_BO_WC); + mutex_unlock(&dev->struct_mutex); + if (IS_ERR(mdp4_kms->blank_cursor_bo)) { + ret = PTR_ERR(mdp4_kms->blank_cursor_bo); + dev_err(dev->dev, "could not allocate blank-cursor bo: %d\n", ret); + mdp4_kms->blank_cursor_bo = NULL; + goto fail; + } + + ret = msm_gem_get_iova(mdp4_kms->blank_cursor_bo, mdp4_kms->id, + &mdp4_kms->blank_cursor_iova); + if (ret) { + dev_err(dev->dev, "could not pin blank-cursor bo: %d\n", ret); + goto fail; + } + return kms; fail: diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index 66a4d31aec80..715520c54cde 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h @@ -44,6 +44,10 @@ struct mdp4_kms { struct clk *lut_clk; struct mdp_irq error_handler; + + /* empty/blank cursor bo to use when cursor is "disabled" */ + struct drm_gem_object *blank_cursor_bo; + uint32_t blank_cursor_iova; }; #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c index 353d494a497f..f2b985bc2adf 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c @@ -71,11 +71,11 @@ static void mdp5_irq_mdp(struct mdp_kms *mdp_kms) VERB("status=%08x", status); + mdp_dispatch_irqs(mdp_kms, status); + for (id = 0; id < priv->num_crtcs; id++) if (status & mdp5_crtc_vblank(priv->crtcs[id])) drm_handle_vblank(dev, id); - - mdp_dispatch_irqs(mdp_kms, status); } irqreturn_t mdp5_irq(struct msm_kms *kms) -- GitLab From 3ff04a160a891e56cdcee5c198d4c764d1c8c78b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 24 Apr 2014 12:03:17 +0200 Subject: [PATCH 672/797] drm/i915: Don't WARN nor handle unexpected hpd interrupts on gmch platforms The status bits are unconditionally set, the control bits only enable the actual interrupt generation. Which means if we get some random other interrupts we'll bogusly complain about them. So restrict the WARN to platforms with a sane hotplug interrupt handling scheme. And even more important also don't attempt to process the hpd bit since we've detected a storm already. Instead just clear the bit silently. This WARN has been introduced in commit b8f102e8bf71cacf33326360fdf9dcfd1a63925b Author: Egbert Eich Date: Fri Jul 26 14:14:24 2013 +0200 drm/i915: Add messages useful for HPD storm detection debugging (v2) before that we silently handled the hpd event and so partially defeated the storm detection. v2: Pimp commit message (Jani) Cc: Jani Nikula Cc: Egbert Eich Cc: bitlord Reported-by: bitlord Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_irq.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 7753249b3a95..f98ba4e6e70b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1362,10 +1362,20 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, spin_lock(&dev_priv->irq_lock); for (i = 1; i < HPD_NUM_PINS; i++) { - WARN_ONCE(hpd[i] & hotplug_trigger && - dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED, - "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", - hotplug_trigger, i, hpd[i]); + if (hpd[i] & hotplug_trigger && + dev_priv->hpd_stats[i].hpd_mark == HPD_DISABLED) { + /* + * On GMCH platforms the interrupt mask bits only + * prevent irq generation, not the setting of the + * hotplug bits itself. So only WARN about unexpected + * interrupts on saner platforms. + */ + WARN_ONCE(INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev), + "Received HPD interrupt (0x%08x) on pin %d (0x%08x) although disabled\n", + hotplug_trigger, i, hpd[i]); + + continue; + } if (!(hpd[i] & hotplug_trigger) || dev_priv->hpd_stats[i].hpd_mark != HPD_ENABLED) -- GitLab From 78f2975eec9faff353a6194e854d3d39907bab68 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 2 Apr 2014 16:36:07 +0100 Subject: [PATCH 673/797] drm/i915: Move all ring resets before setting the HWS page In commit a51435a3137ad8ae75c288c39bd2d8b2696bae8f Author: Naresh Kumar Kachhi Date: Wed Mar 12 16:39:40 2014 +0530 drm/i915: disable rings before HW status page setup we reordered stopping the rings to do so before we set the HWS register. However, there is an extra workaround for g45 to reset the rings twice, and for consistency we should apply that workaround before setting the HWS to be sure that the rings are truly stopped. Reference: http://lkml.kernel.org/r/20140423202248.GA3621@amd.pavel.ucw.cz Tested-by: Pavel Machek Cc: Naresh Kumar Kachhi Signed-off-by: Chris Wilson Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 54 ++++++++++++++++--------- drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9f5b18d9d885..c77af69c2d8f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -827,6 +827,7 @@ enum punit_power_well { # define MI_FLUSH_ENABLE (1 << 12) # define ASYNC_FLIP_PERF_DISABLE (1 << 14) # define MODE_IDLE (1 << 9) +# define STOP_RING (1 << 8) #define GEN6_GT_MODE 0x20d0 #define GEN7_GT_MODE 0x7008 diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6bc68bdcf433..79fb4cc2137c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -437,32 +437,41 @@ static void ring_setup_phys_status_page(struct intel_ring_buffer *ring) I915_WRITE(HWS_PGA, addr); } -static int init_ring_common(struct intel_ring_buffer *ring) +static bool stop_ring(struct intel_ring_buffer *ring) { - struct drm_device *dev = ring->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj = ring->obj; - int ret = 0; - u32 head; + struct drm_i915_private *dev_priv = to_i915(ring->dev); - gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); + if (!IS_GEN2(ring->dev)) { + I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); + if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { + DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); + return false; + } + } - /* Stop the ring if it's running. */ I915_WRITE_CTL(ring, 0); I915_WRITE_HEAD(ring, 0); ring->write_tail(ring, 0); - if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) - DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); - if (I915_NEED_GFX_HWS(dev)) - intel_ring_setup_status_page(ring); - else - ring_setup_phys_status_page(ring); + if (!IS_GEN2(ring->dev)) { + (void)I915_READ_CTL(ring); + I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); + } - head = I915_READ_HEAD(ring) & HEAD_ADDR; + return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0; +} - /* G45 ring initialization fails to reset head to zero */ - if (head != 0) { +static int init_ring_common(struct intel_ring_buffer *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj = ring->obj; + int ret = 0; + + gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); + + if (!stop_ring(ring)) { + /* G45 ring initialization often fails to reset head to zero */ DRM_DEBUG_KMS("%s head not reset to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, @@ -471,9 +480,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_READ_TAIL(ring), I915_READ_START(ring)); - I915_WRITE_HEAD(ring, 0); - - if (I915_READ_HEAD(ring) & HEAD_ADDR) { + if (!stop_ring(ring)) { DRM_ERROR("failed to set %s head to zero " "ctl %08x head %08x tail %08x start %08x\n", ring->name, @@ -481,9 +488,16 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_READ_HEAD(ring), I915_READ_TAIL(ring), I915_READ_START(ring)); + ret = -EIO; + goto out; } } + if (I915_NEED_GFX_HWS(dev)) + intel_ring_setup_status_page(ring); + else + ring_setup_phys_status_page(ring); + /* Initialize the ring. This must happen _after_ we've cleared the ring * registers with the above sequence (the readback of the HEAD registers * also enforces ordering), otherwise the hw might lose the new ring diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 270a6a973438..2b91c4b4d34b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -34,6 +34,7 @@ struct intel_hw_status_page { #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) #define I915_READ_MODE(ring) I915_READ(RING_MI_MODE((ring)->mmio_base)) +#define I915_WRITE_MODE(ring, val) I915_WRITE(RING_MI_MODE((ring)->mmio_base), val) enum intel_ring_hangcheck_action { HANGCHECK_IDLE = 0, -- GitLab From 2eb835e058c737205d35d9a8791ad27b0f9e89a4 Mon Sep 17 00:00:00 2001 From: Steve Capper Date: Thu, 24 Apr 2014 15:33:21 +0100 Subject: [PATCH 674/797] arm64: mm: Add THP TLB entries to general mmu_gather When arm64 moved over to the core mmu_gather, it lost the logic to flush THP TLB entries (tlb_remove_pmd_tlb_entry was removed and the core implementation only signals that the mmu_gather needs a flush). This patch ensures that tlb_add_flush is called for THP TLB entries. Signed-off-by: Steve Capper Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/tlb.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h index 72cadf52ca80..80e2c08900d6 100644 --- a/arch/arm64/include/asm/tlb.h +++ b/arch/arm64/include/asm/tlb.h @@ -19,6 +19,7 @@ #ifndef __ASM_TLB_H #define __ASM_TLB_H +#define __tlb_remove_pmd_tlb_entry __tlb_remove_pmd_tlb_entry #include @@ -99,5 +100,10 @@ static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmdp, } #endif +static inline void __tlb_remove_pmd_tlb_entry(struct mmu_gather *tlb, pmd_t *pmdp, + unsigned long address) +{ + tlb_add_flush(tlb, address); +} #endif -- GitLab From 43683afbcb32f7b7318ac1badd6469d91fe22711 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 17 Apr 2014 12:37:14 +0100 Subject: [PATCH 675/797] arm64: debug: remove noisy, pointless warning Sending a SIGTRAP to a user task after execution of a BRK instruction at EL0 is fundamental to the way in which software breakpoints work and doesn't deserve a warning to be logged in dmesg. Whilst the warning can be justified from EL1, do_debug_exception will already do the right thing, so simply remove the code altogether. Cc: Sandeepa Prabhu Reported-by: Kyrylo Tkachov Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/debug-monitors.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c index ed3955a95747..a7fb874b595e 100644 --- a/arch/arm64/kernel/debug-monitors.c +++ b/arch/arm64/kernel/debug-monitors.c @@ -318,9 +318,6 @@ static int brk_handler(unsigned long addr, unsigned int esr, if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED) return 0; - pr_warn("unexpected brk exception at %lx, esr=0x%x\n", - (long)instruction_pointer(regs), esr); - if (!user_mode(regs)) return -EFAULT; -- GitLab From 8f0712037b4ed63dfce844939ac9866054f15ca0 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Wed, 16 Apr 2014 13:26:35 +0100 Subject: [PATCH 676/797] arm64: initialize spinlock for init_mm's context ARM64 has defined the spinlock for init_mm's context, so need initialize the spinlock structure; otherwise during the suspend flow it will dump the info for spinlock's bad magic warning as below: [ 39.084394] Disabling non-boot CPUs ... [ 39.092871] BUG: spinlock bad magic on CPU#1, swapper/1/0 [ 39.092896] lock: init_mm+0x338/0x3e0, .magic: 00000000, .owner: /-1, .owner_cpu: 0 [ 39.092907] CPU: 1 PID: 0 Comm: swapper/1 Tainted: G O 3.10.33 #125 [ 39.092912] Call trace: [ 39.092927] [] dump_backtrace+0x0/0x16c [ 39.092934] [] show_stack+0x10/0x1c [ 39.092947] [] dump_stack+0x1c/0x28 [ 39.092953] [] spin_dump+0x78/0x88 [ 39.092960] [] spin_bug+0x24/0x34 [ 39.092971] [] do_raw_spin_lock+0x98/0x17c [ 39.092979] [] _raw_spin_lock_irqsave+0x4c/0x60 [ 39.092990] [] set_mm_context+0x1c/0x6c [ 39.092996] [] __new_context+0x94/0x10c [ 39.093007] [] idle_task_exit+0x104/0x1b0 [ 39.093014] [] cpu_die+0x14/0x74 [ 39.093021] [] arch_cpu_idle_dead+0x8/0x14 [ 39.093030] [] cpu_startup_entry+0x1ec/0x258 [ 39.093036] [] secondary_start_kernel+0x114/0x124 Signed-off-by: Leo Yan Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/include/asm/mmu.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index f600d400c07d..aff0292c8f4d 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -22,6 +22,9 @@ typedef struct { void *vdso; } mm_context_t; +#define INIT_MM_CONTEXT(name) \ + .context.id_lock = __RAW_SPIN_LOCK_UNLOCKED(name.context.id_lock), + #define ASID(mm) ((mm)->context.id & 0xffff) extern void paging_init(void); -- GitLab From 1f81b6d22a5980955b01e08cf27fb745dc9b686f Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 25 Apr 2014 19:20:13 +0300 Subject: [PATCH 677/797] usb: xhci: Prefer endpoint context dequeue pointer over stopped_trb We have observed a rare cycle state desync bug after Set TR Dequeue Pointer commands on Intel LynxPoint xHCs (resulting in an endpoint that doesn't fetch new TRBs and thus an unresponsive USB device). It always triggers when a previous Set TR Dequeue Pointer command has set the pointer to the final Link TRB of a segment, and then another URB gets enqueued and cancelled again before it can be completed. Further investigation showed that the xHC had returned the Link TRB in the TRB Pointer field of the Transfer Event (CC == Stopped -- Length Invalid), but when xhci_find_new_dequeue_state() later accesses the Endpoint Context's TR Dequeue Pointer field it is set to the first TRB of the next segment. The driver expects those two values to be the same in this situation, and uses the cycle state of the latter together with the address of the former. This should be fine according to the XHCI specification, since the endpoint ring should be stopped when returning the Transfer Event and thus should not advance over the Link TRB before it gets restarted. However, real-world XHCI implementations apparently don't really care that much about these details, so the driver should follow a more defensive approach to try to work around HC spec violations. This patch removes the stopped_trb variable that had been used to store the TRB Pointer from the last Transfer Event of a stopped TRB. Instead, xhci_find_new_dequeue_state() now relies only on the Endpoint Context, requiring a small amount of additional processing to find the virtual address corresponding to the TR Dequeue Pointer. Some other parts of the function were slightly rearranged to better fit into this model. This patch should be backported to kernels as old as 2.6.31 that contain the commit ae636747146ea97efa18e04576acd3416e2514f5 "USB: xhci: URB cancellation support." Signed-off-by: Julius Werner Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 67 +++++++++++++++++------------------- drivers/usb/host/xhci.c | 1 - drivers/usb/host/xhci.h | 2 -- 3 files changed, 31 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 5f926bea5ab1..7a0e3c720c00 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -550,6 +550,7 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, struct xhci_ring *ep_ring; struct xhci_generic_trb *trb; dma_addr_t addr; + u64 hw_dequeue; ep_ring = xhci_triad_to_transfer_ring(xhci, slot_id, ep_index, stream_id); @@ -559,16 +560,6 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, stream_id); return; } - state->new_cycle_state = 0; - xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, - "Finding segment containing stopped TRB."); - state->new_deq_seg = find_trb_seg(cur_td->start_seg, - dev->eps[ep_index].stopped_trb, - &state->new_cycle_state); - if (!state->new_deq_seg) { - WARN_ON(1); - return; - } /* Dig out the cycle state saved by the xHC during the stop ep cmd */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, @@ -577,46 +568,57 @@ void xhci_find_new_dequeue_state(struct xhci_hcd *xhci, if (ep->ep_state & EP_HAS_STREAMS) { struct xhci_stream_ctx *ctx = &ep->stream_info->stream_ctx_array[stream_id]; - state->new_cycle_state = 0x1 & le64_to_cpu(ctx->stream_ring); + hw_dequeue = le64_to_cpu(ctx->stream_ring); } else { struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index); - state->new_cycle_state = 0x1 & le64_to_cpu(ep_ctx->deq); + hw_dequeue = le64_to_cpu(ep_ctx->deq); } + /* Find virtual address and segment of hardware dequeue pointer */ + state->new_deq_seg = ep_ring->deq_seg; + state->new_deq_ptr = ep_ring->dequeue; + while (xhci_trb_virt_to_dma(state->new_deq_seg, state->new_deq_ptr) + != (dma_addr_t)(hw_dequeue & ~0xf)) { + next_trb(xhci, ep_ring, &state->new_deq_seg, + &state->new_deq_ptr); + if (state->new_deq_ptr == ep_ring->dequeue) { + WARN_ON(1); + return; + } + } + /* + * Find cycle state for last_trb, starting at old cycle state of + * hw_dequeue. If there is only one segment ring, find_trb_seg() will + * return immediately and cannot toggle the cycle state if this search + * wraps around, so add one more toggle manually in that case. + */ + state->new_cycle_state = hw_dequeue & 0x1; + if (ep_ring->first_seg == ep_ring->first_seg->next && + cur_td->last_trb < state->new_deq_ptr) + state->new_cycle_state ^= 0x1; + state->new_deq_ptr = cur_td->last_trb; xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Finding segment containing last TRB in TD."); state->new_deq_seg = find_trb_seg(state->new_deq_seg, - state->new_deq_ptr, - &state->new_cycle_state); + state->new_deq_ptr, &state->new_cycle_state); if (!state->new_deq_seg) { WARN_ON(1); return; } + /* Increment to find next TRB after last_trb. Cycle if appropriate. */ trb = &state->new_deq_ptr->generic; if (TRB_TYPE_LINK_LE32(trb->field[3]) && (trb->field[3] & cpu_to_le32(LINK_TOGGLE))) state->new_cycle_state ^= 0x1; next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr); - /* - * If there is only one segment in a ring, find_trb_seg()'s while loop - * will not run, and it will return before it has a chance to see if it - * needs to toggle the cycle bit. It can't tell if the stalled transfer - * ended just before the link TRB on a one-segment ring, or if the TD - * wrapped around the top of the ring, because it doesn't have the TD in - * question. Look for the one-segment case where stalled TRB's address - * is greater than the new dequeue pointer address. - */ - if (ep_ring->first_seg == ep_ring->first_seg->next && - state->new_deq_ptr < dev->eps[ep_index].stopped_trb) - state->new_cycle_state ^= 0x1; + /* Don't update the ring cycle state for the producer (us). */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Cycle state = 0x%x", state->new_cycle_state); - /* Don't update the ring cycle state for the producer (us). */ xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "New dequeue segment = %p (virtual)", state->new_deq_seg); @@ -799,7 +801,6 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, if (list_empty(&ep->cancelled_td_list)) { xhci_stop_watchdog_timer_in_irq(xhci, ep); ep->stopped_td = NULL; - ep->stopped_trb = NULL; ring_doorbell_for_active_rings(xhci, slot_id, ep_index); return; } @@ -867,11 +868,9 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, ring_doorbell_for_active_rings(xhci, slot_id, ep_index); } - /* Clear stopped_td and stopped_trb if endpoint is not halted */ - if (!(ep->ep_state & EP_HALTED)) { + /* Clear stopped_td if endpoint is not halted */ + if (!(ep->ep_state & EP_HALTED)) ep->stopped_td = NULL; - ep->stopped_trb = NULL; - } /* * Drop the lock and complete the URBs in the cancelled TD list. @@ -1941,14 +1940,12 @@ static void xhci_cleanup_halted_endpoint(struct xhci_hcd *xhci, struct xhci_virt_ep *ep = &xhci->devs[slot_id]->eps[ep_index]; ep->ep_state |= EP_HALTED; ep->stopped_td = td; - ep->stopped_trb = event_trb; ep->stopped_stream = stream_id; xhci_queue_reset_ep(xhci, slot_id, ep_index); xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index); ep->stopped_td = NULL; - ep->stopped_trb = NULL; ep->stopped_stream = 0; xhci_ring_cmd_db(xhci); @@ -2030,7 +2027,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, * the ring dequeue pointer or take this TD off any lists yet. */ ep->stopped_td = td; - ep->stopped_trb = event_trb; return 0; } else { if (trb_comp_code == COMP_STALL) { @@ -2042,7 +2038,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td, * USB class driver clear the stall later. */ ep->stopped_td = td; - ep->stopped_trb = event_trb; ep->stopped_stream = ep_ring->stream_id; } else if (xhci_requires_manual_halt_cleanup(xhci, ep_ctx, trb_comp_code)) { diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8fe4e124ddd4..988ed5f1cb2c 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -2954,7 +2954,6 @@ void xhci_endpoint_reset(struct usb_hcd *hcd, xhci_ring_cmd_db(xhci); } virt_ep->stopped_td = NULL; - virt_ep->stopped_trb = NULL; virt_ep->stopped_stream = 0; spin_unlock_irqrestore(&xhci->lock, flags); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d280e9213d08..4746816aed3e 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -865,8 +865,6 @@ struct xhci_virt_ep { #define EP_GETTING_NO_STREAMS (1 << 5) /* ---- Related to URB cancellation ---- */ struct list_head cancelled_td_list; - /* The TRB that was last reported in a stopped endpoint ring */ - union xhci_trb *stopped_trb; struct xhci_td *stopped_td; unsigned int stopped_stream; /* Watchdog timer for stop endpoint command to cancel URBs */ -- GitLab From c09ec25d3684cad74d851c0f028a495999591279 Mon Sep 17 00:00:00 2001 From: Denis Turischev Date: Fri, 25 Apr 2014 19:20:14 +0300 Subject: [PATCH 678/797] xhci: Switch Intel Lynx Point ports to EHCI on shutdown. The same issue like with Panther Point chipsets. If the USB ports are switched to xHCI on shutdown, the xHCI host will send a spurious interrupt, which will wake the system. Some BIOS have work around for this, but not all. One example is Compulab's mini-desktop, the Intense-PC2. The bug can be avoided if the USB ports are switched back to EHCI on shutdown. This patch should be backported to stable kernels as old as 3.12, that contain the commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 "xhci: Fix spurious wakeups after S5 on Haswell" Signed-off-by: Denis Turischev Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 47390e369cd4..1715063630bd 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -134,6 +134,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) */ if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP) xhci->quirks |= XHCI_SPURIOUS_WAKEUP; + + xhci->quirks |= XHCI_SPURIOUS_REBOOT; } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_ASROCK_P67) { -- GitLab From 6db249ebefc6bf5c39f35dfaacc046d8ad3ffd70 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Fri, 25 Apr 2014 19:20:15 +0300 Subject: [PATCH 679/797] xhci: extend quirk for Renesas cards After suspend another Renesas PCI-X USB 3.0 card doesn't work. [root@fedora-20 ~]# lspci -vmnnd 1912: Device: 03:00.0 Class: USB controller [0c03] Vendor: Renesas Technology Corp. [1912] Device: uPD720202 USB 3.0 Host Controller [0015] SVendor: Renesas Technology Corp. [1912] SDevice: uPD720202 USB 3.0 Host Controller [0015] Rev: 02 ProgIf: 30 This patch should be applied to stable kernel 3.14 that contain the commit 1aa9578c1a9450fb21501c4f549f5b1edb557e6d "xhci: Fix resume issues on Renesas chips in Samsung laptops" Reported-and-tested-by: Anatoly Kharchenko Reference: http://redmine.russianfedora.pro/issues/1315 Signed-off-by: Igor Gnatenko Cc: stable@vger.kernel.org # 3.14 Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 1715063630bd..35d447780707 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -145,9 +145,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_TRUST_TX_LENGTH; } if (pdev->vendor == PCI_VENDOR_ID_RENESAS && - pdev->device == 0x0015 && - pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG && - pdev->subsystem_device == 0xc0cd) + pdev->device == 0x0015) xhci->quirks |= XHCI_RESET_ON_RESUME; if (pdev->vendor == PCI_VENDOR_ID_VIA) xhci->quirks |= XHCI_RESET_ON_RESUME; -- GitLab From 01bb59ebffdec314da8da66266edf29529372f9b Mon Sep 17 00:00:00 2001 From: David Cohen Date: Fri, 25 Apr 2014 19:20:16 +0300 Subject: [PATCH 680/797] usb/xhci: fix compilation warning when !CONFIG_PCI && !CONFIG_PM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When CONFIG_PCI and CONFIG_PM are not selected, xhci.c gets this warning: drivers/usb/host/xhci.c:409:13: warning: ‘xhci_msix_sync_irqs’ defined but not used [-Wunused-function] Instead of creating nested #ifdefs, this patch fixes it by defining the xHCI PCI stubs as inline. This warning has been in since 3.2 kernel and was caused by commit 421aa841a134f6a743111cf44d0c6d3b45e3cf8c "usb/xhci: hide MSI code behind PCI bars", but wasn't noticed until 3.13 when a configuration with these options was tried Signed-off-by: David Cohen Cc: stable@vger.kernel.org # 3.2 Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 988ed5f1cb2c..300836972faa 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -408,16 +408,16 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) #else -static int xhci_try_enable_msi(struct usb_hcd *hcd) +static inline int xhci_try_enable_msi(struct usb_hcd *hcd) { return 0; } -static void xhci_cleanup_msix(struct xhci_hcd *xhci) +static inline void xhci_cleanup_msix(struct xhci_hcd *xhci) { } -static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) +static inline void xhci_msix_sync_irqs(struct xhci_hcd *xhci) { } -- GitLab From 5509076d1b4485ce9fb07705fcbcd2695907ab5b Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 25 Apr 2014 15:23:03 +0200 Subject: [PATCH 681/797] USB: io_ti: fix firmware download on big-endian machines During firmware download the device expects memory addresses in big-endian byte order. As the wIndex parameter which hold the address is sent in little-endian byte order regardless of host byte order, we need to use swab16 rather than cpu_to_be16. Also make sure to handle the struct ti_i2c_desc size parameter which is returned in little-endian byte order. Reported-by: Ludovic Drolez Tested-by: Ludovic Drolez Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/io_ti.c | 50 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index a2db5be9c305..df90dae53eb9 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -280,7 +281,7 @@ static int read_download_mem(struct usb_device *dev, int start_address, { int status = 0; __u8 read_length; - __be16 be_start_address; + u16 be_start_address; dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, length); @@ -296,10 +297,14 @@ static int read_download_mem(struct usb_device *dev, int start_address, if (read_length > 1) { dev_dbg(&dev->dev, "%s - @ %x for %d\n", __func__, start_address, read_length); } - be_start_address = cpu_to_be16(start_address); + /* + * NOTE: Must use swab as wIndex is sent in little-endian + * byte order regardless of host byte order. + */ + be_start_address = swab16((u16)start_address); status = ti_vread_sync(dev, UMPC_MEMORY_READ, (__u16)address_type, - (__force __u16)be_start_address, + be_start_address, buffer, read_length); if (status) { @@ -394,7 +399,7 @@ static int write_i2c_mem(struct edgeport_serial *serial, struct device *dev = &serial->serial->dev->dev; int status = 0; int write_length; - __be16 be_start_address; + u16 be_start_address; /* We can only send a maximum of 1 aligned byte page at a time */ @@ -409,11 +414,16 @@ static int write_i2c_mem(struct edgeport_serial *serial, __func__, start_address, write_length); usb_serial_debug_data(dev, __func__, write_length, buffer); - /* Write first page */ - be_start_address = cpu_to_be16(start_address); + /* + * Write first page. + * + * NOTE: Must use swab as wIndex is sent in little-endian byte order + * regardless of host byte order. + */ + be_start_address = swab16((u16)start_address); status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE, (__u16)address_type, - (__force __u16)be_start_address, + be_start_address, buffer, write_length); if (status) { dev_dbg(dev, "%s - ERROR %d\n", __func__, status); @@ -436,11 +446,16 @@ static int write_i2c_mem(struct edgeport_serial *serial, __func__, start_address, write_length); usb_serial_debug_data(dev, __func__, write_length, buffer); - /* Write next page */ - be_start_address = cpu_to_be16(start_address); + /* + * Write next page. + * + * NOTE: Must use swab as wIndex is sent in little-endian byte + * order regardless of host byte order. + */ + be_start_address = swab16((u16)start_address); status = ti_vsend_sync(serial->serial->dev, UMPC_MEMORY_WRITE, (__u16)address_type, - (__force __u16)be_start_address, + be_start_address, buffer, write_length); if (status) { dev_err(dev, "%s - ERROR %d\n", __func__, status); @@ -585,8 +600,8 @@ static int get_descriptor_addr(struct edgeport_serial *serial, if (rom_desc->Type == desc_type) return start_address; - start_address = start_address + sizeof(struct ti_i2c_desc) - + rom_desc->Size; + start_address = start_address + sizeof(struct ti_i2c_desc) + + le16_to_cpu(rom_desc->Size); } while ((start_address < TI_MAX_I2C_SIZE) && rom_desc->Type); @@ -599,7 +614,7 @@ static int valid_csum(struct ti_i2c_desc *rom_desc, __u8 *buffer) __u16 i; __u8 cs = 0; - for (i = 0; i < rom_desc->Size; i++) + for (i = 0; i < le16_to_cpu(rom_desc->Size); i++) cs = (__u8)(cs + buffer[i]); if (cs != rom_desc->CheckSum) { @@ -650,7 +665,7 @@ static int check_i2c_image(struct edgeport_serial *serial) break; if ((start_address + sizeof(struct ti_i2c_desc) + - rom_desc->Size) > TI_MAX_I2C_SIZE) { + le16_to_cpu(rom_desc->Size)) > TI_MAX_I2C_SIZE) { status = -ENODEV; dev_dbg(dev, "%s - structure too big, erroring out.\n", __func__); break; @@ -665,7 +680,8 @@ static int check_i2c_image(struct edgeport_serial *serial) /* Read the descriptor data */ status = read_rom(serial, start_address + sizeof(struct ti_i2c_desc), - rom_desc->Size, buffer); + le16_to_cpu(rom_desc->Size), + buffer); if (status) break; @@ -674,7 +690,7 @@ static int check_i2c_image(struct edgeport_serial *serial) break; } start_address = start_address + sizeof(struct ti_i2c_desc) + - rom_desc->Size; + le16_to_cpu(rom_desc->Size); } while ((rom_desc->Type != I2C_DESC_TYPE_ION) && (start_address < TI_MAX_I2C_SIZE)); @@ -712,7 +728,7 @@ static int get_manuf_info(struct edgeport_serial *serial, __u8 *buffer) /* Read the descriptor data */ status = read_rom(serial, start_address+sizeof(struct ti_i2c_desc), - rom_desc->Size, buffer); + le16_to_cpu(rom_desc->Size), buffer); if (status) goto exit; -- GitLab From bc3ee18a7a57243721ecfd879319e3d2e882f289 Mon Sep 17 00:00:00 2001 From: Chanho Min Date: Mon, 14 Apr 2014 08:38:53 +0100 Subject: [PATCH 682/797] arm64: init: Move of_clk_init to time_init Clock providers should be initialized before clocksource_of_init. If not, Clock source initialization can be fail to get the clock. Acked-by: Will Deacon Signed-off-by: Chanho Min Signed-off-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/kernel/setup.c | 1 - arch/arm64/kernel/time.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 720853f70b6b..93e7df8968fe 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -393,7 +393,6 @@ void __init setup_arch(char **cmdline_p) static int __init arm64_device_init(void) { - of_clk_init(NULL); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); return 0; } diff --git a/arch/arm64/kernel/time.c b/arch/arm64/kernel/time.c index 29c39d5d77e3..6815987b50f8 100644 --- a/arch/arm64/kernel/time.c +++ b/arch/arm64/kernel/time.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -65,6 +66,7 @@ void __init time_init(void) { u32 arch_timer_rate; + of_clk_init(NULL); clocksource_of_init(); arch_timer_rate = arch_timer_get_rate(); -- GitLab From a00986f81182a69dee4d2c48e8c19805bdf0f790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 25 Apr 2014 18:49:15 +0200 Subject: [PATCH 683/797] usb: qcserial: add Sierra Wireless EM7355 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 968a40201e5f..662235240f3f 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -139,6 +139,9 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 0)}, /* Sierra Wireless EM7700 Device Management */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 2)}, /* Sierra Wireless EM7700 NMEA */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 3)}, /* Sierra Wireless EM7700 Modem */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 0)}, /* Sierra Wireless EM7355 Device Management */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 2)}, /* Sierra Wireless EM7355 NMEA */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 3)}, /* Sierra Wireless EM7355 Modem */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */ -- GitLab From 70a3615fc07c2330ed7c1e922f3c44f4a67c0762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 25 Apr 2014 18:49:16 +0200 Subject: [PATCH 684/797] usb: qcserial: add Sierra Wireless MC73xx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 662235240f3f..1d1bc9b41337 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -136,6 +136,9 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68a2, 0)}, /* Sierra Wireless MC7710 Device Management */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68a2, 2)}, /* Sierra Wireless MC7710 NMEA */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68a2, 3)}, /* Sierra Wireless MC7710 Modem */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68c0, 0)}, /* Sierra Wireless MC73xx Device Management */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68c0, 2)}, /* Sierra Wireless MC73xx NMEA */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x68c0, 3)}, /* Sierra Wireless MC73xx Modem */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 0)}, /* Sierra Wireless EM7700 Device Management */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 2)}, /* Sierra Wireless EM7700 NMEA */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901c, 3)}, /* Sierra Wireless EM7700 Modem */ -- GitLab From bce4f588f19d59fc07fadfeb0b2a3a06c942827a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 25 Apr 2014 18:49:17 +0200 Subject: [PATCH 685/797] usb: qcserial: add Sierra Wireless MC7305/MC7355 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 1d1bc9b41337..7ed681a714a5 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -145,6 +145,9 @@ static const struct usb_device_id id_table[] = { {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 0)}, /* Sierra Wireless EM7355 Device Management */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 2)}, /* Sierra Wireless EM7355 NMEA */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x901f, 3)}, /* Sierra Wireless EM7355 Modem */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9041, 0)}, /* Sierra Wireless MC7305/MC7355 Device Management */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9041, 2)}, /* Sierra Wireless MC7305/MC7355 NMEA */ + {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9041, 3)}, /* Sierra Wireless MC7305/MC7355 Modem */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */ {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */ -- GitLab From 533b3994610f316e5cd61b56d0c4daa15c830f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 25 Apr 2014 18:49:18 +0200 Subject: [PATCH 686/797] usb: option: add Olivetti Olicard 500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device interface layout: 0: ff/ff/ff - serial 1: ff/ff/ff - serial AT+PPP 2: 08/06/50 - storage 3: ff/ff/ff - serial 4: ff/ff/ff - QMI/wwan Cc: Reported-by: Julio Araujo Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 367c7f08b27c..6335222cb892 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -349,6 +349,7 @@ static void option_instat_callback(struct urb *urb); #define OLIVETTI_PRODUCT_OLICARD100 0xc000 #define OLIVETTI_PRODUCT_OLICARD145 0xc003 #define OLIVETTI_PRODUCT_OLICARD200 0xc005 +#define OLIVETTI_PRODUCT_OLICARD500 0xc00b /* Celot products */ #define CELOT_VENDOR_ID 0x211f @@ -1545,6 +1546,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist + }, { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, -- GitLab From dd6b48ecec2ea7d15f28d5e5474388681899a5e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 25 Apr 2014 18:49:19 +0200 Subject: [PATCH 687/797] usb: option: add Alcatel L800MA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device interface layout: 0: ff/ff/ff - serial 1: ff/00/00 - serial AT+PPP 2: ff/ff/ff - QMI/wwan 3: 08/06/50 - storage Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 6335222cb892..776c86f3c091 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -287,6 +287,7 @@ static void option_instat_callback(struct urb *urb); #define ALCATEL_PRODUCT_X060S_X200 0x0000 #define ALCATEL_PRODUCT_X220_X500D 0x0017 #define ALCATEL_PRODUCT_L100V 0x011e +#define ALCATEL_PRODUCT_L800MA 0x0203 #define PIRELLI_VENDOR_ID 0x1266 #define PIRELLI_PRODUCT_C100_1 0x1002 @@ -1501,6 +1502,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L800MA), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), -- GitLab From 34f972d6156fe9eea2ab7bb418c71f9d1d5c8e7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 25 Apr 2014 18:49:20 +0200 Subject: [PATCH 688/797] usb: option: add and update a number of CMOTech devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A number of older CMOTech modems are based on Qualcomm chips. The blacklisted interfaces are QMI/wwan. Reported-by: Lars Melin Cc: Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 74 +++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 776c86f3c091..f213ee978516 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -234,8 +234,31 @@ static void option_instat_callback(struct urb *urb); #define QUALCOMM_VENDOR_ID 0x05C6 #define CMOTECH_VENDOR_ID 0x16d8 -#define CMOTECH_PRODUCT_6008 0x6008 -#define CMOTECH_PRODUCT_6280 0x6280 +#define CMOTECH_PRODUCT_6001 0x6001 +#define CMOTECH_PRODUCT_CMU_300 0x6002 +#define CMOTECH_PRODUCT_6003 0x6003 +#define CMOTECH_PRODUCT_6004 0x6004 +#define CMOTECH_PRODUCT_6005 0x6005 +#define CMOTECH_PRODUCT_CGU_628A 0x6006 +#define CMOTECH_PRODUCT_CHE_628S 0x6007 +#define CMOTECH_PRODUCT_CMU_301 0x6008 +#define CMOTECH_PRODUCT_CHU_628 0x6280 +#define CMOTECH_PRODUCT_CHU_628S 0x6281 +#define CMOTECH_PRODUCT_CDU_680 0x6803 +#define CMOTECH_PRODUCT_CDU_685A 0x6804 +#define CMOTECH_PRODUCT_CHU_720S 0x7001 +#define CMOTECH_PRODUCT_7002 0x7002 +#define CMOTECH_PRODUCT_CHU_629K 0x7003 +#define CMOTECH_PRODUCT_7004 0x7004 +#define CMOTECH_PRODUCT_7005 0x7005 +#define CMOTECH_PRODUCT_CGU_629 0x7006 +#define CMOTECH_PRODUCT_CHU_629S 0x700a +#define CMOTECH_PRODUCT_CHU_720I 0x7211 +#define CMOTECH_PRODUCT_7212 0x7212 +#define CMOTECH_PRODUCT_7213 0x7213 +#define CMOTECH_PRODUCT_7251 0x7251 +#define CMOTECH_PRODUCT_7252 0x7252 +#define CMOTECH_PRODUCT_7253 0x7253 #define TELIT_VENDOR_ID 0x1bc7 #define TELIT_PRODUCT_UC864E 0x1003 @@ -504,6 +527,10 @@ static const struct option_blacklist_info huawei_cdc12_blacklist = { .reserved = BIT(1) | BIT(2), }; +static const struct option_blacklist_info net_intf0_blacklist = { + .reserved = BIT(0), +}; + static const struct option_blacklist_info net_intf1_blacklist = { .reserved = BIT(1), }; @@ -1037,8 +1064,47 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6280) }, /* BP3-USB & BP3-EXT HSDPA */ - { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6008) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6004) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6005) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_628A) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHE_628S), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_301), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628S) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_680) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_685A) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720S), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7002), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629K), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7004), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7005) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_629), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629S), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720I), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7212), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7213), + .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7251), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7252), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7253), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, -- GitLab From c1befb885939cdaaf420c10bbe9ff57aa00446ea Mon Sep 17 00:00:00 2001 From: Jianyu Zhan Date: Thu, 17 Apr 2014 17:52:10 +0800 Subject: [PATCH 689/797] kernfs: fix a subdir count leak Currently kernfs_link_sibling() increates parent->dir.subdirs before adding the node into parent's chidren rb tree. Because it is possible that kernfs_link_sibling() couldn't find a suitable slot and bail out, this leads to a mismatch between elevated subdir count with actual children node numbers. This patches fix this problem, by moving the subdir accouting after the actual addtion happening. Signed-off-by: Jianyu Zhan Acked-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/dir.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 78f3403300af..ac127cd008bf 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -232,9 +232,6 @@ static int kernfs_link_sibling(struct kernfs_node *kn) struct rb_node **node = &kn->parent->dir.children.rb_node; struct rb_node *parent = NULL; - if (kernfs_type(kn) == KERNFS_DIR) - kn->parent->dir.subdirs++; - while (*node) { struct kernfs_node *pos; int result; @@ -249,9 +246,15 @@ static int kernfs_link_sibling(struct kernfs_node *kn) else return -EEXIST; } + /* add new node and rebalance the tree */ rb_link_node(&kn->rb, parent, node); rb_insert_color(&kn->rb, &kn->parent->dir.children); + + /* successfully added, account subdir number */ + if (kernfs_type(kn) == KERNFS_DIR) + kn->parent->dir.subdirs++; + return 0; } -- GitLab From b44b2140265ddfde03acbe809336111d31adb0d1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 20 Apr 2014 08:29:21 -0400 Subject: [PATCH 690/797] kernfs: add back missing error check in kernfs_fop_mmap() While updating how mmap enabled kernfs files are handled by lockdep, 9b2db6e18945 ("sysfs: bail early from kernfs_file_mmap() to avoid spurious lockdep warning") inadvertently dropped error return check from kernfs_file_mmap(). The intention was just dropping "if (ops->mmap)" check as the control won't reach the point if the mmap callback isn't implemented, but I mistakenly removed the error return check together with it. This led to Xorg crash on i810 which was reported and bisected to the commit and then to the specific change by Tobias. Signed-off-by: Tejun Heo Reported-and-bisected-by: Tobias Powalowski Tested-by: Tobias Powalowski References: http://lkml.kernel.org/g/533D01BD.1010200@googlemail.com Cc: stable # 3.14 Signed-off-by: Greg Kroah-Hartman --- fs/kernfs/file.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 8034706a7af8..e01ea4a14a01 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -484,6 +484,8 @@ static int kernfs_fop_mmap(struct file *file, struct vm_area_struct *vma) ops = kernfs_ops(of->kn); rc = ops->mmap(of, vma); + if (rc) + goto out_put; /* * PowerPC's pci_mmap of legacy_mem uses shmem_zero_setup() -- GitLab From 0c8c77d35582c3f7989f1316368da5ae7f14ad4b Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Wed, 23 Apr 2014 20:58:45 +0200 Subject: [PATCH 691/797] s390/ccwgroup: Fix memory corruption commit 0b60f9ead5d4816e7e3d6e28f4a0d22d4a1b2513 (s390: use device_remove_file_self() instead of device_schedule_callback()) caused random memory corruption on my s390 box. Turns out that the last element of the ccwgroup structure is of dynamic size, so we must move the newly introduced work structure _before_ the zero length array. Signed-off-by: Christian Borntraeger CC: Tejun Heo CC: Martin Schwidefsky CC: Heiko Carstens CC: Sebastian Ott CC: Peter Oberparleiter Acked-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- arch/s390/include/asm/ccwgroup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h index 6e670f88d125..ebc2913f9ee0 100644 --- a/arch/s390/include/asm/ccwgroup.h +++ b/arch/s390/include/asm/ccwgroup.h @@ -22,8 +22,8 @@ struct ccwgroup_device { /* public: */ unsigned int count; struct device dev; - struct ccw_device *cdev[0]; struct work_struct ungroup_work; + struct ccw_device *cdev[0]; }; /** -- GitLab From 1cf35d47712dd5dc4d62c6ce984f04ac6eab0408 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 25 Apr 2014 16:05:40 -0700 Subject: [PATCH 692/797] mm: split 'tlb_flush_mmu()' into tlb flushing and memory freeing parts The mmu-gather operation 'tlb_flush_mmu()' has done two things: the actual tlb flush operation, and the batched freeing of the pages that the TLB entries pointed at. This splits the operation into separate phases, so that the forced batched flushing done by zap_pte_range() can now do the actual TLB flush while still holding the page table lock, but delay the batched freeing of all the pages to after the lock has been dropped. This in turn allows us to avoid a race condition between set_page_dirty() (as called by zap_pte_range() when it finds a dirty shared memory pte) and page_mkclean(): because we now flush all the dirty page data from the TLB's while holding the pte lock, page_mkclean() will be held up walking the (recently cleaned) page tables until after the TLB entries have been flushed from all CPU's. Reported-by: Benjamin Herrenschmidt Tested-by: Dave Hansen Acked-by: Hugh Dickins Cc: Peter Zijlstra Cc: Russell King - ARM Linux Cc: Tony Luck Signed-off-by: Linus Torvalds --- arch/arm/include/asm/tlb.h | 12 ++++++++- arch/ia64/include/asm/tlb.h | 42 ++++++++++++++++++++++------- arch/s390/include/asm/tlb.h | 13 ++++++++- arch/sh/include/asm/tlb.h | 8 ++++++ arch/um/include/asm/tlb.h | 16 +++++++++-- mm/memory.c | 53 ++++++++++++++++++++++++------------- 6 files changed, 111 insertions(+), 33 deletions(-) diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 0baf7f0d9394..f1a0dace3efe 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -98,15 +98,25 @@ static inline void __tlb_alloc_page(struct mmu_gather *tlb) } } -static inline void tlb_flush_mmu(struct mmu_gather *tlb) +static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) { tlb_flush(tlb); +} + +static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) +{ free_pages_and_swap_cache(tlb->pages, tlb->nr); tlb->nr = 0; if (tlb->pages == tlb->local) __tlb_alloc_page(tlb); } +static inline void tlb_flush_mmu(struct mmu_gather *tlb) +{ + tlb_flush_mmu_tlbonly(tlb); + tlb_flush_mmu_free(tlb); +} + static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start, unsigned long end) { diff --git a/arch/ia64/include/asm/tlb.h b/arch/ia64/include/asm/tlb.h index bc5efc7c3f3f..39d64e0df1de 100644 --- a/arch/ia64/include/asm/tlb.h +++ b/arch/ia64/include/asm/tlb.h @@ -91,18 +91,9 @@ extern struct ia64_tr_entry *ia64_idtrs[NR_CPUS]; #define RR_RID_MASK 0x00000000ffffff00L #define RR_TO_RID(val) ((val >> 8) & 0xffffff) -/* - * Flush the TLB for address range START to END and, if not in fast mode, release the - * freed pages that where gathered up to this point. - */ static inline void -ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end) +ia64_tlb_flush_mmu_tlbonly(struct mmu_gather *tlb, unsigned long start, unsigned long end) { - unsigned long i; - unsigned int nr; - - if (!tlb->need_flush) - return; tlb->need_flush = 0; if (tlb->fullmm) { @@ -135,6 +126,14 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e flush_tlb_range(&vma, ia64_thash(start), ia64_thash(end)); } +} + +static inline void +ia64_tlb_flush_mmu_free(struct mmu_gather *tlb) +{ + unsigned long i; + unsigned int nr; + /* lastly, release the freed pages */ nr = tlb->nr; @@ -144,6 +143,19 @@ ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long e free_page_and_swap_cache(tlb->pages[i]); } +/* + * Flush the TLB for address range START to END and, if not in fast mode, release the + * freed pages that where gathered up to this point. + */ +static inline void +ia64_tlb_flush_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end) +{ + if (!tlb->need_flush) + return; + ia64_tlb_flush_mmu_tlbonly(tlb, start, end); + ia64_tlb_flush_mmu_free(tlb); +} + static inline void __tlb_alloc_page(struct mmu_gather *tlb) { unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0); @@ -206,6 +218,16 @@ static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) return tlb->max - tlb->nr; } +static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) +{ + ia64_tlb_flush_mmu_tlbonly(tlb, tlb->start_addr, tlb->end_addr); +} + +static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) +{ + ia64_tlb_flush_mmu_free(tlb); +} + static inline void tlb_flush_mmu(struct mmu_gather *tlb) { ia64_tlb_flush_mmu(tlb, tlb->start_addr, tlb->end_addr); diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h index c544b6f05d95..a25f09fbaf36 100644 --- a/arch/s390/include/asm/tlb.h +++ b/arch/s390/include/asm/tlb.h @@ -59,12 +59,23 @@ static inline void tlb_gather_mmu(struct mmu_gather *tlb, tlb->batch = NULL; } -static inline void tlb_flush_mmu(struct mmu_gather *tlb) +static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) { __tlb_flush_mm_lazy(tlb->mm); +} + +static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) +{ tlb_table_flush(tlb); } + +static inline void tlb_flush_mmu(struct mmu_gather *tlb) +{ + tlb_flush_mmu_tlbonly(tlb); + tlb_flush_mmu_free(tlb); +} + static inline void tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end) { diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 362192ed12fe..62f80d2a9df9 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -86,6 +86,14 @@ tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vma) } } +static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) +{ +} + +static inline void tlb_flush_mmu_free(struct mmu_gather *tlb) +{ +} + static inline void tlb_flush_mmu(struct mmu_gather *tlb) { } diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h index 29b0301c18aa..16eb63fac57d 100644 --- a/arch/um/include/asm/tlb.h +++ b/arch/um/include/asm/tlb.h @@ -58,14 +58,26 @@ tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long start extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end); +static inline void +tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) +{ + flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end); +} + +static inline void +tlb_flush_mmu_free(struct mmu_gather *tlb) +{ + init_tlb_gather(tlb); +} + static inline void tlb_flush_mmu(struct mmu_gather *tlb) { if (!tlb->need_flush) return; - flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end); - init_tlb_gather(tlb); + tlb_flush_mmu_tlbonly(tlb); + tlb_flush_mmu_free(tlb); } /* tlb_finish_mmu diff --git a/mm/memory.c b/mm/memory.c index 93e332d5ed77..037b812a9531 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -232,17 +232,18 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned long #endif } -void tlb_flush_mmu(struct mmu_gather *tlb) +static void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb) { - struct mmu_gather_batch *batch; - - if (!tlb->need_flush) - return; tlb->need_flush = 0; tlb_flush(tlb); #ifdef CONFIG_HAVE_RCU_TABLE_FREE tlb_table_flush(tlb); #endif +} + +static void tlb_flush_mmu_free(struct mmu_gather *tlb) +{ + struct mmu_gather_batch *batch; for (batch = &tlb->local; batch; batch = batch->next) { free_pages_and_swap_cache(batch->pages, batch->nr); @@ -251,6 +252,14 @@ void tlb_flush_mmu(struct mmu_gather *tlb) tlb->active = &tlb->local; } +void tlb_flush_mmu(struct mmu_gather *tlb) +{ + if (!tlb->need_flush) + return; + tlb_flush_mmu_tlbonly(tlb); + tlb_flush_mmu_free(tlb); +} + /* tlb_finish_mmu * Called at the end of the shootdown operation to free up any resources * that were required. @@ -1127,8 +1136,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, if (PageAnon(page)) rss[MM_ANONPAGES]--; else { - if (pte_dirty(ptent)) + if (pte_dirty(ptent)) { + force_flush = 1; set_page_dirty(page); + } if (pte_young(ptent) && likely(!(vma->vm_flags & VM_SEQ_READ))) mark_page_accessed(page); @@ -1137,9 +1148,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, page_remove_rmap(page); if (unlikely(page_mapcount(page) < 0)) print_bad_pte(vma, addr, ptent, page); - force_flush = !__tlb_remove_page(tlb, page); - if (force_flush) + if (unlikely(!__tlb_remove_page(tlb, page))) { + force_flush = 1; break; + } continue; } /* @@ -1174,18 +1186,11 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, add_mm_rss_vec(mm, rss); arch_leave_lazy_mmu_mode(); - pte_unmap_unlock(start_pte, ptl); - /* - * mmu_gather ran out of room to batch pages, we break out of - * the PTE lock to avoid doing the potential expensive TLB invalidate - * and page-free while holding it. - */ + /* Do the actual TLB flush before dropping ptl */ if (force_flush) { unsigned long old_end; - force_flush = 0; - /* * Flush the TLB just for the previous segment, * then update the range to be the remaining @@ -1193,11 +1198,21 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, */ old_end = tlb->end; tlb->end = addr; - - tlb_flush_mmu(tlb); - + tlb_flush_mmu_tlbonly(tlb); tlb->start = addr; tlb->end = old_end; + } + pte_unmap_unlock(start_pte, ptl); + + /* + * If we forced a TLB flush (either due to running out of + * batch buffers or because we needed to flush dirty TLB + * entries before releasing the ptl), free the batched + * memory too. Restart if we didn't do everything. + */ + if (force_flush) { + force_flush = 0; + tlb_flush_mmu_free(tlb); if (addr != end) goto again; -- GitLab From 4e4468fac4381b92eb333d94256e7fb8350f3de3 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 25 Apr 2014 11:46:04 +0100 Subject: [PATCH 693/797] ARM: KVM: disable KVM in Kconfig on big-endian systems KVM currently crashes and burns on big-endian hosts, so don't allow it to be selected until we've got that fixed. Cc: Marc Zyngier Signed-off-by: Will Deacon Signed-off-by: Christoffer Dall --- arch/arm/kvm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig index 466bd299b1a8..4be5bb150bdd 100644 --- a/arch/arm/kvm/Kconfig +++ b/arch/arm/kvm/Kconfig @@ -23,7 +23,7 @@ config KVM select HAVE_KVM_CPU_RELAX_INTERCEPT select KVM_MMIO select KVM_ARM_HOST - depends on ARM_VIRT_EXT && ARM_LPAE + depends on ARM_VIRT_EXT && ARM_LPAE && !CPU_BIG_ENDIAN ---help--- Support hosting virtualized guest machines. You will also need to select one or more of the processor modules below. -- GitLab From cfd4a535b68faf651b238586011f5bae128391c4 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Sat, 26 Apr 2014 05:02:03 -0700 Subject: [PATCH 694/797] Btrfs: limit the path size in send to PATH_MAX fs_path_ensure_buf is used to make sure our path buffers for send are big enough for the path names as we construct them. The buffer size is limited to 32K by the length field in the struct. But bugs in the path construction can end up trying to build a huge buffer, and we'll do invalid memmmoves when the buffer length field wraps. This patch is step one, preventing the overflows. Signed-off-by: Chris Mason --- fs/btrfs/send.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 1ac3ca98c429..eb6537a08c1b 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -349,6 +349,11 @@ static int fs_path_ensure_buf(struct fs_path *p, int len) if (p->buf_len >= len) return 0; + if (len > PATH_MAX) { + WARN_ON(1); + return -ENOMEM; + } + path_len = p->end - p->start; old_buf_len = p->buf_len; -- GitLab From ec6931b281797b69e6cf109f9cc94d5a2bf994e0 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 23 Apr 2014 17:52:52 +0100 Subject: [PATCH 695/797] word-at-a-time: avoid undefined behaviour in zero_bytemask macro The asm-generic, big-endian version of zero_bytemask creates a mask of bytes preceding the first zero-byte by left shifting ~0ul based on the position of the first zero byte. Unfortunately, if the first (top) byte is zero, the output of prep_zero_mask has only the top bit set, resulting in undefined C behaviour as we shift left by an amount equal to the width of the type. As it happens, GCC doesn't manage to spot this through the call to fls(), but the issue remains if architectures choose to implement their shift instructions differently. An example would be arch/arm/ (AArch32), where LSL Rd, Rn, #32 results in Rd == 0x0, whilst on arch/arm64 (AArch64) LSL Xd, Xn, #64 results in Xd == Xn. Rather than check explicitly for the problematic shift, this patch adds an extra shift by 1, replacing fls with __fls. Since zero_bytemask is never called with a zero argument (has_zero() is used to check the data first), we don't need to worry about calling __fls(0), which is undefined. Cc: Cc: Victor Kamensky Signed-off-by: Will Deacon Signed-off-by: Linus Torvalds --- include/asm-generic/word-at-a-time.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h index d3909effd725..d96deb443f18 100644 --- a/include/asm-generic/word-at-a-time.h +++ b/include/asm-generic/word-at-a-time.h @@ -50,11 +50,7 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct } #ifndef zero_bytemask -#ifdef CONFIG_64BIT -#define zero_bytemask(mask) (~0ul << fls64(mask)) -#else -#define zero_bytemask(mask) (~0ul << fls(mask)) -#endif /* CONFIG_64BIT */ -#endif /* zero_bytemask */ +#define zero_bytemask(mask) (~0ul << __fls(mask) << 1) +#endif #endif /* _ASM_WORD_AT_A_TIME_H */ -- GitLab From 79465d2fd48e68940c2bdecddbdecd45bbba06fe Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 28 Apr 2014 11:05:43 +0930 Subject: [PATCH 696/797] module: remove warning about waiting module removal. We remove the waiting module removal in commit 3f2b9c9cdf38 (September 2013), but it turns out that modprobe in kmod (< version 16) was asking for waiting module removal. No one noticed since modprobe would check for 0 usage immediately before trying to remove the module, and the race is unlikely. However, it means that anyone running old (but not ancient) kmod versions is hitting the printk designed to see if anyone was running "rmmod -w". All reports so far have been false positives, so remove the warning. Fixes: 3f2b9c9cdf389e303b2273679af08aab5f153517 Reported-by: Valerio Vanni Cc: Elliott, Robert (Server Storage) Cc: stable@kernel.org Acked-by: Lucas De Marchi Signed-off-by: Rusty Russell --- kernel/module.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index 11869408f79b..ae7821898bf2 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -815,9 +815,6 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user, return -EFAULT; name[MODULE_NAME_LEN-1] = '\0'; - if (!(flags & O_NONBLOCK)) - pr_warn("waiting module removal not supported: please upgrade\n"); - if (mutex_lock_interruptible(&module_mutex) != 0) return -EINTR; -- GitLab From d1db0eea852497762cab43b905b879dfcd3b8987 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 27 Apr 2014 19:29:27 -0700 Subject: [PATCH 697/797] Linux 3.15-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 80a2d2448531..041c685e11ea 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 15 SUBLEVEL = 0 -EXTRAVERSION = -rc2 +EXTRAVERSION = -rc3 NAME = Shuffling Zombie Juror # *DOCUMENTATION* -- GitLab From 28ea3c7529388c1e4177336a0e655c6c7272fd1c Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Sun, 27 Apr 2014 18:10:43 -0400 Subject: [PATCH 698/797] powerpc: Export flush_icache_range Commit aac416fc38c (lkdtm: flush icache and report actions) calls flush_icache_range from a module. It's exported on most architectures that implement it, but not on powerpc. This patch exports it to fix the module link failure. Signed-off-by: Jeff Mahoney Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/ppc_ksyms.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index 3bd77edd7610..450850a49dce 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -120,6 +120,7 @@ EXPORT_SYMBOL(giveup_spe); EXPORT_SYMBOL(flush_instruction_cache); #endif EXPORT_SYMBOL(flush_dcache_range); +EXPORT_SYMBOL(flush_icache_range); #ifdef CONFIG_SMP #ifdef CONFIG_PPC32 -- GitLab From 4fb8d027dca0236c811272d342cf185569d91311 Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Mon, 28 Apr 2014 08:29:51 +0800 Subject: [PATCH 699/797] powerpc: Fix Oops in rtas_stop_self() commit 41dd03a9 may cause Oops in rtas_stop_self(). The reason is that the rtas_args was moved into stack space. For a box with more that 4GB RAM, the stack could easily be outside 32bit range, but RTAS is 32bit. So the patch moves rtas_args away from stack by adding static before it. Signed-off-by: Li Zhong Signed-off-by: Anton Blanchard Cc: stable@vger.kernel.org # 3.14+ Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/hotplug-cpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 9b8e05078a63..20d62975856f 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -88,13 +88,14 @@ void set_default_offline_state(int cpu) static void rtas_stop_self(void) { - struct rtas_args args = { - .token = cpu_to_be32(rtas_stop_self_token), + static struct rtas_args args = { .nargs = 0, .nret = 1, .rets = &args.args[0], }; + args.token = cpu_to_be32(rtas_stop_self_token); + local_irq_disable(); BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE); -- GitLab From ba9a32b176c31ec4d3d7314bb2e529a85423f7a4 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 24 Apr 2014 16:55:33 +0930 Subject: [PATCH 700/797] powerpc/powernv: Fix sysparam sysfs error handling When a sysparam query in OPAL returned a negative value (error code), sysfs would spew out a decent chunk of memory; almost 64K more than expected. This was traced to a sign/unsigned mix up in the OPAL sysparam sysfs code at sys_param_show. The return value of sys_param_show is a ssize_t, calculated using return ret ? ret : attr->param_size; Alan Modra explains: "attr->param_size" is an unsigned int, "ret" an int, so the overall expression has type unsigned int. Result is that ret is cast to unsigned int before being cast to ssize_t. Instead of using the ternary operator, set ret to the param_size if an error is not detected. The same bug exists in the sysfs write callback; this patch fixes it in the same way. A note on debugging this next time: on my system gcc will warn about this if compiled with -Wsign-compare, which is not enabled by -Wall, only -Wextra. Signed-off-by: Joel Stanley Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-sysparam.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 6b614726baf2..a51ea189aec3 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -121,9 +121,10 @@ static ssize_t sys_param_show(struct kobject *kobj, memcpy(buf, param_data_buf, attr->param_size); + ret = attr->param_size; out: mutex_unlock(&opal_sysparam_mutex); - return ret ? ret : attr->param_size; + return ret; } static ssize_t sys_param_store(struct kobject *kobj, @@ -138,7 +139,9 @@ static ssize_t sys_param_store(struct kobject *kobj, ret = opal_set_sys_param(attr->param_id, attr->param_size, param_data_buf); mutex_unlock(&opal_sysparam_mutex); - return ret ? ret : count; + if (!ret) + ret = count; + return ret; } void __init opal_sys_param_init(void) -- GitLab From b8569d230416c490065098684adf13c1751cb830 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 24 Apr 2014 16:55:34 +0930 Subject: [PATCH 701/797] powerpc/powernv: Use ssize_t for sysparam return values The OPAL calls are returning int64_t values, which the sysparam code stores in an int, and the sysfs callback returns ssize_t. Make code a easier to read by consistently using ssize_t. Signed-off-by: Joel Stanley Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-sysparam.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index a51ea189aec3..0675e1a90b40 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -39,10 +39,11 @@ struct param_attr { struct kobj_attribute kobj_attr; }; -static int opal_get_sys_param(u32 param_id, u32 length, void *buffer) +static ssize_t opal_get_sys_param(u32 param_id, u32 length, void *buffer) { struct opal_msg msg; - int ret, token; + ssize_t ret; + int token; token = opal_async_get_token_interruptible(); if (token < 0) { @@ -59,7 +60,7 @@ static int opal_get_sys_param(u32 param_id, u32 length, void *buffer) ret = opal_async_wait_response(token, &msg); if (ret) { - pr_err("%s: Failed to wait for the async response, %d\n", + pr_err("%s: Failed to wait for the async response, %zd\n", __func__, ret); goto out_token; } @@ -111,7 +112,7 @@ static ssize_t sys_param_show(struct kobject *kobj, { struct param_attr *attr = container_of(kobj_attr, struct param_attr, kobj_attr); - int ret; + ssize_t ret; mutex_lock(&opal_sysparam_mutex); ret = opal_get_sys_param(attr->param_id, attr->param_size, @@ -132,7 +133,7 @@ static ssize_t sys_param_store(struct kobject *kobj, { struct param_attr *attr = container_of(kobj_attr, struct param_attr, kobj_attr); - int ret; + ssize_t ret; mutex_lock(&opal_sysparam_mutex); memcpy(param_data_buf, buf, count); -- GitLab From 85390378f0a6abf3bdb10c3d504d77862a2d0ec9 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 24 Apr 2014 16:55:35 +0930 Subject: [PATCH 702/797] powerpc/powernv: Check sysfs size before copying The sysparam code currently uses the userspace supplied number of bytes when memcpy()ing in to a local 64-byte buffer. Limit the maximum number of bytes by the size of the buffer. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-sysparam.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 0675e1a90b40..83f5f2a1c563 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -135,6 +135,10 @@ static ssize_t sys_param_store(struct kobject *kobj, kobj_attr); ssize_t ret; + /* MAX_PARAM_DATA_LEN is sizeof(param_data_buf) */ + if (count > MAX_PARAM_DATA_LEN) + count = MAX_PARAM_DATA_LEN; + mutex_lock(&opal_sysparam_mutex); memcpy(param_data_buf, buf, count); ret = opal_set_sys_param(attr->param_id, attr->param_size, -- GitLab From 16003d235bdb4d1ebcecfe4915c6e6d8c95f4a0c Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 24 Apr 2014 16:55:36 +0930 Subject: [PATCH 703/797] powerpc/powernv: Fix typos in sysparam code Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-sysparam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index 83f5f2a1c563..c59e77a84721 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -222,13 +222,13 @@ void __init opal_sys_param_init(void) } if (of_property_read_u32_array(sysparam, "param-len", size, count)) { - pr_err("SYSPARAM: Missing propery param-len in the DT\n"); + pr_err("SYSPARAM: Missing property param-len in the DT\n"); goto out_free_perm; } if (of_property_read_u8_array(sysparam, "param-perm", perm, count)) { - pr_err("SYSPARAM: Missing propery param-perm in the DT\n"); + pr_err("SYSPARAM: Missing property param-perm in the DT\n"); goto out_free_perm; } -- GitLab From 63aecfb20a6629f1ca91d7a052f87988ceb6dd53 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 24 Apr 2014 16:55:37 +0930 Subject: [PATCH 704/797] powerpc/powernv: Check sysparam size before creation The size of the sysparam sysfs files is determined from the device tree at boot. However the buffer is hard coded to 64 bytes. If we encounter a parameter that is larger than 64, or miss-parse the device tree, the buffer will overflow when reading or writing to the parameter. Check it at discovery time, and if the parameter is too large, do not create a sysfs entry for it. Signed-off-by: Joel Stanley Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-sysparam.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index c59e77a84721..d202f9bc3683 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -241,6 +241,12 @@ void __init opal_sys_param_init(void) /* For each of the parameters, populate the parameter attributes */ for (i = 0; i < count; i++) { + if (size[i] > MAX_PARAM_DATA_LEN) { + pr_warn("SYSPARAM: Not creating parameter %d as size " + "exceeds buffer length\n", i); + continue; + } + sysfs_attr_init(&attr[i].kobj_attr.attr); attr[i].param_id = id[i]; attr[i].param_size = size[i]; -- GitLab From 298b34d7d578c3b4325248b823f3d83a8ea1541c Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 24 Apr 2014 16:14:25 +1000 Subject: [PATCH 705/797] powerpc/powernv: Fix kexec races going back to OPAL We have a subtle race when sending CPUs back to OPAL on kexec. We mark them as "in real mode" right before we send them down. Once we've booted the new kernel, it might try to call opal_reinit_cpus() to change endianness, and that requires all CPUs to be spinning inside OPAL. However there is no synchronization here and we've observed cases where the returning CPUs hadn't established their new state inside OPAL before opal_reinit_cpus() is called, causing it to fail. The proper fix is to actually wait for them to go down all the way from the kexec'ing kernel. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/setup.c | 48 ++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c index 61cf8fa9c61b..8723d32632f5 100644 --- a/arch/powerpc/platforms/powernv/setup.c +++ b/arch/powerpc/platforms/powernv/setup.c @@ -162,18 +162,62 @@ static void pnv_shutdown(void) } #ifdef CONFIG_KEXEC +static void pnv_kexec_wait_secondaries_down(void) +{ + int my_cpu, i, notified = -1; + + my_cpu = get_cpu(); + + for_each_online_cpu(i) { + uint8_t status; + int64_t rc; + + if (i == my_cpu) + continue; + + for (;;) { + rc = opal_query_cpu_status(get_hard_smp_processor_id(i), + &status); + if (rc != OPAL_SUCCESS || status != OPAL_THREAD_STARTED) + break; + barrier(); + if (i != notified) { + printk(KERN_INFO "kexec: waiting for cpu %d " + "(physical %d) to enter OPAL\n", + i, paca[i].hw_cpu_id); + notified = i; + } + } + } +} + static void pnv_kexec_cpu_down(int crash_shutdown, int secondary) { xics_kexec_teardown_cpu(secondary); - /* Return secondary CPUs to firmware on OPAL v3 */ - if (firmware_has_feature(FW_FEATURE_OPALv3) && secondary) { + /* On OPAL v3, we return all CPUs to firmware */ + + if (!firmware_has_feature(FW_FEATURE_OPALv3)) + return; + + if (secondary) { + /* Return secondary CPUs to firmware on OPAL v3 */ mb(); get_paca()->kexec_state = KEXEC_STATE_REAL_MODE; mb(); /* Return the CPU to OPAL */ opal_return_cpu(); + } else if (crash_shutdown) { + /* + * On crash, we don't wait for secondaries to go + * down as they might be unreachable or hung, so + * instead we just wait a bit and move on. + */ + mdelay(1); + } else { + /* Primary waits for the secondaries to have reached OPAL */ + pnv_kexec_wait_secondaries_down(); } } #endif /* CONFIG_KEXEC */ -- GitLab From cc146d1db0673396429ce4f906350d684ef4ca2a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 24 Apr 2014 07:25:34 +1000 Subject: [PATCH 706/797] powerpc/powernv: Fix little endian issues in OPAL flash code With this patch I was able to update firmware on an LE kernel. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal-flash.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index 714ef972406b..a968fd1888b3 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c @@ -131,11 +131,15 @@ static DEFINE_MUTEX(image_data_mutex); */ static inline void opal_flash_validate(void) { - struct validate_flash_t *args_buf = &validate_flash_data; + long ret; + void *buf = validate_flash_data.buf; + __be32 size, result; + + ret = opal_validate_flash(__pa(buf), &size, &result); - args_buf->status = opal_validate_flash(__pa(args_buf->buf), - &(args_buf->buf_size), - &(args_buf->result)); + validate_flash_data.status = ret; + validate_flash_data.buf_size = be32_to_cpu(size); + validate_flash_data.result = be32_to_cpu(result); } /* -- GitLab From 3f28c5af3964c11e61e9a58df77cae5ebdb8209e Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Wed, 23 Apr 2014 10:26:32 +0800 Subject: [PATCH 707/797] powerpc/powernv: Reduce multi-hit of iommu_add_device() During the EEH hotplug event, iommu_add_device() will be invoked three times and two of them will trigger warning or error. The three times to invoke the iommu_add_device() are: pci_device_add ... set_iommu_table_base_and_group <- 1st time, fail device_add ... tce_iommu_bus_notifier <- 2nd time, succees pcibios_add_pci_devices ... pcibios_setup_bus_devices <- 3rd time, re-attach The first time fails, since the dev->kobj->sd is not initialized. The dev->kobj->sd is initialized in device_add(). The third time's warning is triggered by the re-attach of the iommu_group. After applying this patch, the error iommu_tce: 0003:05:00.0 has not been added, ret=-14 and the warning [ 204.123609] ------------[ cut here ]------------ [ 204.123645] WARNING: at arch/powerpc/kernel/iommu.c:1125 [ 204.123680] Modules linked in: xt_CHECKSUM nf_conntrack_netbios_ns nf_conntrack_broadcast ipt_MASQUERADE ip6t_REJECT bnep bluetooth 6lowpan_iphc rfkill xt_conntrack ebtable_nat ebtable_broute bridge stp llc mlx4_ib ib_sa ib_mad ib_core ib_addr ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw bnx2x tg3 mlx4_core nfsd ptp mdio ses libcrc32c nfs_acl enclosure be2net pps_core shpchp lockd kvm uinput sunrpc binfmt_misc lpfc scsi_transport_fc ipr scsi_tgt [ 204.124356] CPU: 18 PID: 650 Comm: eehd Not tainted 3.14.0-rc5yw+ #102 [ 204.124400] task: c0000027ed485670 ti: c0000027ed50c000 task.ti: c0000027ed50c000 [ 204.124453] NIP: c00000000003cf80 LR: c00000000006c648 CTR: c00000000006c5c0 [ 204.124506] REGS: c0000027ed50f440 TRAP: 0700 Not tainted (3.14.0-rc5yw+) [ 204.124558] MSR: 9000000000029032 CR: 88008084 XER: 20000000 [ 204.124682] CFAR: c00000000006c644 SOFTE: 1 GPR00: c00000000006c648 c0000027ed50f6c0 c000000001398380 c0000027ec260300 GPR04: c0000027ea92c000 c00000000006ad00 c0000000016e41b0 0000000000000110 GPR08: c0000000012cd4c0 0000000000000001 c0000027ec2602ff 0000000000000062 GPR12: 0000000028008084 c00000000fdca200 c0000000000d1d90 c0000027ec281a80 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000001 GPR24: 000000005342697b 0000000000002906 c000001fe6ac9800 c000001fe6ac9800 GPR28: 0000000000000000 c0000000016e3a80 c0000027ea92c090 c0000027ea92c000 [ 204.125353] NIP [c00000000003cf80] .iommu_add_device+0x30/0x1f0 [ 204.125399] LR [c00000000006c648] .pnv_pci_ioda_dma_dev_setup+0x88/0xb0 [ 204.125443] Call Trace: [ 204.125464] [c0000027ed50f6c0] [c0000027ed50f750] 0xc0000027ed50f750 (unreliable) [ 204.125526] [c0000027ed50f750] [c00000000006c648] .pnv_pci_ioda_dma_dev_setup+0x88/0xb0 [ 204.125588] [c0000027ed50f7d0] [c000000000069cc8] .pnv_pci_dma_dev_setup+0x78/0x340 [ 204.125650] [c0000027ed50f870] [c000000000044408] .pcibios_setup_device+0x88/0x2f0 [ 204.125712] [c0000027ed50f940] [c000000000046040] .pcibios_setup_bus_devices+0x60/0xd0 [ 204.125774] [c0000027ed50f9c0] [c000000000043acc] .pcibios_add_pci_devices+0xdc/0x1c0 [ 204.125837] [c0000027ed50fa50] [c00000000086f970] .eeh_reset_device+0x36c/0x4f0 [ 204.125939] [c0000027ed50fb20] [c00000000003a2d8] .eeh_handle_normal_event+0x448/0x480 [ 204.126068] [c0000027ed50fbc0] [c00000000003a35c] .eeh_handle_event+0x4c/0x340 [ 204.126192] [c0000027ed50fc80] [c00000000003a74c] .eeh_event_handler+0xfc/0x1b0 [ 204.126319] [c0000027ed50fd30] [c0000000000d1ea0] .kthread+0x110/0x130 [ 204.126430] [c0000027ed50fe30] [c00000000000a460] .ret_from_kernel_thread+0x5c/0x7c [ 204.126556] Instruction dump: [ 204.126610] 7c0802a6 fba1ffe8 fbc1fff0 fbe1fff8 f8010010 f821ff71 7c7e1b78 60000000 [ 204.126787] 60000000 e87e0298 3143ffff 7d2a1910 <0b090000> 2fa90000 40de00c8 ebfe0218 [ 204.126966] ---[ end trace 6e7aefd80add2973 ]--- are cleared. This patch removes iommu_add_device() in pnv_pci_ioda_dma_dev_setup(), which revert part of the change in commit d905c5df(PPC: POWERNV: move iommu_add_device earlier). Signed-off-by: Wei Yang Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/pci-ioda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3b2b4fb3585b..1d992f137c48 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -462,7 +462,7 @@ static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev pe = &phb->ioda.pe_array[pdn->pe_number]; WARN_ON(get_dma_ops(&pdev->dev) != &dma_iommu_ops); - set_iommu_table_base_and_group(&pdev->dev, &pe->tce32_table); + set_iommu_table_base(&pdev->dev, &pe->tce32_table); } static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb, -- GitLab From 4966bfa1b3347ee75e6d93859a2e8ce9a662390c Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Wed, 23 Apr 2014 10:26:33 +0800 Subject: [PATCH 708/797] powerpc/powernv: Release the refcount for pci_dev On PowerNV platform, we are holding an unnecessary refcount on a pci_dev, which leads to the pci_dev is not destroyed when hotplugging a pci device. This patch release the unnecessary refcount. Signed-off-by: Wei Yang Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/pci-ioda.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 1d992f137c48..98824aa99173 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -343,7 +343,6 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) pci_name(dev)); continue; } - pci_dev_get(dev); pdn->pcidev = dev; pdn->pe_number = pe->pe_number; pe->dma_weight += pnv_ioda_dma_weight(dev); -- GitLab From 2bad742388d23c15f2cb355bb992046e30065a11 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 22 Apr 2014 15:01:22 +1000 Subject: [PATCH 709/797] powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs Using size_t in our APIs is asking for trouble, especially when some OPAL calls use size_t pointers. Signed-off-by: Anton Blanchard Reviewed-by: Stewart Smith Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 12 ++++++------ arch/powerpc/platforms/powernv/opal-elog.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a2efdaa020b0..2a34485f7e0a 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -858,8 +858,8 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type, int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, uint32_t addr, __be32 *data, uint32_t sz); -int64_t opal_read_elog(uint64_t buffer, size_t size, uint64_t log_id); -int64_t opal_get_elog_size(uint64_t *log_id, size_t *size, uint64_t *elog_type); +int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id); +int64_t opal_get_elog_size(uint64_t *log_id, uint64_t *size, uint64_t *elog_type); int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_send_ack_elog(uint64_t log_id); void opal_resend_pending_logs(void); @@ -874,13 +874,13 @@ int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer); int64_t opal_dump_ack(uint32_t dump_id); int64_t opal_dump_resend_notification(void); -int64_t opal_get_msg(uint64_t buffer, size_t size); -int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token); +int64_t opal_get_msg(uint64_t buffer, uint64_t size); +int64_t opal_check_completion(uint64_t buffer, uint64_t size, uint64_t token); int64_t opal_sync_host_reboot(void); int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer, - size_t length); + uint64_t length); int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, - size_t length); + uint64_t length); int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); /* Internal functions */ diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index ef7bc2a97862..7e3821e611a8 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -238,7 +238,7 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) static void elog_work_fn(struct work_struct *work) { - size_t elog_size; + uint64_t elog_size; uint64_t log_id; uint64_t elog_type; int rc; -- GitLab From e2c8b93e65935498d9bd419cec900221ace70c5b Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 22 Apr 2014 15:01:23 +1000 Subject: [PATCH 710/797] powerpc/powernv: Remove some OPAL function declaration duplication We had some duplication of the internal OPAL functions. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 2a34485f7e0a..cb7d52ed86d2 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -884,7 +884,8 @@ int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); /* Internal functions */ -extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); +extern int early_init_dt_scan_opal(unsigned long node, const char *uname, + int depth, void *data); extern int early_init_dt_scan_recoverable_ranges(unsigned long node, const char *uname, int depth, void *data); @@ -893,10 +894,6 @@ extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); extern void hvc_opal_init_early(void); -/* Internal functions */ -extern int early_init_dt_scan_opal(unsigned long node, const char *uname, - int depth, void *data); - extern int opal_notifier_register(struct notifier_block *nb); extern int opal_notifier_unregister(struct notifier_block *nb); @@ -906,9 +903,6 @@ extern void opal_notifier_enable(void); extern void opal_notifier_disable(void); extern void opal_notifier_update_evt(uint64_t evt_mask, uint64_t evt_val); -extern int opal_get_chars(uint32_t vtermno, char *buf, int count); -extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len); - extern int __opal_async_get_token(void); extern int opal_async_get_token_interruptible(void); extern int __opal_async_release_token(int token); @@ -916,8 +910,6 @@ extern int opal_async_release_token(int token); extern int opal_async_wait_response(uint64_t token, struct opal_msg *msg); extern int opal_get_sensor_data(u32 sensor_hndl, u32 *sensor_data); -extern void hvc_opal_init_early(void); - struct rtc_time; extern int opal_set_rtc_time(struct rtc_time *tm); extern void opal_get_rtc_time(struct rtc_time *tm); -- GitLab From 56b4c993124d15f3b198cc757ba49a0022b5d695 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 22 Apr 2014 15:01:24 +1000 Subject: [PATCH 711/797] powerpc/powernv: Fix little endian issues with opal_do_notifier calls The bitmap in opal_poll_events and opal_handle_interrupt is big endian, so we need to byteswap it on little endian builds. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/opal.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 49d2f00019e5..17cfc70082aa 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -242,14 +242,14 @@ void opal_notifier_update_evt(uint64_t evt_mask, void opal_notifier_enable(void) { int64_t rc; - uint64_t evt = 0; + __be64 evt = 0; atomic_set(&opal_notifier_hold, 0); /* Process pending events */ rc = opal_poll_events(&evt); if (rc == OPAL_SUCCESS && evt) - opal_do_notifier(evt); + opal_do_notifier(be64_to_cpu(evt)); } void opal_notifier_disable(void) @@ -529,7 +529,7 @@ static irqreturn_t opal_interrupt(int irq, void *data) opal_handle_interrupt(virq_to_hw(irq), &events); - opal_do_notifier(events); + opal_do_notifier(be64_to_cpu(events)); return IRQ_HANDLED; } -- GitLab From 14ad0c58d5df6e5911a5413abdc2a9be6a8acb51 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 22 Apr 2014 15:01:25 +1000 Subject: [PATCH 712/797] powerpc/powernv: Fix little endian issues in OPAL error log code Fix little endian issues with the OPAL error log code. Signed-off-by: Anton Blanchard Reviewed-by: Stewart Smith Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 2 +- arch/powerpc/platforms/powernv/opal-elog.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 cb7d52ed86d2..1a752ac8c0ba 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -859,7 +859,7 @@ int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type, uint32_t addr, __be32 *data, uint32_t sz); int64_t opal_read_elog(uint64_t buffer, uint64_t size, uint64_t log_id); -int64_t opal_get_elog_size(uint64_t *log_id, uint64_t *size, uint64_t *elog_type); +int64_t opal_get_elog_size(__be64 *log_id, __be64 *size, __be64 *elog_type); int64_t opal_write_elog(uint64_t buffer, uint64_t size, uint64_t offset); int64_t opal_send_ack_elog(uint64_t log_id); void opal_resend_pending_logs(void); diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index 7e3821e611a8..10268c41d830 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -238,18 +238,25 @@ static struct elog_obj *create_elog_obj(uint64_t id, size_t size, uint64_t type) static void elog_work_fn(struct work_struct *work) { + __be64 size; + __be64 id; + __be64 type; uint64_t elog_size; uint64_t log_id; uint64_t elog_type; int rc; char name[2+16+1]; - rc = opal_get_elog_size(&log_id, &elog_size, &elog_type); + rc = opal_get_elog_size(&id, &size, &type); if (rc != OPAL_SUCCESS) { pr_err("ELOG: Opal log read failed\n"); return; } + elog_size = be64_to_cpu(size); + log_id = be64_to_cpu(id); + elog_type = be64_to_cpu(type); + BUG_ON(elog_size > OPAL_MAX_ERRLOG_SIZE); if (elog_size >= OPAL_MAX_ERRLOG_SIZE) -- GitLab From 3441f04b4b62758a798f9fbbf2047dfedf0329a5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 22 Apr 2014 15:01:26 +1000 Subject: [PATCH 713/797] powerpc/powernv: Create OPAL sglist helper functions and fix endian issues We have two copies of code that creates an OPAL sg list. Consolidate these into a common set of helpers and fix the endian issues. The flash interface embedded a version number in the num_entries field, whereas the dump interface did did not. Since versioning wasn't added to the flash interface and it is impossible to add this in a backwards compatible way, just remove it. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 14 ++- arch/powerpc/platforms/powernv/opal-dump.c | 81 +-------------- arch/powerpc/platforms/powernv/opal-flash.c | 106 +------------------- arch/powerpc/platforms/powernv/opal.c | 63 ++++++++++++ 4 files changed, 76 insertions(+), 188 deletions(-) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 1a752ac8c0ba..afb0fedd1214 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -41,14 +41,14 @@ struct opal_takeover_args { * size except the last one in the list to be as well. */ struct opal_sg_entry { - void *data; - long length; + __be64 data; + __be64 length; }; -/* sg list */ +/* SG list */ struct opal_sg_list { - unsigned long num_entries; - struct opal_sg_list *next; + __be64 length; + __be64 next; struct opal_sg_entry entry[]; }; @@ -929,6 +929,10 @@ extern int opal_resync_timebase(void); extern void opal_lpc_init(void); +struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, + unsigned long vmalloc_size); +void opal_free_sg_list(struct opal_sg_list *sg); + #endif /* __ASSEMBLY__ */ #endif /* __OPAL_H */ diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index b9827b0d87e4..f0b472427c57 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c @@ -209,80 +209,6 @@ static struct kobj_type dump_ktype = { .default_attrs = dump_default_attrs, }; -static void free_dump_sg_list(struct opal_sg_list *list) -{ - struct opal_sg_list *sg1; - while (list) { - sg1 = list->next; - kfree(list); - list = sg1; - } - list = NULL; -} - -static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump) -{ - struct opal_sg_list *sg1, *list = NULL; - void *addr; - int64_t size; - - addr = dump->buffer; - size = dump->size; - - sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!sg1) - goto nomem; - - list = sg1; - sg1->num_entries = 0; - while (size > 0) { - /* Translate virtual address to physical address */ - sg1->entry[sg1->num_entries].data = - (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); - - if (size > PAGE_SIZE) - sg1->entry[sg1->num_entries].length = PAGE_SIZE; - else - sg1->entry[sg1->num_entries].length = size; - - sg1->num_entries++; - if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { - sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!sg1->next) - goto nomem; - - sg1 = sg1->next; - sg1->num_entries = 0; - } - addr += PAGE_SIZE; - size -= PAGE_SIZE; - } - return list; - -nomem: - pr_err("%s : Failed to allocate memory\n", __func__); - free_dump_sg_list(list); - return NULL; -} - -static void sglist_to_phy_addr(struct opal_sg_list *list) -{ - struct opal_sg_list *sg, *next; - - for (sg = list; sg; sg = next) { - next = sg->next; - /* Don't translate NULL pointer for last entry */ - if (sg->next) - sg->next = (struct opal_sg_list *)__pa(sg->next); - else - sg->next = NULL; - - /* Convert num_entries to length */ - sg->num_entries = - sg->num_entries * sizeof(struct opal_sg_entry) + 16; - } -} - static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type) { int rc; @@ -314,15 +240,12 @@ static int64_t dump_read_data(struct dump_obj *dump) } /* Generate SG list */ - list = dump_data_to_sglist(dump); + list = opal_vmalloc_to_sg_list(dump->buffer, dump->size); if (!list) { rc = -ENOMEM; goto out; } - /* Translate sg list addr to real address */ - sglist_to_phy_addr(list); - /* First entry address */ addr = __pa(list); @@ -341,7 +264,7 @@ static int64_t dump_read_data(struct dump_obj *dump) __func__, dump->id); /* Free SG list */ - free_dump_sg_list(list); + opal_free_sg_list(list); out: return rc; diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c index a968fd1888b3..dc487ff04704 100644 --- a/arch/powerpc/platforms/powernv/opal-flash.c +++ b/arch/powerpc/platforms/powernv/opal-flash.c @@ -79,9 +79,6 @@ /* XXX: Assume candidate image size is <= 1GB */ #define MAX_IMAGE_SIZE 0x40000000 -/* Flash sg list version */ -#define SG_LIST_VERSION (1UL) - /* Image status */ enum { IMAGE_INVALID, @@ -271,94 +268,12 @@ static ssize_t manage_store(struct kobject *kobj, return count; } -/* - * Free sg list - */ -static void free_sg_list(struct opal_sg_list *list) -{ - struct opal_sg_list *sg1; - while (list) { - sg1 = list->next; - kfree(list); - list = sg1; - } - list = NULL; -} - -/* - * Build candidate image scatter gather list - * - * list format: - * ----------------------------------- - * | VER (8) | Entry length in bytes | - * ----------------------------------- - * | Pointer to next entry | - * ----------------------------------- - * | Address of memory area 1 | - * ----------------------------------- - * | Length of memory area 1 | - * ----------------------------------- - * | ......... | - * ----------------------------------- - * | ......... | - * ----------------------------------- - * | Address of memory area N | - * ----------------------------------- - * | Length of memory area N | - * ----------------------------------- - */ -static struct opal_sg_list *image_data_to_sglist(void) -{ - struct opal_sg_list *sg1, *list = NULL; - void *addr; - int size; - - addr = image_data.data; - size = image_data.size; - - sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!sg1) - return NULL; - - list = sg1; - sg1->num_entries = 0; - while (size > 0) { - /* Translate virtual address to physical address */ - sg1->entry[sg1->num_entries].data = - (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT); - - if (size > PAGE_SIZE) - sg1->entry[sg1->num_entries].length = PAGE_SIZE; - else - sg1->entry[sg1->num_entries].length = size; - - sg1->num_entries++; - if (sg1->num_entries >= SG_ENTRIES_PER_NODE) { - sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!sg1->next) { - pr_err("%s : Failed to allocate memory\n", - __func__); - goto nomem; - } - - sg1 = sg1->next; - sg1->num_entries = 0; - } - addr += PAGE_SIZE; - size -= PAGE_SIZE; - } - return list; -nomem: - free_sg_list(list); - return NULL; -} - /* * OPAL update flash */ static int opal_flash_update(int op) { - struct opal_sg_list *sg, *list, *next; + struct opal_sg_list *list; unsigned long addr; int64_t rc = OPAL_PARAMETER; @@ -368,30 +283,13 @@ static int opal_flash_update(int op) goto flash; } - list = image_data_to_sglist(); + list = opal_vmalloc_to_sg_list(image_data.data, image_data.size); if (!list) goto invalid_img; /* First entry address */ addr = __pa(list); - /* Translate sg list address to absolute */ - for (sg = list; sg; sg = next) { - next = sg->next; - /* Don't translate NULL pointer for last entry */ - if (sg->next) - sg->next = (struct opal_sg_list *)__pa(sg->next); - else - sg->next = NULL; - - /* - * Convert num_entries to version/length format - * to satisfy OPAL. - */ - sg->num_entries = (SG_LIST_VERSION << 56) | - (sg->num_entries * sizeof(struct opal_sg_entry) + 16); - } - pr_alert("FLASH: Image is %u bytes\n", image_data.size); pr_alert("FLASH: Image update requested\n"); pr_alert("FLASH: Image will be updated during system reboot\n"); diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 17cfc70082aa..360ad80c754c 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -638,3 +638,66 @@ void opal_shutdown(void) /* Export this so that test modules can use it */ EXPORT_SYMBOL_GPL(opal_invalid_call); + +/* Convert a region of vmalloc memory to an opal sg list */ +struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, + unsigned long vmalloc_size) +{ + struct opal_sg_list *sg, *first = NULL; + unsigned long i = 0; + + sg = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!sg) + goto nomem; + + first = sg; + + while (vmalloc_size > 0) { + uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT; + uint64_t length = min(vmalloc_size, PAGE_SIZE); + + sg->entry[i].data = cpu_to_be64(data); + sg->entry[i].length = cpu_to_be64(length); + i++; + + if (i >= SG_ENTRIES_PER_NODE) { + struct opal_sg_list *next; + + next = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!next) + goto nomem; + + sg->length = cpu_to_be64( + i * sizeof(struct opal_sg_entry) + 16); + i = 0; + sg->next = cpu_to_be64(__pa(next)); + sg = next; + } + + vmalloc_addr += length; + vmalloc_size -= length; + } + + sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16); + + return first; + +nomem: + pr_err("%s : Failed to allocate memory\n", __func__); + opal_free_sg_list(first); + return NULL; +} + +void opal_free_sg_list(struct opal_sg_list *sg) +{ + while (sg) { + uint64_t next = be64_to_cpu(sg->next); + + kfree(sg); + + if (next) + sg = __va(next); + else + sg = NULL; + } +} -- GitLab From 2d6b63bbdd7a649ea17fae19f8bab07d4b292a09 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 22 Apr 2014 15:01:27 +1000 Subject: [PATCH 714/797] powerpc/powernv: Fix little endian issues in OPAL dump code Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 4 ++-- arch/powerpc/platforms/powernv/opal-dump.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index afb0fedd1214..66ad7a74116f 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -868,8 +868,8 @@ int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result); int64_t opal_manage_flash(uint8_t op); int64_t opal_update_flash(uint64_t blk_list); int64_t opal_dump_init(uint8_t dump_type); -int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size); -int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type); +int64_t opal_dump_info(__be32 *dump_id, __be32 *dump_size); +int64_t opal_dump_info2(__be32 *dump_id, __be32 *dump_size, __be32 *dump_type); int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer); int64_t opal_dump_ack(uint32_t dump_id); int64_t opal_dump_resend_notification(void); diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index f0b472427c57..788a1977b9a5 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c @@ -209,15 +209,20 @@ static struct kobj_type dump_ktype = { .default_attrs = dump_default_attrs, }; -static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type) +static int64_t dump_read_info(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type) { + __be32 id, size, type; int rc; - *type = 0xffffffff; - rc = opal_dump_info2(id, size, type); + type = cpu_to_be32(0xffffffff); + rc = opal_dump_info2(&id, &size, &type); if (rc == OPAL_PARAMETER) - rc = opal_dump_info(id, size); + rc = opal_dump_info(&id, &size); + + *dump_id = be32_to_cpu(id); + *dump_size = be32_to_cpu(size); + *dump_type = be32_to_cpu(type); if (rc) pr_warn("%s: Failed to get dump info (%d)\n", -- GitLab From 29ef7a3e26283606f181000b11e5fd37d73ab98f Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 21 Apr 2014 10:37:36 +0530 Subject: [PATCH 715/797] powerpc/mm: Fix tlbie to add AVAL fields for 64K pages The if condition check was based on a draft ISA doc. Remove the same. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/hash_native_64.c | 38 ++++++++++++++------------------ 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c index 3ea26c25590b..cf1d325eae8b 100644 --- a/arch/powerpc/mm/hash_native_64.c +++ b/arch/powerpc/mm/hash_native_64.c @@ -82,17 +82,14 @@ static inline void __tlbie(unsigned long vpn, int psize, int apsize, int ssize) va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); va |= penc << 12; va |= ssize << 8; - /* Add AVAL part */ - if (psize != apsize) { - /* - * MPSS, 64K base page size and 16MB parge page size - * We don't need all the bits, but rest of the bits - * must be ignored by the processor. - * vpn cover upto 65 bits of va. (0...65) and we need - * 58..64 bits of va. - */ - va |= (vpn & 0xfe); - } + /* + * AVAL bits: + * We don't need all the bits, but rest of the bits + * must be ignored by the processor. + * vpn cover upto 65 bits of va. (0...65) and we need + * 58..64 bits of va. + */ + va |= (vpn & 0xfe); /* AVAL */ va |= 1; /* L */ asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2) : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) @@ -133,17 +130,14 @@ static inline void __tlbiel(unsigned long vpn, int psize, int apsize, int ssize) va &= ~((1ul << mmu_psize_defs[apsize].shift) - 1); va |= penc << 12; va |= ssize << 8; - /* Add AVAL part */ - if (psize != apsize) { - /* - * MPSS, 64K base page size and 16MB parge page size - * We don't need all the bits, but rest of the bits - * must be ignored by the processor. - * vpn cover upto 65 bits of va. (0...65) and we need - * 58..64 bits of va. - */ - va |= (vpn & 0xfe); - } + /* + * AVAL bits: + * We don't need all the bits, but rest of the bits + * must be ignored by the processor. + * vpn cover upto 65 bits of va. (0...65) and we need + * 58..64 bits of va. + */ + va |= (vpn & 0xfe); va |= 1; /* L */ asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)" : : "r"(va) : "memory"); -- GitLab From e98bf005d5feafb3a089868420c1f3743d304e14 Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Tue, 15 Apr 2014 10:10:50 -0700 Subject: [PATCH 716/797] powerpc/perf/hv_24x7: Probe errors changed to pr_debug(), padding fixed fixup for "powerpc/perf: Add support for the hv 24x7 interface" Makes the "not enabled" message less awful (and hides it in most cases). Signed-off-by: Cody P Schafer Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/hv-24x7.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 297c91051413..f5bca73d92b8 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -485,13 +485,13 @@ static int hv_24x7_init(void) struct hv_perf_caps caps; if (!firmware_has_feature(FW_FEATURE_LPAR)) { - pr_info("not a virtualized system, not enabling\n"); + pr_debug("not a virtualized system, not enabling\n"); return -ENODEV; } hret = hv_perf_caps_get(&caps); if (hret) { - pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n", + pr_debug("could not obtain capabilities, not enabling, rc=%ld\n", hret); return -ENODEV; } -- GitLab From 0a8cf9e28c094cd934deaedfd3ec07830f2a63cf Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Tue, 15 Apr 2014 10:10:51 -0700 Subject: [PATCH 717/797] powerpc/perf/hv_gpci: Probe failures use pr_debug(), and padding reduced fixup for "powerpc/perf: Add support for the hv gpci (get performance counter info) interface". Makes the "not enabled" message less awful (and hidden unless debugging). Signed-off-by: Cody P Schafer Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/hv-gpci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 278ba7b9c2b5..8fee1dccaaec 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -273,13 +273,13 @@ static int hv_gpci_init(void) struct hv_perf_caps caps; if (!firmware_has_feature(FW_FEATURE_LPAR)) { - pr_info("not a virtualized system, not enabling\n"); + pr_debug("not a virtualized system, not enabling\n"); return -ENODEV; } hret = hv_perf_caps_get(&caps); if (hret) { - pr_info("could not obtain capabilities, error 0x%80lx, not enabling\n", + pr_debug("could not obtain capabilities, not enabling, rc=%ld\n", hret); return -ENODEV; } -- GitLab From 58a685c2d8f0616b5c6cfa0f7a9f2d081af3c6fd Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Tue, 15 Apr 2014 10:10:52 -0700 Subject: [PATCH 718/797] powerpc/perf/hv-gpci: Make device attr static Signed-off-by: Cody P Schafer Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/hv-gpci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 8fee1dccaaec..c9d399a2df82 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -78,7 +78,7 @@ static ssize_t kernel_version_show(struct device *dev, return sprintf(page, "0x%x\n", COUNTER_INFO_VERSION_CURRENT); } -DEVICE_ATTR_RO(kernel_version); +static DEVICE_ATTR_RO(kernel_version); HV_CAPS_ATTR(version, "0x%x\n"); HV_CAPS_ATTR(ga, "%d\n"); HV_CAPS_ATTR(expanded, "%d\n"); -- GitLab From 78d13166b189ff1741327d748a7f8d73e65d70bd Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Tue, 15 Apr 2014 10:10:53 -0700 Subject: [PATCH 719/797] powerpc/perf/hv-24x7: Use (unsigned long) not (u32) values when calling plpar_hcall_norets() Signed-off-by: Cody P Schafer Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/hv-24x7.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index f5bca73d92b8..3e8f60a1d53f 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -155,16 +155,28 @@ static ssize_t read_offset_data(void *dest, size_t dest_len, return copy_len; } -static unsigned long h_get_24x7_catalog_page(char page[static 4096], - u32 version, u32 index) +static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096, + unsigned long version, + unsigned long index) { - WARN_ON(!IS_ALIGNED((unsigned long)page, 4096)); + pr_devel("h_get_24x7_catalog_page(0x%lx, %lu, %lu)", + phys_4096, + version, + index); + WARN_ON(!IS_ALIGNED(phys_4096, 4096)); return plpar_hcall_norets(H_GET_24X7_CATALOG_PAGE, - virt_to_phys(page), + phys_4096, version, index); } +static unsigned long h_get_24x7_catalog_page(char page[static 4096], + u32 version, u32 index) +{ + return h_get_24x7_catalog_page_(virt_to_phys(page), + version, index); +} + static ssize_t catalog_read(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t offset, size_t count) -- GitLab From 1ee9fcc1a021e54454a23b107a47d10fb603508c Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Tue, 15 Apr 2014 10:10:54 -0700 Subject: [PATCH 720/797] powerpc/perf/hv-24x7: Remove [static 4096], sparse chokes on it Signed-off-by: Cody P Schafer Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/hv-24x7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 3e8f60a1d53f..95a67f81f22a 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -170,7 +170,7 @@ static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096, index); } -static unsigned long h_get_24x7_catalog_page(char page[static 4096], +static unsigned long h_get_24x7_catalog_page(char page[], u32 version, u32 index) { return h_get_24x7_catalog_page_(virt_to_phys(page), -- GitLab From bbad3e50e8ed2d48294c141e687d411430cacbcf Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Tue, 15 Apr 2014 10:10:55 -0700 Subject: [PATCH 721/797] powerpc/perf/hv-24x7: Catalog version number is be64, not be32 The catalog version number was changed from a be32 (with proceeding 32bits of padding) to a be64, update the code to treat it as a be64 Signed-off-by: Cody P Schafer Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/hv-24x7.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index 95a67f81f22a..e0766b82e165 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -171,7 +171,7 @@ static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096, } static unsigned long h_get_24x7_catalog_page(char page[], - u32 version, u32 index) + u64 version, u32 index) { return h_get_24x7_catalog_page_(virt_to_phys(page), version, index); @@ -185,7 +185,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, ssize_t ret = 0; size_t catalog_len = 0, catalog_page_len = 0, page_count = 0; loff_t page_offset = 0; - uint32_t catalog_version_num = 0; + uint64_t catalog_version_num = 0; void *page = kmem_cache_alloc(hv_page_cache, GFP_USER); struct hv_24x7_catalog_page_0 *page_0 = page; if (!page) @@ -197,7 +197,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, goto e_free; } - catalog_version_num = be32_to_cpu(page_0->version); + catalog_version_num = be64_to_cpu(page_0->version); catalog_page_len = be32_to_cpu(page_0->length); catalog_len = catalog_page_len * 4096; @@ -220,8 +220,9 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj, page, 4096, page_offset * 4096); e_free: if (hret) - pr_err("h_get_24x7_catalog_page(ver=%d, page=%lld) failed: rc=%ld\n", - catalog_version_num, page_offset, hret); + pr_err("h_get_24x7_catalog_page(ver=%lld, page=%lld) failed:" + " rc=%ld\n", + catalog_version_num, page_offset, hret); kfree(page); pr_devel("catalog_read: offset=%lld(%lld) count=%zu(%zu) catalog_len=%zu(%zu) => %zd\n", @@ -255,7 +256,7 @@ e_free: \ static DEVICE_ATTR_RO(_name) PAGE_0_ATTR(catalog_version, "%lld\n", - (unsigned long long)be32_to_cpu(page_0->version)); + (unsigned long long)be64_to_cpu(page_0->version)); PAGE_0_ATTR(catalog_len, "%lld\n", (unsigned long long)be32_to_cpu(page_0->length) * 4096); static BIN_ATTR_RO(catalog, 0/* real length varies */); -- GitLab From a2dd5da77f2cc9fc9ff11ea6b699556254e94a6c Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 14 Apr 2014 21:54:05 +1000 Subject: [PATCH 722/797] powerpc: Rename duplicate COMMAND_LINE_SIZE define We have two definitions of COMMAND_LINE_SIZE, one for the kernel and one for the boot wrapper. I assume this is so the boot wrapper can be self sufficient and not rely on kernel headers. Having two defines with the same name is confusing, I just updated the wrong one when trying to bump it. Make the boot wrapper define unique by calling it BOOT_COMMAND_LINE_SIZE. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/main.c | 8 ++++---- arch/powerpc/boot/ops.h | 2 +- arch/powerpc/boot/ps3.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c index a28f02165e97..d367a0aece2a 100644 --- a/arch/powerpc/boot/main.c +++ b/arch/powerpc/boot/main.c @@ -139,18 +139,18 @@ static struct addr_range prep_initrd(struct addr_range vmlinux, void *chosen, * edit the command line passed to vmlinux (by setting /chosen/bootargs). * The buffer is put in it's own section so that tools may locate it easier. */ -static char cmdline[COMMAND_LINE_SIZE] +static char cmdline[BOOT_COMMAND_LINE_SIZE] __attribute__((__section__("__builtin_cmdline"))); static void prep_cmdline(void *chosen) { if (cmdline[0] == '\0') - getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); + getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); printf("\n\rLinux/PowerPC load: %s", cmdline); /* If possible, edit the command line */ if (console_ops.edit_cmdline) - console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE); + console_ops.edit_cmdline(cmdline, BOOT_COMMAND_LINE_SIZE); printf("\n\r"); /* Put the command line back into the devtree for the kernel */ @@ -174,7 +174,7 @@ void start(void) * built-in command line wasn't set by an external tool */ if ((loader_info.cmdline_len > 0) && (cmdline[0] == '\0')) memmove(cmdline, loader_info.cmdline, - min(loader_info.cmdline_len, COMMAND_LINE_SIZE-1)); + min(loader_info.cmdline_len, BOOT_COMMAND_LINE_SIZE-1)); if (console_ops.open && (console_ops.open() < 0)) exit(); diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index b3218ce451bb..339e041e8dda 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -15,7 +15,7 @@ #include "types.h" #include "string.h" -#define COMMAND_LINE_SIZE 512 +#define BOOT_COMMAND_LINE_SIZE 512 #define MAX_PATH_LEN 256 #define MAX_PROP_LEN 256 /* What should this be? */ diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c index 9954d98871d0..4ec2d86d3c50 100644 --- a/arch/powerpc/boot/ps3.c +++ b/arch/powerpc/boot/ps3.c @@ -47,13 +47,13 @@ BSS_STACK(4096); * The buffer is put in it's own section so that tools may locate it easier. */ -static char cmdline[COMMAND_LINE_SIZE] +static char cmdline[BOOT_COMMAND_LINE_SIZE] __attribute__((__section__("__builtin_cmdline"))); static void prep_cmdline(void *chosen) { if (cmdline[0] == '\0') - getprop(chosen, "bootargs", cmdline, COMMAND_LINE_SIZE-1); + getprop(chosen, "bootargs", cmdline, BOOT_COMMAND_LINE_SIZE-1); else setprop_str(chosen, "bootargs", cmdline); -- GitLab From a5980d064fe292584da73ddd180f4f140f9ab97d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 14 Apr 2014 21:54:52 +1000 Subject: [PATCH 723/797] powerpc: Bump COMMAND_LINE_SIZE to 2048 I've had a report that the current limit is too small for an automated network based installer. Bump it. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/uapi/asm/setup.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/uapi/asm/setup.h b/arch/powerpc/include/uapi/asm/setup.h index 552df83f1a49..ae3fb68cb28e 100644 --- a/arch/powerpc/include/uapi/asm/setup.h +++ b/arch/powerpc/include/uapi/asm/setup.h @@ -1 +1,6 @@ -#include +#ifndef _UAPI_ASM_POWERPC_SETUP_H +#define _UAPI_ASM_POWERPC_SETUP_H + +#define COMMAND_LINE_SIZE 2048 + +#endif /* _UAPI_ASM_POWERPC_SETUP_H */ -- GitLab From 579a53cafdd641f2d67ba4f4fbd9cc4180b8717d Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 14 Apr 2014 21:55:25 +1000 Subject: [PATCH 724/797] powerpc: Bump BOOT_COMMAND_LINE_SIZE to 2048 Bump the boot wrapper BOOT_COMMAND_LINE_SIZE to match the kernel. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/boot/ops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 339e041e8dda..8aad3c55aeda 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h @@ -15,7 +15,7 @@ #include "types.h" #include "string.h" -#define BOOT_COMMAND_LINE_SIZE 512 +#define BOOT_COMMAND_LINE_SIZE 2048 #define MAX_PATH_LEN 256 #define MAX_PROP_LEN 256 /* What should this be? */ -- GitLab From 0c930692107be4b91c3eeecfd9c9d600039f966f Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 14 Apr 2014 21:23:32 +1000 Subject: [PATCH 725/797] powerpc: Fix error return in rtas_flash module init module_init should return 0 or a negative errno. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/rtas_flash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 2f3cdb01506d..658e89d2025b 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -705,7 +705,7 @@ static int __init rtas_flash_init(void) if (rtas_token("ibm,update-flash-64-and-reboot") == RTAS_UNKNOWN_SERVICE) { pr_info("rtas_flash: no firmware flash support\n"); - return 1; + return -EINVAL; } rtas_validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL); -- GitLab From 42dbfc8649737cb622b2a7e02045401c4c09561c Mon Sep 17 00:00:00 2001 From: Li Zhong Date: Thu, 10 Apr 2014 16:25:31 +0800 Subject: [PATCH 726/797] powerpc/pseries: Protect remove_memory() with device hotplug lock While testing memory hot-remove, I found following dead lock: Process #1141 is drmgr, trying to remove some memory, i.e. memory499. It holds the memory_hotplug_mutex, and blocks when trying to remove file "online" under dir memory499, in kernfs_drain(), at wait_event(root->deactivate_waitq, atomic_read(&kn->active) == KN_DEACTIVATED_BIAS); Process #1120 is trying to online memory499 by echo 1 > memory499/online In .kernfs_fop_write, it uses kernfs_get_active() to increase &kn->active, thus blocking process #1141. While itself is blocked later when trying to acquire memory_hotplug_mutex, which is held by process The backtrace of both processes are shown below: [] 0xc000000001b18600 [] .__switch_to+0x144/0x200 [] .online_pages+0x74/0x7b0 [] .memory_subsys_online+0x9c/0x150 [] .device_online+0xb8/0x120 [] .online_store+0xb4/0xc0 [] .dev_attr_store+0x64/0xa0 [] .sysfs_kf_write+0x7c/0xb0 [] .kernfs_fop_write+0x154/0x1e0 [] .vfs_write+0xe0/0x260 [] .SyS_write+0x64/0x110 [] syscall_exit+0x0/0x7c [] 0xc000000001b18600 [] .__switch_to+0x144/0x200 [] .__kernfs_remove+0x204/0x300 [] .kernfs_remove_by_name_ns+0x68/0xf0 [] .sysfs_remove_file_ns+0x38/0x60 [] .device_remove_attrs+0x54/0xc0 [] .device_del+0x158/0x250 [] .device_unregister+0x34/0xa0 [] .unregister_memory_section+0x164/0x170 [] .__remove_pages+0x108/0x4c0 [] .arch_remove_memory+0x60/0xc0 [] .remove_memory+0x8c/0xe0 [] .pseries_remove_memblock+0xd4/0x160 [] .pseries_memory_notifier+0x27c/0x290 [] .notifier_call_chain+0x8c/0x100 [] .__blocking_notifier_call_chain+0x6c/0xe0 [] .of_property_notify+0x7c/0xc0 [] .of_update_property+0x3c/0x1b0 [] .ofdt_write+0x3dc/0x740 [] .proc_reg_write+0xac/0x110 [] .vfs_write+0xe0/0x260 [] .SyS_write+0x64/0x110 [] syscall_exit+0x0/0x7c This patch uses lock_device_hotplug() to protect remove_memory() called in pseries_remove_memblock(), which is also stated before function remove_memory(): * NOTE: The caller must call lock_device_hotplug() to serialize hotplug * and online/offline operations before this call, as required by * try_offline_node(). */ void __ref remove_memory(int nid, u64 start, u64 size) With this lock held, the other process(#1120 above) trying to online the memory block will retry the system call when calling lock_device_hotplug_sysfs(), and finally find No such device error. Signed-off-by: Li Zhong Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/hotplug-memory.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 573b488fc48b..7f75c94af822 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -100,10 +100,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz start_pfn = base >> PAGE_SHIFT; - if (!pfn_valid(start_pfn)) { - memblock_remove(base, memblock_size); - return 0; - } + lock_device_hotplug(); + + if (!pfn_valid(start_pfn)) + goto out; block_sz = memory_block_size_bytes(); sections_per_block = block_sz / MIN_MEMORY_BLOCK_SIZE; @@ -114,8 +114,10 @@ static int pseries_remove_memblock(unsigned long base, unsigned int memblock_siz base += MIN_MEMORY_BLOCK_SIZE; } +out: /* Update memory regions for memory remove */ memblock_remove(base, memblock_size); + unlock_device_hotplug(); return 0; } -- GitLab From f203891117323dd31c11adcbba60452c933d604e Mon Sep 17 00:00:00 2001 From: Preeti U Murthy Date: Fri, 11 Apr 2014 16:01:48 +0530 Subject: [PATCH 727/797] ppc/powernv: Set the runlatch bits correctly for offline cpus Up until now we have been setting the runlatch bits for a busy CPU and clearing it when a CPU enters idle state. The runlatch bit has thus been consistent with the utilization of a CPU as long as the CPU is online. However when a CPU is hotplugged out the runlatch bit is not cleared. It needs to be cleared to indicate an unused CPU. Hence this patch has the runlatch bit cleared for an offline CPU just before entering an idle state and sets it immediately after it exits the idle state. Signed-off-by: Preeti U Murthy Acked-by: Paul Mackerras Reviewed-by: Srivatsa S. Bhat Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powernv/smp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c index 908672bdcea6..bf5fcd452168 100644 --- a/arch/powerpc/platforms/powernv/smp.c +++ b/arch/powerpc/platforms/powernv/smp.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "powernv.h" @@ -156,7 +157,9 @@ static void pnv_smp_cpu_kill_self(void) */ mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1); while (!generic_check_cpu_restart(cpu)) { + ppc64_runlatch_off(); power7_nap(); + ppc64_runlatch_on(); if (!generic_check_cpu_restart(cpu)) { DBG("CPU%d Unexpected exit while offline !\n", cpu); /* We may be getting an IPI, so we re-enable -- GitLab From fd17dc7b9a8d57150ee0121c4c83edbb7e26eece Mon Sep 17 00:00:00 2001 From: Preeti U Murthy Date: Fri, 11 Apr 2014 16:01:58 +0530 Subject: [PATCH 728/797] ppc/kvm: Set the runlatch bit of a CPU just before starting guest The secondary threads in the core are kept offline before launching guests in kvm on powerpc: "371fefd6f2dc4666:KVM: PPC: Allow book3s_hv guests to use SMT processor modes." Hence their runlatch bits are cleared. When the secondary threads are called in to start a guest, their runlatch bits need to be set to indicate that they are busy. The primary thread has its runlatch bit set though, but there is no harm in setting this bit once again. Hence set the runlatch bit for all threads before they start guest. Signed-off-by: Preeti U Murthy Acked-by: Paul Mackerras Reviewed-by: Srivatsa S. Bhat Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index ffbb871c2bd8..b25407533618 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -242,6 +242,12 @@ kvm_novcpu_exit: */ .globl kvm_start_guest kvm_start_guest: + + /* Set runlatch bit the minute you wake up from nap */ + mfspr r1, SPRN_CTRLF + ori r1, r1, 1 + mtspr SPRN_CTRLT, r1 + ld r2,PACATOC(r13) li r0,KVM_HWTHREAD_IN_KVM -- GitLab From 582b910edafd283dfab78f41f437a92a65ee5103 Mon Sep 17 00:00:00 2001 From: Preeti U Murthy Date: Fri, 11 Apr 2014 16:02:08 +0530 Subject: [PATCH 729/797] ppc/kvm: Clear the runlatch bit of a vcpu before napping When the guest cedes the vcpu or the vcpu has no guest to run it naps. Clear the runlatch bit of the vcpu before napping to indicate an idle cpu. Signed-off-by: Preeti U Murthy Acked-by: Paul Mackerras Reviewed-by: Srivatsa S. Bhat Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kvm/book3s_hv_rmhandlers.S | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S index b25407533618..b031f932c0cc 100644 --- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -315,6 +315,11 @@ kvm_no_guest: li r0, KVM_HWTHREAD_IN_NAP stb r0, HSTATE_HWTHREAD_STATE(r13) kvm_do_nap: + /* Clear the runlatch bit before napping */ + mfspr r2, SPRN_CTRLF + clrrdi r2, r2, 1 + mtspr SPRN_CTRLT, r2 + li r3, LPCR_PECE0 mfspr r4, SPRN_LPCR rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1 @@ -2005,8 +2010,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_206) /* * Take a nap until a decrementer or external or doobell interrupt - * occurs, with PECE1, PECE0 and PECEDP set in LPCR + * occurs, with PECE1, PECE0 and PECEDP set in LPCR. Also clear the + * runlatch bit before napping. */ + mfspr r2, SPRN_CTRLF + clrrdi r2, r2, 1 + mtspr SPRN_CTRLT, r2 + li r0,1 stb r0,HSTATE_HWTHREAD_REQ(r13) mfspr r5,SPRN_LPCR -- GitLab From e4565362c7adc31201135c4b6d649fc1bdc3bf20 Mon Sep 17 00:00:00 2001 From: Alistair Popple Date: Tue, 8 Apr 2014 14:20:19 +1000 Subject: [PATCH 730/797] powerpc/4xx: Fix section mismatch in ppc4xx_pci.c This patch fixes this section mismatch: WARNING: vmlinux.o(.text+0x1efc4): Section mismatch in reference from the function apm821xx_pciex_init_port_hw() to the function .init.text:ppc4xx_pciex_wait_on_sdr.isra.9() The function apm821xx_pciex_init_port_hw() references the function __init ppc4xx_pciex_wait_on_sdr.isra.9(). This is often because apm821xx_pciex_init_port_hw lacks a __init annotation or the annotation of ppc4xx_pciex_wait_on_sdr.isra.9 is wrong. apm821xx_pciex_init_port_hw is only referenced by a struct in __initdata, so it should be safe to add __init to apm821xx_pciex_init_port_hw. Signed-off-by: Alistair Popple Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/ppc4xx_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/sysdev/ppc4xx_pci.c b/arch/powerpc/sysdev/ppc4xx_pci.c index 64603a10b863..4914fd3f41ec 100644 --- a/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/arch/powerpc/sysdev/ppc4xx_pci.c @@ -1058,7 +1058,7 @@ static int __init apm821xx_pciex_core_init(struct device_node *np) return 1; } -static int apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) +static int __init apm821xx_pciex_init_port_hw(struct ppc4xx_pciex_port *port) { u32 val; -- GitLab From 39025ba38278f3003ee538409f7c98970620ef49 Mon Sep 17 00:00:00 2001 From: Oren Twaig Date: Mon, 28 Apr 2014 10:21:37 +0300 Subject: [PATCH 731/797] x86/vsmp: Fix irq routing Correct IRQ routing in case a vSMP box is detected but the Interrupt Routing Comply (IRC) value is set to "comply", which leads to incorrect IRQ routing. Before the patch: When a vSMP box was detected and IRC was set to "comply", users (and the kernel) couldn't effectively set the destination of the IRQs. This is because the hook inside vsmp_64.c always setup all CPUs as the IRQ destination using cpumask_setall() as the return value for IRQ allocation mask. Later, this "overrided" mask caused the kernel to set the IRQ destination to the lowest online CPU in the mask (CPU0 usually). After the patch: When the IRC is set to "comply", users (and the kernel) can control the destination of the IRQs as we will not be changing the default "apic->vector_allocation_domain". Signed-off-by: Oren Twaig Acked-by: Shai Fultheim Link: http://lkml.kernel.org/r/1398669697-2123-1-git-send-email-oren@scalemp.com [ Minor readability edits. ] Signed-off-by: Ingo Molnar --- arch/x86/kernel/vsmp_64.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index f6584a90aba3..5edc34b5b951 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c @@ -26,6 +26,9 @@ #define TOPOLOGY_REGISTER_OFFSET 0x10 +/* Flag below is initialized once during vSMP PCI initialization. */ +static int irq_routing_comply = 1; + #if defined CONFIG_PCI && defined CONFIG_PARAVIRT /* * Interrupt control on vSMPowered systems: @@ -101,6 +104,10 @@ static void __init set_vsmp_pv_ops(void) #ifdef CONFIG_SMP if (cap & ctl & BIT(8)) { ctl &= ~BIT(8); + + /* Interrupt routing set to ignore */ + irq_routing_comply = 0; + #ifdef CONFIG_PROC_FS /* Don't let users change irq affinity via procfs */ no_irq_affinity = 1; @@ -218,7 +225,9 @@ static void vsmp_apic_post_init(void) { /* need to update phys_pkg_id */ apic->phys_pkg_id = apicid_phys_pkg_id; - apic->vector_allocation_domain = fill_vector_allocation_domain; + + if (!irq_routing_comply) + apic->vector_allocation_domain = fill_vector_allocation_domain; } void __init vsmp_init(void) -- GitLab From e8e249d78e0600cb892c87992b6c8c9ea3b301ae Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Fri, 21 Feb 2014 18:05:05 +0100 Subject: [PATCH 732/797] kvm: Use pci_enable_msix_exact() instead of pci_enable_msix() As result of deprecation of MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block() all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces. Signed-off-by: Alexander Gordeev Cc: Gleb Natapov Cc: Paolo Bonzini Cc: kvm@vger.kernel.org Cc: linux-pci@vger.kernel.org Signed-off-by: Paolo Bonzini --- virt/kvm/assigned-dev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virt/kvm/assigned-dev.c b/virt/kvm/assigned-dev.c index 8db43701016f..bf06577fea51 100644 --- a/virt/kvm/assigned-dev.c +++ b/virt/kvm/assigned-dev.c @@ -395,7 +395,8 @@ static int assigned_device_enable_host_msix(struct kvm *kvm, if (dev->entries_nr == 0) return r; - r = pci_enable_msix(dev->dev, dev->host_msix_entries, dev->entries_nr); + r = pci_enable_msix_exact(dev->dev, + dev->host_msix_entries, dev->entries_nr); if (r) return r; -- GitLab From fe2b201b3be91575857227da7ef21f661bc460b1 Mon Sep 17 00:00:00 2001 From: Bandan Das Date: Mon, 21 Apr 2014 15:20:14 -0400 Subject: [PATCH 733/797] KVM: x86: Check for host supported fields in shadow vmcs We track shadow vmcs fields through two static lists, one for read only and another for r/w fields. However, with addition of new vmcs fields, not all fields may be supported on all hosts. If so, copy_vmcs12_to_shadow() trying to vmwrite on unsupported hosts will result in a vmwrite error. For example, commit 36be0b9deb23161 introduced GUEST_BNDCFGS, which is not supported by all processors. Filter out host unsupported fields before letting guests use shadow vmcs Signed-off-by: Bandan Das Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 53 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1f68c5831924..33e8c028842f 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -503,7 +503,7 @@ static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) [number##_HIGH] = VMCS12_OFFSET(name)+4 -static const unsigned long shadow_read_only_fields[] = { +static unsigned long shadow_read_only_fields[] = { /* * We do NOT shadow fields that are modified when L0 * traps and emulates any vmx instruction (e.g. VMPTRLD, @@ -526,10 +526,10 @@ static const unsigned long shadow_read_only_fields[] = { GUEST_LINEAR_ADDRESS, GUEST_PHYSICAL_ADDRESS }; -static const int max_shadow_read_only_fields = +static int max_shadow_read_only_fields = ARRAY_SIZE(shadow_read_only_fields); -static const unsigned long shadow_read_write_fields[] = { +static unsigned long shadow_read_write_fields[] = { GUEST_RIP, GUEST_RSP, GUEST_CR0, @@ -558,7 +558,7 @@ static const unsigned long shadow_read_write_fields[] = { HOST_FS_SELECTOR, HOST_GS_SELECTOR }; -static const int max_shadow_read_write_fields = +static int max_shadow_read_write_fields = ARRAY_SIZE(shadow_read_write_fields); static const unsigned short vmcs_field_to_offset_table[] = { @@ -3009,6 +3009,41 @@ static void free_kvm_area(void) } } +static void init_vmcs_shadow_fields(void) +{ + int i, j; + + /* No checks for read only fields yet */ + + for (i = j = 0; i < max_shadow_read_write_fields; i++) { + switch (shadow_read_write_fields[i]) { + case GUEST_BNDCFGS: + if (!vmx_mpx_supported()) + continue; + break; + default: + break; + } + + if (j < i) + shadow_read_write_fields[j] = + shadow_read_write_fields[i]; + j++; + } + max_shadow_read_write_fields = j; + + /* shadowed fields guest access without vmexit */ + for (i = 0; i < max_shadow_read_write_fields; i++) { + clear_bit(shadow_read_write_fields[i], + vmx_vmwrite_bitmap); + clear_bit(shadow_read_write_fields[i], + vmx_vmread_bitmap); + } + for (i = 0; i < max_shadow_read_only_fields; i++) + clear_bit(shadow_read_only_fields[i], + vmx_vmread_bitmap); +} + static __init int alloc_kvm_area(void) { int cpu; @@ -3039,6 +3074,8 @@ static __init int hardware_setup(void) enable_vpid = 0; if (!cpu_has_vmx_shadow_vmcs()) enable_shadow_vmcs = 0; + if (enable_shadow_vmcs) + init_vmcs_shadow_fields(); if (!cpu_has_vmx_ept() || !cpu_has_vmx_ept_4levels()) { @@ -8803,14 +8840,6 @@ static int __init vmx_init(void) memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE); memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE); - /* shadowed read/write fields */ - for (i = 0; i < max_shadow_read_write_fields; i++) { - clear_bit(shadow_read_write_fields[i], vmx_vmwrite_bitmap); - clear_bit(shadow_read_write_fields[i], vmx_vmread_bitmap); - } - /* shadowed read only fields */ - for (i = 0; i < max_shadow_read_only_fields; i++) - clear_bit(shadow_read_only_fields[i], vmx_vmread_bitmap); /* * Allow direct access to the PC debug port (it is often used for I/O -- GitLab From e32dfbed8cc06aac72528e2bb53067ce02262413 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Mon, 28 Apr 2014 14:45:00 +0800 Subject: [PATCH 734/797] ALSA: hda - add headset mic detect quirk for a Dell laptop When we plug a 3-ring headset on the Dell machine (VID: 0x10ec0255, SID: 0x10280674), the headset mic can't be detected, after apply this patch, the headset mic can work well. BugLink: https://bugs.launchpad.net/bugs/1297581 Cc: David Henningsson Cc: stable@vger.kernel.org Signed-off-by: Hui Wang Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c643dfc0a826..c1952c910339 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4621,6 +4621,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), -- GitLab From def5f1273c5f18abf8fcaee03a115d3e907ad407 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 27 Apr 2014 21:03:09 -0700 Subject: [PATCH 735/797] linux/interrupt.h: fix new kernel-doc warnings Fix new kernel-doc warnings in : Warning(include/linux/interrupt.h:219): No description found for parameter 'cpumask' Warning(include/linux/interrupt.h:219): Excess function parameter 'mask' description in 'irq_set_affinity' Warning(include/linux/interrupt.h:236): No description found for parameter 'cpumask' Warning(include/linux/interrupt.h:236): Excess function parameter 'mask' description in 'irq_force_affinity' Signed-off-by: Randy Dunlap Link: http://lkml.kernel.org/r/535DD2FD.7030804@infradead.org Signed-off-by: Thomas Gleixner --- include/linux/interrupt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 8834a7e5b944..97ac926c78a7 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -210,7 +210,7 @@ extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask, /** * irq_set_affinity - Set the irq affinity of a given irq * @irq: Interrupt to set affinity - * @mask: cpumask + * @cpumask: cpumask * * Fails if cpumask does not contain an online CPU */ @@ -223,7 +223,7 @@ irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) /** * irq_force_affinity - Force the irq affinity of a given irq * @irq: Interrupt to set affinity - * @mask: cpumask + * @cpumask: cpumask * * Same as irq_set_affinity, but without checking the mask against * online cpus. -- GitLab From 62a08ae2a5763aabeee98264605236b001503e0c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 24 Apr 2014 09:50:53 +0200 Subject: [PATCH 736/797] genirq: x86: Ensure that dynamic irq allocation does not conflict On x86 the allocation of irq descriptors may allocate interrupts which are in the range of the GSI interrupts. That's wrong as those interrupts are hardwired and we don't have the irq domain translation like PPC. So one of these interrupts can be hooked up later to one of the devices which are hard wired to it and the io_apic init code for that particular interrupt line happily reuses that descriptor with a completely different configuration so hell breaks lose. Inside x86 we allocate dynamic interrupts from above nr_gsi_irqs, except for a few usage sites which have not yet blown up in our face for whatever reason. But for drivers which need an irq range, like the GPIO drivers, we have no limit in place and we don't want to expose such a detail to a driver. To cure this introduce a function which an architecture can implement to impose a lower bound on the dynamic interrupt allocations. Implement it for x86 and set the lower bound to nr_gsi_irqs, which is the end of the hardwired interrupt space, so all dynamic allocations happen above. That not only allows the GPIO driver to work sanely, it also protects the bogus callsites of create_irq_nr() in hpet, uv, irq_remapping and htirq code. They need to be cleaned up as well, but that's a separate issue. Reported-by: Jin Yao Signed-off-by: Thomas Gleixner Tested-by: Mika Westerberg Cc: Mathias Nyman Cc: Linus Torvalds Cc: Grant Likely Cc: H. Peter Anvin Cc: Rafael J. Wysocki Cc: Andy Shevchenko Cc: Krogerus Heikki Cc: Linus Walleij Link: http://lkml.kernel.org/r/alpine.DEB.2.02.1404241617360.28206@ionos.tec.linutronix.de Signed-off-by: Thomas Gleixner --- arch/x86/kernel/apic/io_apic.c | 5 +++++ include/linux/irq.h | 2 ++ kernel/irq/irqdesc.c | 7 +++++++ kernel/softirq.c | 5 +++++ 4 files changed, 19 insertions(+) diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 6ad4658de705..d23aa82e7a7b 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3425,6 +3425,11 @@ int get_nr_irqs_gsi(void) return nr_irqs_gsi; } +unsigned int arch_dynirq_lower_bound(unsigned int from) +{ + return from < nr_irqs_gsi ? nr_irqs_gsi : from; +} + int __init arch_probe_nr_irqs(void) { int nr; diff --git a/include/linux/irq.h b/include/linux/irq.h index 10a0b1ac4ea0..5c57efb863d0 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -603,6 +603,8 @@ static inline u32 irq_get_trigger_type(unsigned int irq) return d ? irqd_get_trigger_type(d) : 0; } +unsigned int arch_dynirq_lower_bound(unsigned int from); + int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, struct module *owner); diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index a7174617616b..bb07f2928f4b 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -363,6 +363,13 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, if (from > irq) return -EINVAL; from = irq; + } else { + /* + * For interrupts which are freely allocated the + * architecture can force a lower bound to the @from + * argument. x86 uses this to exclude the GSI space. + */ + from = arch_dynirq_lower_bound(from); } mutex_lock(&sparse_irq_lock); diff --git a/kernel/softirq.c b/kernel/softirq.c index b50990a5bea0..33e4648ae0e7 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -779,3 +779,8 @@ int __init __weak arch_early_irq_init(void) { return 0; } + +unsigned int __weak arch_dynirq_lower_bound(unsigned int from) +{ + return from; +} -- GitLab From 5d4e08c45a6cf8f1ab3c7fa375007635ac569165 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 28 Mar 2014 14:25:19 +0000 Subject: [PATCH 737/797] arm: KVM: fix possible misalignment of PGDs and bounce page The kvm/mmu code shared by arm and arm64 uses kalloc() to allocate a bounce page (if hypervisor init code crosses page boundary) and hypervisor PGDs. The problem is that kalloc() does not guarantee the proper alignment. In the case of the bounce page, the page sized buffer allocated may also cross a page boundary negating the purpose and leading to a hang during kvm initialization. Likewise the PGDs allocated may not meet the minimum alignment requirements of the underlying MMU. This patch uses __get_free_page() to guarantee the worst case alignment needs of the bounce page and PGDs on both arm and arm64. Cc: # 3.10+ Signed-off-by: Mark Salter Acked-by: Marc Zyngier Signed-off-by: Christoffer Dall --- arch/arm/kvm/mmu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c index 80bb1e6c2c29..16f804938b8f 100644 --- a/arch/arm/kvm/mmu.c +++ b/arch/arm/kvm/mmu.c @@ -42,6 +42,8 @@ static unsigned long hyp_idmap_start; static unsigned long hyp_idmap_end; static phys_addr_t hyp_idmap_vector; +#define pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t)) + #define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x)) static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa) @@ -293,14 +295,14 @@ void free_boot_hyp_pgd(void) if (boot_hyp_pgd) { unmap_range(NULL, boot_hyp_pgd, hyp_idmap_start, PAGE_SIZE); unmap_range(NULL, boot_hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); - kfree(boot_hyp_pgd); + free_pages((unsigned long)boot_hyp_pgd, pgd_order); boot_hyp_pgd = NULL; } if (hyp_pgd) unmap_range(NULL, hyp_pgd, TRAMPOLINE_VA, PAGE_SIZE); - kfree(init_bounce_page); + free_page((unsigned long)init_bounce_page); init_bounce_page = NULL; mutex_unlock(&kvm_hyp_pgd_mutex); @@ -330,7 +332,7 @@ void free_hyp_pgds(void) for (addr = VMALLOC_START; is_vmalloc_addr((void*)addr); addr += PGDIR_SIZE) unmap_range(NULL, hyp_pgd, KERN_TO_HYP(addr), PGDIR_SIZE); - kfree(hyp_pgd); + free_pages((unsigned long)hyp_pgd, pgd_order); hyp_pgd = NULL; } @@ -1024,7 +1026,7 @@ int kvm_mmu_init(void) size_t len = __hyp_idmap_text_end - __hyp_idmap_text_start; phys_addr_t phys_base; - init_bounce_page = kmalloc(PAGE_SIZE, GFP_KERNEL); + init_bounce_page = (void *)__get_free_page(GFP_KERNEL); if (!init_bounce_page) { kvm_err("Couldn't allocate HYP init bounce page\n"); err = -ENOMEM; @@ -1050,8 +1052,9 @@ int kvm_mmu_init(void) (unsigned long)phys_base); } - hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); - boot_hyp_pgd = kzalloc(PTRS_PER_PGD * sizeof(pgd_t), GFP_KERNEL); + hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); + boot_hyp_pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, pgd_order); + if (!hyp_pgd || !boot_hyp_pgd) { kvm_err("Hyp mode PGD not allocated\n"); err = -ENOMEM; -- GitLab From 5c8818b46e067120d33bbb2f610313240d76ba02 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 26 Apr 2014 03:43:01 -0700 Subject: [PATCH 738/797] MAINTAINERS: co-maintainance of KVM/{arm,arm64} The KVM/{arm,arm64} ports are sharing a lot of code, and are effectively co-maintained (and have been for quite a while). Make the situation official and list the two maintainers for both ports. Cc: Catalin Marinas Cc: Russell King Cc: Paolo Bonzini Cc: Gleb Natapov Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall Acked-by: Catalin Marinas Signed-off-by: Paolo Bonzini --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6dc67b1fdb50..24815e784905 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5108,14 +5108,19 @@ F: drivers/s390/kvm/ KERNEL VIRTUAL MACHINE (KVM) FOR ARM M: Christoffer Dall +M: Marc Zyngier +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: kvmarm@lists.cs.columbia.edu W: http://systems.cs.columbia.edu/projects/kvm-arm S: Supported F: arch/arm/include/uapi/asm/kvm* F: arch/arm/include/asm/kvm* F: arch/arm/kvm/ +F: virt/kvm/arm/ +F: include/kvm/arm_* KERNEL VIRTUAL MACHINE FOR ARM64 (KVM/arm64) +M: Christoffer Dall M: Marc Zyngier L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: kvmarm@lists.cs.columbia.edu -- GitLab From 91021a6c8ffdc55804dab5acdfc7de4f278b9ac3 Mon Sep 17 00:00:00 2001 From: Haibin Wang Date: Thu, 10 Apr 2014 13:14:32 +0100 Subject: [PATCH 739/797] KVM: ARM: vgic: Fix sgi dispatch problem When dispatch SGI(mode == 0), that is the vcpu of VM should send sgi to the cpu which the target_cpus list. So, there must add the "break" to branch of case 0. Cc: # 3.10+ Signed-off-by: Haibin Wang Acked-by: Marc Zyngier Signed-off-by: Christoffer Dall --- virt/kvm/arm/vgic.c | 1 + 1 file changed, 1 insertion(+) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 47b29834a6b6..7e8b44efb739 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -916,6 +916,7 @@ static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg) case 0: if (!target_cpus) return; + break; case 1: target_cpus = ((1 << nrcpus) - 1) & ~(1 << vcpu_id) & 0xff; -- GitLab From 41c22f626254b9dc0376928cae009e73d1b6a49a Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 21 Apr 2014 15:26:01 +0200 Subject: [PATCH 740/797] KVM: async_pf: mm->mm_users can not pin apf->mm get_user_pages(mm) is simply wrong if mm->mm_users == 0 and exit_mmap/etc was already called (or is in progress), mm->mm_count can only pin mm->pgd and mm_struct itself. Change kvm_setup_async_pf/async_pf_execute to inc/dec mm->mm_users. kvm_create_vm/kvm_destroy_vm play with ->mm_count too but this case looks fine at first glance, it seems that this ->mm is only used to verify that current->mm == kvm->mm. Signed-off-by: Oleg Nesterov Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini --- virt/kvm/async_pf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c index 10df100c4514..06e6401d6ef4 100644 --- a/virt/kvm/async_pf.c +++ b/virt/kvm/async_pf.c @@ -101,7 +101,7 @@ static void async_pf_execute(struct work_struct *work) if (waitqueue_active(&vcpu->wq)) wake_up_interruptible(&vcpu->wq); - mmdrop(mm); + mmput(mm); kvm_put_kvm(vcpu->kvm); } @@ -118,7 +118,7 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) flush_work(&work->work); #else if (cancel_work_sync(&work->work)) { - mmdrop(work->mm); + mmput(work->mm); kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ kmem_cache_free(async_pf_cache, work); } @@ -183,7 +183,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva, work->addr = hva; work->arch = *arch; work->mm = current->mm; - atomic_inc(&work->mm->mm_count); + atomic_inc(&work->mm->mm_users); kvm_get_kvm(work->vcpu->kvm); /* this can't really happen otherwise gfn_to_pfn_async @@ -201,7 +201,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva, return 1; retry_sync: kvm_put_kvm(work->vcpu->kvm); - mmdrop(work->mm); + mmput(work->mm); kmem_cache_free(async_pf_cache, work); return 0; } -- GitLab From f2ae85b2ab3776b9e4e42e5b6fa090f40d396794 Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Fri, 11 Apr 2014 00:07:18 +0200 Subject: [PATCH 741/797] KVM: arm/arm64: vgic: fix GICD_ICFGR register accesses Since KVM internally represents the ICFGR registers by stuffing two of them into one word, the offset for accessing the internal representation and the one for the MMIO based access are different. So keep the original offset around, but adjust the internal array offset by one bit. Reported-by: Haibin Wang Signed-off-by: Andre Przywara Signed-off-by: Marc Zyngier Signed-off-by: Christoffer Dall --- virt/kvm/arm/vgic.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index 7e8b44efb739..f9af48c9eb37 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -548,11 +548,10 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu, u32 val; u32 *reg; - offset >>= 1; reg = vgic_bitmap_get_reg(&vcpu->kvm->arch.vgic.irq_cfg, - vcpu->vcpu_id, offset); + vcpu->vcpu_id, offset >> 1); - if (offset & 2) + if (offset & 4) val = *reg >> 16; else val = *reg & 0xffff; @@ -561,13 +560,13 @@ static bool handle_mmio_cfg_reg(struct kvm_vcpu *vcpu, vgic_reg_access(mmio, &val, offset, ACCESS_READ_VALUE | ACCESS_WRITE_VALUE); if (mmio->is_write) { - if (offset < 4) { + if (offset < 8) { *reg = ~0U; /* Force PPIs/SGIs to 1 */ return false; } val = vgic_cfg_compress(val); - if (offset & 2) { + if (offset & 4) { *reg &= 0xffff; *reg |= val << 16; } else { -- GitLab From a949ae560a511fe4e3adf48fa44fefded93e5c2b Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Thu, 24 Apr 2014 10:40:12 -0400 Subject: [PATCH 742/797] ftrace/module: Hardcode ftrace_module_init() call into load_module() A race exists between module loading and enabling of function tracer. CPU 1 CPU 2 ----- ----- load_module() module->state = MODULE_STATE_COMING register_ftrace_function() mutex_lock(&ftrace_lock); ftrace_startup() update_ftrace_function(); ftrace_arch_code_modify_prepare() set_all_module_text_rw(); ftrace_arch_code_modify_post_process() set_all_module_text_ro(); [ here all module text is set to RO, including the module that is loading!! ] blocking_notifier_call_chain(MODULE_STATE_COMING); ftrace_init_module() [ tries to modify code, but it's RO, and fails! ftrace_bug() is called] When this race happens, ftrace_bug() will produces a nasty warning and all of the function tracing features will be disabled until reboot. The simple solution is to treate module load the same way the core kernel is treated at boot. To hardcode the ftrace function modification of converting calls to mcount into nops. This is done in init/main.c there's no reason it could not be done in load_module(). This gives a better control of the changes and doesn't tie the state of the module to its notifiers as much. Ftrace is special, it needs to be treated as such. The reason this would work, is that the ftrace_module_init() would be called while the module is in MODULE_STATE_UNFORMED, which is ignored by the set_all_module_text_ro() call. Link: http://lkml.kernel.org/r/1395637826-3312-1-git-send-email-indou.takao@jp.fujitsu.com Reported-by: Takao Indoh Acked-by: Rusty Russell Cc: stable@vger.kernel.org # 2.6.38+ Signed-off-by: Steven Rostedt --- include/linux/ftrace.h | 2 ++ kernel/module.c | 3 +++ kernel/trace/ftrace.c | 27 ++++----------------------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 9212b017bc72..ae9504b4b67d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -535,6 +535,7 @@ static inline int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_a extern int ftrace_arch_read_dyn_info(char *buf, int size); extern int skip_trace(unsigned long ip); +extern void ftrace_module_init(struct module *mod); extern void ftrace_disable_daemon(void); extern void ftrace_enable_daemon(void); @@ -544,6 +545,7 @@ static inline int ftrace_force_update(void) { return 0; } static inline void ftrace_disable_daemon(void) { } static inline void ftrace_enable_daemon(void) { } static inline void ftrace_release_mod(struct module *mod) {} +static inline void ftrace_module_init(struct module *mod) {} static inline __init int register_ftrace_command(struct ftrace_func_command *cmd) { return -EINVAL; diff --git a/kernel/module.c b/kernel/module.c index 11869408f79b..5f14fec9f825 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -3271,6 +3271,9 @@ static int load_module(struct load_info *info, const char __user *uargs, dynamic_debug_setup(info->debug, info->num_debug); + /* Ftrace init must be called in the MODULE_STATE_UNFORMED state */ + ftrace_module_init(mod); + /* Finally it's fully formed, ready to start executing. */ err = complete_formation(mod, info); if (err) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 1fd4b9479210..4a54a25afa2f 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -4330,16 +4330,11 @@ static void ftrace_init_module(struct module *mod, ftrace_process_locs(mod, start, end); } -static int ftrace_module_notify_enter(struct notifier_block *self, - unsigned long val, void *data) +void ftrace_module_init(struct module *mod) { - struct module *mod = data; - - if (val == MODULE_STATE_COMING) - ftrace_init_module(mod, mod->ftrace_callsites, - mod->ftrace_callsites + - mod->num_ftrace_callsites); - return 0; + ftrace_init_module(mod, mod->ftrace_callsites, + mod->ftrace_callsites + + mod->num_ftrace_callsites); } static int ftrace_module_notify_exit(struct notifier_block *self, @@ -4353,11 +4348,6 @@ static int ftrace_module_notify_exit(struct notifier_block *self, return 0; } #else -static int ftrace_module_notify_enter(struct notifier_block *self, - unsigned long val, void *data) -{ - return 0; -} static int ftrace_module_notify_exit(struct notifier_block *self, unsigned long val, void *data) { @@ -4365,11 +4355,6 @@ static int ftrace_module_notify_exit(struct notifier_block *self, } #endif /* CONFIG_MODULES */ -struct notifier_block ftrace_module_enter_nb = { - .notifier_call = ftrace_module_notify_enter, - .priority = INT_MAX, /* Run before anything that can use kprobes */ -}; - struct notifier_block ftrace_module_exit_nb = { .notifier_call = ftrace_module_notify_exit, .priority = INT_MIN, /* Run after anything that can remove kprobes */ @@ -4403,10 +4388,6 @@ void __init ftrace_init(void) __start_mcount_loc, __stop_mcount_loc); - ret = register_module_notifier(&ftrace_module_enter_nb); - if (ret) - pr_warning("Failed to register trace ftrace module enter notifier\n"); - ret = register_module_notifier(&ftrace_module_exit_nb); if (ret) pr_warning("Failed to register trace ftrace module exit notifier\n"); -- GitLab From af61e27c3f77c7623b5335590ae24b6a5c323e22 Mon Sep 17 00:00:00 2001 From: Tyler Stachecki Date: Fri, 25 Apr 2014 16:41:04 -0400 Subject: [PATCH 743/797] [SCSI] mpt2sas: Don't disable device twice at suspend. On suspend, _scsih_suspend calls mpt2sas_base_free_resources, which in turn calls pci_disable_device if the device is enabled prior to suspending. However, _scsih_suspend also calls pci_disable_device itself. Thus, in the event that the device is enabled prior to suspending, pci_disable_device will be called twice. This patch removes the duplicate call to pci_disable_device in _scsi_suspend as it is both unnecessary and results in a kernel oops. Signed-off-by: Tyler Stachecki Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 7f0af4fcc001..6fd7d40b2c4d 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -8293,7 +8293,6 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state) mpt2sas_base_free_resources(ioc); pci_save_state(pdev); - pci_disable_device(pdev); pci_set_power_state(pdev, device_state); return 0; } -- GitLab From 8cc3cfc5ccf1680b7c88f874912b6bec2797b76b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 4 Mar 2014 20:43:41 +0000 Subject: [PATCH 744/797] irqchip: armanda: Sanitize set_irq_affinity() The set_irq_affinity() function has two issues: 1) It has no protection against selecting an offline cpu from the given mask. 2) It pointlessly restricts the affinity masks to have a single cpu set. This collides with the irq migration code of arm. irq affinity is set to core 3 core 3 goes offline migration code sets mask to cpu_online_mask and calls the irq_set_affinity() callback of the irq_chip which fails due to bit 0,1,2 set. So instead of doing silly for_each_cpu() loops just pick any bit of the mask which intersects with the online mask. Get rid of fiddling with the default_irq_affinity as well. [ Gregory: Fixed the access to the routing register ] Signed-off-by: Thomas Gleixner Acked-by: Gregory CLEMENT Tested-by: Gregory CLEMENT Cc: Jason Cooper Cc: Peter Zijlstra Cc: Ingo Molnar Link: http://lkml.kernel.org/r/20140304203101.088889302@linutronix.de Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-armada-370-xp.c | 37 +++++------------------------ 1 file changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 41be897df8d5..304a20d0ad15 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -41,6 +41,7 @@ #define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30) #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34) #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4) +#define ARMADA_370_XP_INT_SOURCE_CPU_MASK 0xF #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44) #define ARMADA_375_PPI_CAUSE (0x10) @@ -244,35 +245,18 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); static int armada_xp_set_affinity(struct irq_data *d, const struct cpumask *mask_val, bool force) { - unsigned long reg; - unsigned long new_mask = 0; - unsigned long online_mask = 0; - unsigned long count = 0; irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned long reg, mask; int cpu; - for_each_cpu(cpu, mask_val) { - new_mask |= 1 << cpu_logical_map(cpu); - count++; - } - - /* - * Forbid mutlicore interrupt affinity - * This is required since the MPIC HW doesn't limit - * several CPUs from acknowledging the same interrupt. - */ - if (count > 1) - return -EINVAL; - - for_each_cpu(cpu, cpu_online_mask) - online_mask |= 1 << cpu_logical_map(cpu); + /* Select a single core from the affinity mask which is online */ + cpu = cpumask_any_and(mask_val, cpu_online_mask); + mask = 1UL << cpu_logical_map(cpu); raw_spin_lock(&irq_controller_lock); - reg = readl(main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq)); - reg = (reg & (~online_mask)) | new_mask; + reg = (reg & (~ARMADA_370_XP_INT_SOURCE_CPU_MASK)) | mask; writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq)); - raw_spin_unlock(&irq_controller_lock); return 0; @@ -494,15 +478,6 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, #ifdef CONFIG_SMP armada_xp_mpic_smp_cpu_init(); - - /* - * Set the default affinity from all CPUs to the boot cpu. - * This is required since the MPIC doesn't limit several CPUs - * from acknowledging the same interrupt. - */ - cpumask_clear(irq_default_affinity); - cpumask_set_cpu(smp_processor_id(), irq_default_affinity); - #endif armada_370_xp_msi_init(node, main_int_res.start); -- GitLab From 3894e9e82dfdc87fa35dc7976e0472d220228826 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 3 Apr 2014 10:21:34 +0300 Subject: [PATCH 745/797] irqchip: irq-crossbar: Not allocating enough memory We are allocating the size of a pointer and not the size of the data. This will lead to memory corruption. There isn't actually a "cb_device" struct, btw. The code is only able to compile because GCC knows that all pointers are the same size. Fixes: 96ca848ef7ea ('DRIVERS: IRQCHIP: CROSSBAR: Add support for Crossbar IP') Signed-off-by: Dan Carpenter Acked-by: Sricharan R Cc: Grant Likely Cc: Rob Herring Link: http://lkml.kernel.org/r/20140403072134.GA14286@mwanda Signed-off-by: Thomas Gleixner --- drivers/irqchip/irq-crossbar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index fc817d28d1fe..3d15d16a7088 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -107,7 +107,7 @@ static int __init crossbar_of_init(struct device_node *node) int i, size, max, reserved = 0, entry; const __be32 *irqsr; - cb = kzalloc(sizeof(struct cb_device *), GFP_KERNEL); + cb = kzalloc(sizeof(*cb), GFP_KERNEL); if (!cb) return -ENOMEM; -- GitLab From 50f5aa8a9b248fa4262cf379863ec9a531b49737 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 28 Apr 2014 14:24:09 -0700 Subject: [PATCH 746/797] mm: don't pointlessly use BUG_ON() for sanity check BUG_ON() is a big hammer, and should be used _only_ if there is some major corruption that you cannot possibly recover from, making it imperative that the current process (and possibly the whole machine) be terminated with extreme prejudice. The trivial sanity check in the vmacache code is *not* such a fatal error. Recovering from it is absolutely trivial, and using BUG_ON() just makes it harder to debug for no actual advantage. To make matters worse, the placement of the BUG_ON() (only if the range check matched) actually makes it harder to hit the sanity check to begin with, so _if_ there is a bug (and we just got a report from Srivatsa Bhat that this can indeed trigger), it is harder to debug not just because the machine is possibly dead, but because we don't have better coverage. BUG_ON() must *die*. Maybe we should add a checkpatch warning for it, because it is simply just about the worst thing you can ever do if you hit some "this cannot happen" situation. Reported-by: Srivatsa S. Bhat Cc: Davidlohr Bueso Cc: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmacache.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mm/vmacache.c b/mm/vmacache.c index d4224b397c0e..1037a3bab505 100644 --- a/mm/vmacache.c +++ b/mm/vmacache.c @@ -81,10 +81,12 @@ struct vm_area_struct *vmacache_find(struct mm_struct *mm, unsigned long addr) for (i = 0; i < VMACACHE_SIZE; i++) { struct vm_area_struct *vma = current->vmacache[i]; - if (vma && vma->vm_start <= addr && vma->vm_end > addr) { - BUG_ON(vma->vm_mm != mm); + if (!vma) + continue; + if (WARN_ON_ONCE(vma->vm_mm != mm)) + break; + if (vma->vm_start <= addr && vma->vm_end > addr) return vma; - } } return NULL; -- GitLab From 0c8482ac92db5ac15792caf23b7f7df9e4f48ae1 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Mon, 14 Apr 2014 10:16:09 +0800 Subject: [PATCH 747/797] [SCSI] virtio-scsi: Skip setting affinity on uninitialized vq virtscsi_init calls virtscsi_remove_vqs on err, even before initializing the vqs. The latter calls virtscsi_set_affinity, so let's check the pointer there before setting affinity on it. This fixes a panic when setting device's num_queues=2 on RHEL 6.5: qemu-system-x86_64 ... \ -device virtio-scsi-pci,id=scsi0,addr=0x13,...,num_queues=2 \ -drive file=/stor/vm/dummy.raw,id=drive-scsi-disk,... \ -device scsi-hd,drive=drive-scsi-disk,... [ 0.354734] scsi0 : Virtio SCSI HBA [ 0.379504] BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 [ 0.380141] IP: [] __virtscsi_set_affinity+0x4f/0x120 [ 0.380141] PGD 0 [ 0.380141] Oops: 0000 [#1] SMP [ 0.380141] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.14.0+ #5 [ 0.380141] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2007 [ 0.380141] task: ffff88003c9f0000 ti: ffff88003c9f8000 task.ti: ffff88003c9f8000 [ 0.380141] RIP: 0010:[] [] __virtscsi_set_affinity+0x4f/0x120 [ 0.380141] RSP: 0000:ffff88003c9f9c08 EFLAGS: 00010256 [ 0.380141] RAX: 0000000000000000 RBX: ffff88003c3a9d40 RCX: 0000000000001070 [ 0.380141] RDX: 0000000000000002 RSI: 0000000000000000 RDI: 0000000000000000 [ 0.380141] RBP: ffff88003c9f9c28 R08: 00000000000136c0 R09: ffff88003c801c00 [ 0.380141] R10: ffffffff81475229 R11: 0000000000000008 R12: 0000000000000000 [ 0.380141] R13: ffffffff81cc7ca8 R14: ffff88003cac3d40 R15: ffff88003cac37a0 [ 0.380141] FS: 0000000000000000(0000) GS:ffff88003e400000(0000) knlGS:0000000000000000 [ 0.380141] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 0.380141] CR2: 0000000000000020 CR3: 0000000001c0e000 CR4: 00000000000006f0 [ 0.380141] Stack: [ 0.380141] ffff88003c3a9d40 0000000000000000 ffff88003cac3d80 ffff88003cac3d40 [ 0.380141] ffff88003c9f9c48 ffffffff814742e8 ffff88003c26d000 ffff88003c26d000 [ 0.380141] ffff88003c9f9c68 ffffffff81474321 ffff88003c26d000 ffff88003c3a9d40 [ 0.380141] Call Trace: [ 0.380141] [] virtscsi_set_affinity+0x28/0x40 [ 0.380141] [] virtscsi_remove_vqs+0x21/0x50 [ 0.380141] [] virtscsi_init+0x91/0x240 [ 0.380141] [] ? vp_get+0x50/0x70 [ 0.380141] [] virtscsi_probe+0xf4/0x280 [ 0.380141] [] virtio_dev_probe+0xe5/0x140 [ 0.380141] [] driver_probe_device+0x89/0x230 [ 0.380141] [] __driver_attach+0x9b/0xa0 [ 0.380141] [] ? driver_probe_device+0x230/0x230 [ 0.380141] [] ? driver_probe_device+0x230/0x230 [ 0.380141] [] bus_for_each_dev+0x8c/0xb0 [ 0.380141] [] driver_attach+0x19/0x20 [ 0.380141] [] bus_add_driver+0x198/0x220 [ 0.380141] [] driver_register+0x5f/0xf0 [ 0.380141] [] ? spi_transport_init+0x79/0x79 [ 0.380141] [] register_virtio_driver+0x1b/0x30 [ 0.380141] [] init+0x88/0xd6 [ 0.380141] [] ? scsi_init_procfs+0x5b/0x5b [ 0.380141] [] do_one_initcall+0x7f/0x10a [ 0.380141] [] kernel_init_freeable+0x14a/0x1de [ 0.380141] [] ? kernel_init_freeable+0x1de/0x1de [ 0.380141] [] ? rest_init+0x80/0x80 [ 0.380141] [] kernel_init+0x9/0xf0 [ 0.380141] [] ret_from_fork+0x7c/0xb0 [ 0.380141] [] ? rest_init+0x80/0x80 [ 0.380141] RIP [] __virtscsi_set_affinity+0x4f/0x120 [ 0.380141] RSP [ 0.380141] CR2: 0000000000000020 [ 0.380141] ---[ end trace 8074b70c3d5e1d73 ]--- [ 0.475018] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009 [ 0.475018] [ 0.475068] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff) [ 0.475068] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009 [jejb: checkpatch fixes] Signed-off-by: Fam Zheng Acked-by: Paolo Bonzini Cc: stable@vger.kernel.org Signed-off-by: James Bottomley --- drivers/scsi/virtio_scsi.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 16bfd50cd3fe..db3b494e5926 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -750,8 +750,12 @@ static void __virtscsi_set_affinity(struct virtio_scsi *vscsi, bool affinity) vscsi->affinity_hint_set = true; } else { - for (i = 0; i < vscsi->num_queues; i++) + for (i = 0; i < vscsi->num_queues; i++) { + if (!vscsi->req_vqs[i].vq) + continue; + virtqueue_set_affinity(vscsi->req_vqs[i].vq, -1); + } vscsi->affinity_hint_set = false; } -- GitLab From 7aa0557fae5ce26dddc877869c7ad934e71f30db Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 29 Apr 2014 00:24:09 +0530 Subject: [PATCH 748/797] cpufreq: longhaul: Fix double invocation of cpufreq_freq_transition_begin/end During frequency transitions, the cpufreq core takes the responsibility of invoking cpufreq_freq_transition_begin() and cpufreq_freq_transition_end() for those cpufreq drivers that define the ->target_index callback but don't set the ASYNC_NOTIFICATION flag. The longhaul cpufreq driver falls under this category, but this driver was invoking the _begin() and _end() APIs itself around frequency transitions, which led to double invocation of the _begin() API. The _begin API makes contending callers wait until the previous invocation is complete. Hence, the longhaul driver ended up waiting on itself, leading to system hangs during boot. Fix this by removing the calls to the _begin() and _end() APIs from the longhaul driver, since they rightly belong to the cpufreq core. (Note that during module_exit(), the longhaul driver sets the frequency without any help from the cpufreq core. So add explicit calls to the _begin() and _end() APIs around that frequency transition alone, to take care of that special case.) Fixes: 12478cf0c55e (cpufreq: Make sure frequency transitions are serialized) Reported-and-tested-by: Meelis Roos Signed-off-by: Srivatsa S. Bhat Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/longhaul.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index d00e5d1abd25..5c4369b5d834 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -242,7 +242,7 @@ static void do_powersaver(int cx_address, unsigned int mults_index, * Sets a new clock ratio. */ -static void longhaul_setstate(struct cpufreq_policy *policy, +static int longhaul_setstate(struct cpufreq_policy *policy, unsigned int table_index) { unsigned int mults_index; @@ -258,10 +258,12 @@ static void longhaul_setstate(struct cpufreq_policy *policy, /* Safety precautions */ mult = mults[mults_index & 0x1f]; if (mult == -1) - return; + return -EINVAL; + speed = calc_speed(mult); if ((speed > highest_speed) || (speed < lowest_speed)) - return; + return -EINVAL; + /* Voltage transition before frequency transition? */ if (can_scale_voltage && longhaul_index < table_index) dir = 1; @@ -269,8 +271,6 @@ static void longhaul_setstate(struct cpufreq_policy *policy, freqs.old = calc_speed(longhaul_get_cpu_mult()); freqs.new = speed; - cpufreq_freq_transition_begin(policy, &freqs); - pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n", fsb, mult/10, mult%10, print_speed(speed/1000)); retry_loop: @@ -385,12 +385,14 @@ static void longhaul_setstate(struct cpufreq_policy *policy, goto retry_loop; } } - /* Report true CPU frequency */ - cpufreq_freq_transition_end(policy, &freqs, 0); - if (!bm_timeout) + if (!bm_timeout) { printk(KERN_INFO PFX "Warning: Timeout while waiting for " "idle PCI bus.\n"); + return -EBUSY; + } + + return 0; } /* @@ -631,9 +633,10 @@ static int longhaul_target(struct cpufreq_policy *policy, unsigned int i; unsigned int dir = 0; u8 vid, current_vid; + int retval = 0; if (!can_scale_voltage) - longhaul_setstate(policy, table_index); + retval = longhaul_setstate(policy, table_index); else { /* On test system voltage transitions exceeding single * step up or down were turning motherboard off. Both @@ -648,7 +651,7 @@ static int longhaul_target(struct cpufreq_policy *policy, while (i != table_index) { vid = (longhaul_table[i].driver_data >> 8) & 0x1f; if (vid != current_vid) { - longhaul_setstate(policy, i); + retval = longhaul_setstate(policy, i); current_vid = vid; msleep(200); } @@ -657,10 +660,11 @@ static int longhaul_target(struct cpufreq_policy *policy, else i--; } - longhaul_setstate(policy, table_index); + retval = longhaul_setstate(policy, table_index); } + longhaul_index = table_index; - return 0; + return retval; } @@ -968,7 +972,15 @@ static void __exit longhaul_exit(void) for (i = 0; i < numscales; i++) { if (mults[i] == maxmult) { + struct cpufreq_freqs freqs; + + freqs.old = policy->cur; + freqs.new = longhaul_table[i].frequency; + freqs.flags = 0; + + cpufreq_freq_transition_begin(policy, &freqs); longhaul_setstate(policy, i); + cpufreq_freq_transition_end(policy, &freqs, 0); break; } } -- GitLab From 237ede16ba5bcd4d6c612ea280518c48ca31986c Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 29 Apr 2014 00:24:27 +0530 Subject: [PATCH 749/797] cpufreq: powernow-k6: Fix incorrect comparison with max_multipler The value of 'max_multiplier' is meant to be used for comparison with clock_ratio[index].driver_data, not the index itself! Fix the code in powernow_k6_cpu_exit() that has this bug. Also, while at it, make the for-loop condition look for CPUFREQ_TABLE_END, instead of hard-coding the loop count to 8. Reported-by: Viresh Kumar Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernow-k6.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 49f120e1bc7b..695a68cfdcd4 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -227,8 +227,9 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy) static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) { unsigned int i; - for (i = 0; i < 8; i++) { - if (i == max_multiplier) + + for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { + if (clock_ratio[i].driver_data == max_multiplier) powernow_k6_target(policy, i); } return 0; -- GitLab From 3221e55b72359c44ed75afbcf707710af5bc2d59 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 29 Apr 2014 00:24:42 +0530 Subject: [PATCH 750/797] cpufreq: powernow-k6: Fix double invocation of cpufreq_freq_transition_begin/end During frequency transitions, the cpufreq core takes the responsibility of invoking cpufreq_freq_transition_begin() and cpufreq_freq_transition_end() for those cpufreq drivers that define the ->target_index callback but don't set the ASYNC_NOTIFICATION flag. The powernow-k6 cpufreq driver falls under this category, but this driver was invoking the _begin() and _end() APIs itself around frequency transitions, which led to double invocation of the _begin() API. The _begin API makes contending callers wait until the previous invocation is complete. Hence, the powernow-k6 driver ended up waiting on itself, leading to system hangs during boot. Fix this by removing the calls to the _begin() and _end() APIs from the powernow-k6 driver, since they rightly belong to the cpufreq core. (Note that during ->exit(), the powernow-k6 driver sets the frequency without any help from the cpufreq core. So add explicit calls to the _begin() and _end() APIs around that frequency transition alone, to take care of that special case. Also, add a missing 'break' statement there.) Fixes: 12478cf0c55e (cpufreq: Make sure frequency transitions are serialized) Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernow-k6.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index 695a68cfdcd4..78904e6ca4a0 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -138,22 +138,14 @@ static void powernow_k6_set_cpu_multiplier(unsigned int best_i) static int powernow_k6_target(struct cpufreq_policy *policy, unsigned int best_i) { - struct cpufreq_freqs freqs; if (clock_ratio[best_i].driver_data > max_multiplier) { printk(KERN_ERR PFX "invalid target frequency\n"); return -EINVAL; } - freqs.old = busfreq * powernow_k6_get_cpu_multiplier(); - freqs.new = busfreq * clock_ratio[best_i].driver_data; - - cpufreq_freq_transition_begin(policy, &freqs); - powernow_k6_set_cpu_multiplier(best_i); - cpufreq_freq_transition_end(policy, &freqs, 0); - return 0; } @@ -229,8 +221,18 @@ static int powernow_k6_cpu_exit(struct cpufreq_policy *policy) unsigned int i; for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) { - if (clock_ratio[i].driver_data == max_multiplier) + if (clock_ratio[i].driver_data == max_multiplier) { + struct cpufreq_freqs freqs; + + freqs.old = policy->cur; + freqs.new = clock_ratio[i].frequency; + freqs.flags = 0; + + cpufreq_freq_transition_begin(policy, &freqs); powernow_k6_target(policy, i); + cpufreq_freq_transition_end(policy, &freqs, 0); + break; + } } return 0; } -- GitLab From 8997b185119966c62c6e95e7b010b4060407e358 Mon Sep 17 00:00:00 2001 From: "Srivatsa S. Bhat" Date: Tue, 29 Apr 2014 00:24:58 +0530 Subject: [PATCH 751/797] cpufreq: powernow-k7: Fix double invocation of cpufreq_freq_transition_begin/end During frequency transitions, the cpufreq core takes the responsibility of invoking cpufreq_freq_transition_begin() and cpufreq_freq_transition_end() for those cpufreq drivers that define the ->target_index callback but don't set the ASYNC_NOTIFICATION flag. The powernow-k7 cpufreq driver falls under this category, but this driver was invoking the _begin() and _end() APIs itself around frequency transitions, which led to double invocation of the _begin() API. The _begin API makes contending callers wait until the previous invocation is complete. Hence, the powernow-k7 driver ended up waiting on itself, leading to system hangs during boot. Fix this by removing the calls to the _begin() and _end() APIs from the powernow-k7 driver, since they rightly belong to the cpufreq core. Fixes: 12478cf0c55e (cpufreq: Make sure frequency transitions are serialized) Signed-off-by: Srivatsa S. Bhat Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernow-k7.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index f911645c3f6d..e61e224475ad 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -269,8 +269,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index) freqs.new = powernow_table[index].frequency; - cpufreq_freq_transition_begin(policy, &freqs); - /* Now do the magic poking into the MSRs. */ if (have_a0 == 1) /* A0 errata 5 */ @@ -290,8 +288,6 @@ static int powernow_target(struct cpufreq_policy *policy, unsigned int index) if (have_a0 == 1) local_irq_enable(); - cpufreq_freq_transition_end(policy, &freqs, 0); - return 0; } -- GitLab From 6712d2931933ada259b82f06c03a855b19937074 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Mon, 28 Apr 2014 10:18:18 -0600 Subject: [PATCH 752/797] cpufreq: ppc-corenet-cpufreq: Fix __udivdi3 modpost error bfa709bc823fc32ee8dd5220d1711b46078235d8 (cpufreq: powerpc: add cpufreq transition latency for FSL e500mc SoCs) introduced a modpost error: ERROR: "__udivdi3" [drivers/cpufreq/ppc-corenet-cpufreq.ko] undefined! make[1]: *** [__modpost] Error 1 Fix this by avoiding 64 bit integer division. gcc version 4.8.2 Fixes: bfa709bc823f (cpufreq: powerpc: add cpufreq transition latency for FSL e500mc SoCs) Signed-off-by: Tim Gardner Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/ppc-corenet-cpufreq.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c index a1ca3dd04a8e..0af618abebaf 100644 --- a/drivers/cpufreq/ppc-corenet-cpufreq.c +++ b/drivers/cpufreq/ppc-corenet-cpufreq.c @@ -138,6 +138,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) struct cpufreq_frequency_table *table; struct cpu_data *data; unsigned int cpu = policy->cpu; + u64 transition_latency_hz; np = of_get_cpu_node(cpu, NULL); if (!np) @@ -205,8 +206,10 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) for_each_cpu(i, per_cpu(cpu_mask, cpu)) per_cpu(cpu_data, i) = data; + transition_latency_hz = 12ULL * NSEC_PER_SEC; policy->cpuinfo.transition_latency = - (12ULL * NSEC_PER_SEC) / fsl_get_sys_freq(); + do_div(transition_latency_hz, fsl_get_sys_freq()); + of_node_put(np); return 0; -- GitLab From cc18b939e1efbc2a47f62dbd2b1df53d974df6b7 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 24 Apr 2014 14:31:53 -0500 Subject: [PATCH 753/797] RDMA/cxgb4: Fix endpoint mutex deadlocks In cases where the cm calls c4iw_modify_rc_qp() with the endpoint mutex held, they must be called with internal == 1. rx_data() and process_mpa_reply() are not doing this. This causes a deadlock because c4iw_modify_rc_qp() might call c4iw_ep_disconnect() in some !internal cases, and c4iw_ep_disconnect() acquires the endpoint mutex. The design was intended to only do the disconnect for !internal calls. Change rx_data(), FPDU_MODE case, to call c4iw_modify_rc_qp() with internal == 1, and then disconnect only after releasing the mutex. Change process_mpa_reply() to call c4iw_modify_rc_qp(TERMINATE) with internal == 1 and set a new attr flag telling it to send a TERMINATE message. Previously this was implied by !internal. Change process_mpa_reply() to return whether the caller should disconnect after releasing the endpoint mutex. Now rx_data() will do the disconnect in the cases where process_mpa_reply() wants to disconnect after the TERMINATE is sent. Change c4iw_modify_rc_qp() RTS->TERM to only disconnect if !internal, and to send a TERMINATE message if attrs->send_term is 1. Change abort_connection() to not aquire the ep mutex for setting the state, and make all calls to abort_connection() do so with the mutex held. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cm.c | 31 +++++++++++++++++--------- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 + drivers/infiniband/hw/cxgb4/qp.c | 9 ++++---- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 185452abf32c..f9b04bc7e602 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -996,7 +996,7 @@ static void close_complete_upcall(struct c4iw_ep *ep, int status) static int abort_connection(struct c4iw_ep *ep, struct sk_buff *skb, gfp_t gfp) { PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); - state_set(&ep->com, ABORTING); + __state_set(&ep->com, ABORTING); set_bit(ABORT_CONN, &ep->com.history); return send_abort(ep, skb, gfp); } @@ -1154,7 +1154,7 @@ static int update_rx_credits(struct c4iw_ep *ep, u32 credits) return credits; } -static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) +static int process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) { struct mpa_message *mpa; struct mpa_v2_conn_params *mpa_v2_params; @@ -1164,6 +1164,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) struct c4iw_qp_attributes attrs; enum c4iw_qp_attr_mask mask; int err; + int disconnect = 0; PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid); @@ -1173,7 +1174,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) * will abort the connection. */ if (stop_ep_timer(ep)) - return; + return 0; /* * If we get more than the supported amount of private data @@ -1195,7 +1196,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) * if we don't even have the mpa message, then bail. */ if (ep->mpa_pkt_len < sizeof(*mpa)) - return; + return 0; mpa = (struct mpa_message *) ep->mpa_pkt; /* Validate MPA header. */ @@ -1235,7 +1236,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) * We'll continue process when more data arrives. */ if (ep->mpa_pkt_len < (sizeof(*mpa) + plen)) - return; + return 0; if (mpa->flags & MPA_REJECT) { err = -ECONNREFUSED; @@ -1337,9 +1338,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) attrs.layer_etype = LAYER_MPA | DDP_LLP; attrs.ecode = MPA_NOMATCH_RTR; attrs.next_state = C4IW_QP_STATE_TERMINATE; + attrs.send_term = 1; err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, - C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); + C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); err = -ENOMEM; + disconnect = 1; goto out; } @@ -1355,9 +1358,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) attrs.layer_etype = LAYER_MPA | DDP_LLP; attrs.ecode = MPA_INSUFF_IRD; attrs.next_state = C4IW_QP_STATE_TERMINATE; + attrs.send_term = 1; err = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, - C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); + C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); err = -ENOMEM; + disconnect = 1; goto out; } goto out; @@ -1366,7 +1371,7 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb) send_abort(ep, skb, GFP_KERNEL); out: connect_reply_upcall(ep, err); - return; + return disconnect; } static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb) @@ -1524,6 +1529,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) unsigned int tid = GET_TID(hdr); struct tid_info *t = dev->rdev.lldi.tids; __u8 status = hdr->status; + int disconnect = 0; ep = lookup_tid(t, tid); if (!ep) @@ -1539,7 +1545,7 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) switch (ep->com.state) { case MPA_REQ_SENT: ep->rcv_seq += dlen; - process_mpa_reply(ep, skb); + disconnect = process_mpa_reply(ep, skb); break; case MPA_REQ_WAIT: ep->rcv_seq += dlen; @@ -1555,13 +1561,16 @@ static int rx_data(struct c4iw_dev *dev, struct sk_buff *skb) ep->com.state, ep->hwtid, status); attrs.next_state = C4IW_QP_STATE_TERMINATE; c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp, - C4IW_QP_ATTR_NEXT_STATE, &attrs, 0); + C4IW_QP_ATTR_NEXT_STATE, &attrs, 1); + disconnect = 1; break; } default: break; } mutex_unlock(&ep->com.mutex); + if (disconnect) + c4iw_ep_disconnect(ep, 0, GFP_KERNEL); return 0; } @@ -3482,9 +3491,9 @@ static void process_timeout(struct c4iw_ep *ep) __func__, ep, ep->hwtid, ep->com.state); abort = 0; } - mutex_unlock(&ep->com.mutex); if (abort) abort_connection(ep, NULL, GFP_KERNEL); + mutex_unlock(&ep->com.mutex); c4iw_put_ep(&ep->com); } diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 7b8c5806a09d..7474b490760a 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -435,6 +435,7 @@ struct c4iw_qp_attributes { u8 ecode; u16 sq_db_inc; u16 rq_db_inc; + u8 send_term; }; struct c4iw_qp { diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 7b5114cb486f..f18ef34e8184 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1388,11 +1388,12 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp, qhp->attr.layer_etype = attrs->layer_etype; qhp->attr.ecode = attrs->ecode; ep = qhp->ep; - disconnect = 1; - c4iw_get_ep(&qhp->ep->com); - if (!internal) + if (!internal) { + c4iw_get_ep(&qhp->ep->com); terminate = 1; - else { + disconnect = 1; + } else { + terminate = qhp->attr.send_term; ret = rdma_fini(rhp, qhp, ep); if (ret) goto err; -- GitLab From 92e5011ab0e073ab8fbb726c11529021e5e63973 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 24 Apr 2014 14:31:59 -0500 Subject: [PATCH 754/797] RDMA/cxgb4: Force T5 connections to use TAHOE congestion control This is required to work around a T5 HW issue. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/cm.c | 8 ++++++++ drivers/infiniband/hw/cxgb4/t4fw_ri_api.h | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index f9b04bc7e602..1f863a96a480 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -587,6 +587,10 @@ static int send_connect(struct c4iw_ep *ep) opt2 |= SACK_EN(1); if (wscale && enable_tcp_window_scaling) opt2 |= WND_SCALE_EN(1); + if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { + opt2 |= T5_OPT_2_VALID; + opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE); + } t4_set_arp_err_handler(skb, NULL, act_open_req_arp_failure); if (is_t4(ep->com.dev->rdev.lldi.adapter_type)) { @@ -2018,6 +2022,10 @@ static void accept_cr(struct c4iw_ep *ep, struct sk_buff *skb, if (tcph->ece && tcph->cwr) opt2 |= CCTRL_ECN(1); } + if (is_t5(ep->com.dev->rdev.lldi.adapter_type)) { + opt2 |= T5_OPT_2_VALID; + opt2 |= V_CONG_CNTRL(CONG_ALG_TAHOE); + } rpl = cplhdr(skb); INIT_TP_WR(rpl, ep->hwtid); diff --git a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h index dc193c292671..6121ca08fe58 100644 --- a/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h +++ b/drivers/infiniband/hw/cxgb4/t4fw_ri_api.h @@ -836,4 +836,18 @@ struct ulptx_idata { #define V_RX_DACK_CHANGE(x) ((x) << S_RX_DACK_CHANGE) #define F_RX_DACK_CHANGE V_RX_DACK_CHANGE(1U) +enum { /* TCP congestion control algorithms */ + CONG_ALG_RENO, + CONG_ALG_TAHOE, + CONG_ALG_NEWRENO, + CONG_ALG_HIGHSPEED +}; + +#define S_CONG_CNTRL 14 +#define M_CONG_CNTRL 0x3 +#define V_CONG_CNTRL(x) ((x) << S_CONG_CNTRL) +#define G_CONG_CNTRL(x) (((x) >> S_CONG_CNTRL) & M_CONG_CNTRL) + +#define T5_OPT_2_VALID (1 << 31) + #endif /* _T4FW_RI_API_H_ */ -- GitLab From c2f9da92f2fd6dbf8f40ef4d5e00db688cc0416a Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Thu, 24 Apr 2014 14:32:04 -0500 Subject: [PATCH 755/797] RDMA/cxgb4: Only allow kernel db ringing for T4 devs The whole db drop avoidance stuff is for T4 only. So we cannot allow that to be enabled for T5 devices. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/qp.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index f18ef34e8184..086f62f5dc9e 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -1777,11 +1777,15 @@ int c4iw_ib_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, /* * Use SQ_PSN and RQ_PSN to pass in IDX_INC values for * ringing the queue db when we're in DB_FULL mode. + * Only allow this on T4 devices. */ attrs.sq_db_inc = attr->sq_psn; attrs.rq_db_inc = attr->rq_psn; mask |= (attr_mask & IB_QP_SQ_PSN) ? C4IW_QP_ATTR_SQ_DB : 0; mask |= (attr_mask & IB_QP_RQ_PSN) ? C4IW_QP_ATTR_RQ_DB : 0; + if (is_t5(to_c4iw_qp(ibqp)->rhp->rdev.lldi.adapter_type) && + (mask & (C4IW_QP_ATTR_SQ_DB|C4IW_QP_ATTR_RQ_DB))) + return -EINVAL; return c4iw_modify_qp(rhp, qhp, mask, &attrs, 0); } -- GitLab From 7d0a73a40c5ceb7524aa6a43f108de0dd8dbe3f0 Mon Sep 17 00:00:00 2001 From: Hariprasad S Date: Sat, 26 Apr 2014 00:51:18 +0530 Subject: [PATCH 756/797] RDMA/cxgb4: Update Kconfig to include Chelsio T5 adapter Signed-off-by: Hariprasad Shenai Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb4/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/infiniband/hw/cxgb4/Kconfig b/drivers/infiniband/hw/cxgb4/Kconfig index d4e8983fba53..23f38cf2c5cd 100644 --- a/drivers/infiniband/hw/cxgb4/Kconfig +++ b/drivers/infiniband/hw/cxgb4/Kconfig @@ -1,10 +1,10 @@ config INFINIBAND_CXGB4 - tristate "Chelsio T4 RDMA Driver" + tristate "Chelsio T4/T5 RDMA Driver" depends on CHELSIO_T4 && INET && (IPV6 || IPV6=n) select GENERIC_ALLOCATOR ---help--- - This is an iWARP/RDMA driver for the Chelsio T4 1GbE and - 10GbE adapters. + This is an iWARP/RDMA driver for the Chelsio T4 and T5 + 1GbE, 10GbE adapters and T5 40GbE adapter. For general information about Chelsio and our products, visit our website at . -- GitLab From 30c2117085bc4e05d091cee6eba79f069b41a9cd Mon Sep 17 00:00:00 2001 From: Haibin Wang Date: Tue, 29 Apr 2014 14:49:17 +0800 Subject: [PATCH 757/797] KVM: ARM: vgic: Fix the overlap check action about setting the GICD & GICC base address. Currently below check in vgic_ioaddr_overlap will always succeed, because the vgic dist base and vgic cpu base are still kept UNDEF after initialization. The code as follows will be return forever. if (IS_VGIC_ADDR_UNDEF(dist) || IS_VGIC_ADDR_UNDEF(cpu)) return 0; So, before invoking the vgic_ioaddr_overlap, it needs to set the corresponding base address firstly. Signed-off-by: Haibin Wang Acked-by: Marc Zyngier Signed-off-by: Christoffer Dall --- virt/kvm/arm/vgic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c index f9af48c9eb37..56ff9bebb577 100644 --- a/virt/kvm/arm/vgic.c +++ b/virt/kvm/arm/vgic.c @@ -1667,10 +1667,11 @@ static int vgic_ioaddr_assign(struct kvm *kvm, phys_addr_t *ioaddr, if (addr + size < addr) return -EINVAL; + *ioaddr = addr; ret = vgic_ioaddr_overlap(kvm); if (ret) - return ret; - *ioaddr = addr; + *ioaddr = VGIC_ADDR_UNDEF; + return ret; } -- GitLab From 82a5619410d4c4df65c04272db198eca5a867c18 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Tue, 8 Apr 2014 10:04:32 +0100 Subject: [PATCH 758/797] clocksource: arch_arm_timer: Fix age-old arch timer C3STOP detection issue ARM arch timers are tightly coupled with the CPU logic and lose context on platform implementing HW power management when cores are powered down at run-time. Marking the arch timers as C3STOP regardless of power management capabilities causes issues on platforms with no power management, since in that case the arch timers cannot possibly enter states where the timer loses context at runtime and therefore can always be used as a high resolution clockevent device. In order to fix the C3STOP issue in a way compliant with how real HW works, this patch adds a boolean property to the arch timer bindings to define if the arch timer is managed by an always-on power domain. This power domain is present on all ARM platforms to date, and manages HW that must not be turned off, whatever the state of other HW components (eg power controller). On platforms with no power management capabilities, it is the only power domain present, which encompasses and manages power supply for all HW components in the system. If the timer is powered by the always-on power domain, the always-on property must be present in the bindings which means that the timer cannot be shutdown at runtime, so it is not a C3STOP clockevent device. If the timer binding does not contain the always-on property, the timer is assumed to be power-gateable, hence it must be defined as a C3STOP clockevent device. Cc: Daniel Lezcano Cc: Magnus Damm Cc: Marc Carino Cc: Mark Rutland Acked-by: Marc Zyngier Acked-by: Rob Herring Signed-off-by: Lorenzo Pieralisi Signed-off-by: Daniel Lezcano --- Documentation/devicetree/bindings/arm/arch_timer.txt | 3 +++ drivers/clocksource/arm_arch_timer.c | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/arch_timer.txt b/Documentation/devicetree/bindings/arm/arch_timer.txt index 06fc7602593a..37b2cafa4e52 100644 --- a/Documentation/devicetree/bindings/arm/arch_timer.txt +++ b/Documentation/devicetree/bindings/arm/arch_timer.txt @@ -19,6 +19,9 @@ to deliver its interrupts via SPIs. - clock-frequency : The frequency of the main counter, in Hz. Optional. +- always-on : a boolean property. If present, the timer is powered through an + always-on power domain, therefore it never loses context. + Example: timer { diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 57e823c44d2a..5163ec13429d 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -66,6 +66,7 @@ static int arch_timer_ppi[MAX_TIMER_PPI]; static struct clock_event_device __percpu *arch_timer_evt; static bool arch_timer_use_virtual = true; +static bool arch_timer_c3stop; static bool arch_timer_mem_use_virtual; /* @@ -263,7 +264,8 @@ static void __arch_timer_setup(unsigned type, clk->features = CLOCK_EVT_FEAT_ONESHOT; if (type == ARCH_CP15_TIMER) { - clk->features |= CLOCK_EVT_FEAT_C3STOP; + if (arch_timer_c3stop) + clk->features |= CLOCK_EVT_FEAT_C3STOP; clk->name = "arch_sys_timer"; clk->rating = 450; clk->cpumask = cpumask_of(smp_processor_id()); @@ -665,6 +667,8 @@ static void __init arch_timer_init(struct device_node *np) } } + arch_timer_c3stop = !of_property_read_bool(np, "always-on"); + arch_timer_register(); arch_timer_common_init(); } -- GitLab From 9afa27ce9414c92e271b0d7eec937bd9f5565da5 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sat, 26 Apr 2014 09:32:16 +0400 Subject: [PATCH 759/797] clocksource: nspire: Fix compiler warning CC drivers/clocksource/zevio-timer.o drivers/clocksource/zevio-timer.c:215:1: warning: comparison of distinct pointer types lacks a cast [enabled by default] Signed-off-by: Alexander Shiyan Signed-off-by: Daniel Lezcano --- drivers/clocksource/zevio-timer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/clocksource/zevio-timer.c b/drivers/clocksource/zevio-timer.c index ca81809d159d..7ce442148c3f 100644 --- a/drivers/clocksource/zevio-timer.c +++ b/drivers/clocksource/zevio-timer.c @@ -212,4 +212,9 @@ static int __init zevio_timer_add(struct device_node *node) return ret; } -CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_add); +static void __init zevio_timer_init(struct device_node *node) +{ + BUG_ON(zevio_timer_add(node)); +} + +CLOCKSOURCE_OF_DECLARE(zevio_timer, "lsi,zevio-timer", zevio_timer_init); -- GitLab From 58b116bce13612e5aa6fcd49ecbd4cf8bb59e835 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 29 Apr 2014 12:05:22 +0100 Subject: [PATCH 760/797] drivercore: deferral race condition fix When the kernel is built with CONFIG_PREEMPT it is possible to reach a state when all modules loaded but some driver still stuck in the deferred list and there is a need for external event to kick the deferred queue to probe these drivers. The issue has been observed on embedded systems with CONFIG_PREEMPT enabled, audio support built as modules and using nfsroot for root filesystem. The following log fragment shows such sequence when all audio modules were loaded but the sound card is not present since the machine driver has failed to probe due to missing dependency during it's probe. The board is am335x-evmsk (McASP<->tlv320aic3106 codec) with davinci-evm machine driver: ... [ 12.615118] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: ENTER [ 12.719969] davinci_evm sound.3: davinci_evm_probe: ENTER [ 12.725753] davinci_evm sound.3: davinci_evm_probe: snd_soc_register_card [ 12.753846] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: snd_soc_register_component [ 12.922051] davinci-mcasp 4803c000.mcasp: davinci_mcasp_probe: snd_soc_register_component DONE [ 12.950839] davinci_evm sound.3: ASoC: platform (null) not registered [ 12.957898] davinci_evm sound.3: davinci_evm_probe: snd_soc_register_card DONE (-517) [ 13.099026] davinci-mcasp 4803c000.mcasp: Kicking the deferred list [ 13.177838] davinci-mcasp 4803c000.mcasp: really_probe: probe_count = 2 [ 13.194130] davinci_evm sound.3: snd_soc_register_card failed (-517) [ 13.346755] davinci_mcasp_driver_init: LEAVE [ 13.377446] platform sound.3: Driver davinci_evm requests probe deferral [ 13.592527] platform sound.3: really_probe: probe_count = 0 In the log the machine driver enters it's probe at 12.719969 (this point it has been removed from the deferred lists). McASP driver already executing it's probing (since 12.615118). The machine driver tries to construct the sound card (12.950839) but did not found one of the components so it fails. After this McASP driver registers all the ASoC components (the machine driver still in it's probe function after it failed to construct the card) and the deferred work is prepared at 13.099026 (note that this time the machine driver is not in the lists so it is not going to be handled when the work is executing). Lastly the machine driver exit from it's probe and the core places it to the deferred list but there will be no other driver going to load and the deferred queue is not going to be kicked again - till we have external event like connecting USB stick, etc. The proposed solution is to try the deferred queue once more when the last driver is asking for deferring and we had drivers loaded while this last driver was probing. This way we can avoid drivers stuck in the deferred queue. Signed-off-by: Grant Likely Reviewed-by: Peter Ujfalusi Tested-by: Peter Ujfalusi Acked-by: Greg Kroah-Hartman Cc: Mark Brown Cc: Stable # v3.4+ --- drivers/base/dd.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 8986b9f22781..62ec61e8f84a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -52,6 +52,7 @@ static DEFINE_MUTEX(deferred_probe_mutex); static LIST_HEAD(deferred_probe_pending_list); static LIST_HEAD(deferred_probe_active_list); static struct workqueue_struct *deferred_wq; +static atomic_t deferred_trigger_count = ATOMIC_INIT(0); /** * deferred_probe_work_func() - Retry probing devices in the active list. @@ -135,6 +136,17 @@ static bool driver_deferred_probe_enable = false; * This functions moves all devices from the pending list to the active * list and schedules the deferred probe workqueue to process them. It * should be called anytime a driver is successfully bound to a device. + * + * Note, there is a race condition in multi-threaded probe. In the case where + * more than one device is probing at the same time, it is possible for one + * probe to complete successfully while another is about to defer. If the second + * depends on the first, then it will get put on the pending list after the + * trigger event has already occured and will be stuck there. + * + * The atomic 'deferred_trigger_count' is used to determine if a successful + * trigger has occurred in the midst of probing a driver. If the trigger count + * changes in the midst of a probe, then deferred processing should be triggered + * again. */ static void driver_deferred_probe_trigger(void) { @@ -147,6 +159,7 @@ static void driver_deferred_probe_trigger(void) * into the active list so they can be retried by the workqueue */ mutex_lock(&deferred_probe_mutex); + atomic_inc(&deferred_trigger_count); list_splice_tail_init(&deferred_probe_pending_list, &deferred_probe_active_list); mutex_unlock(&deferred_probe_mutex); @@ -265,6 +278,7 @@ static DECLARE_WAIT_QUEUE_HEAD(probe_waitqueue); static int really_probe(struct device *dev, struct device_driver *drv) { int ret = 0; + int local_trigger_count = atomic_read(&deferred_trigger_count); atomic_inc(&probe_count); pr_debug("bus: '%s': %s: probing driver %s with device %s\n", @@ -310,6 +324,9 @@ static int really_probe(struct device *dev, struct device_driver *drv) /* Driver requested deferred probing */ dev_info(dev, "Driver %s requests probe deferral\n", drv->name); driver_deferred_probe_add(dev); + /* Did a trigger occur while probing? Need to re-trigger if yes */ + if (local_trigger_count != atomic_read(&deferred_trigger_count)) + driver_deferred_probe_trigger(); } else if (ret != -ENODEV && ret != -ENXIO) { /* driver matched but the probe failed */ printk(KERN_WARNING -- GitLab From fbcde3d8b9c2d97704b8ca299e5266147b24c8ee Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 29 Apr 2014 11:22:04 -0400 Subject: [PATCH 761/797] dm thin: use INIT_WORK_ONSTACK in noflush_work to avoid ODEBUG warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use INIT_WORK_ONSTACK to silence "ODEBUG: object is on stack, but not annotated". Reported-by: Zdeněk Kabeláč Signed-off-by: Mike Snitzer Acked-by: Joe Thornber --- drivers/md/dm-thin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 28fc282b61b2..13abade76ad9 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -1625,7 +1625,7 @@ static void noflush_work(struct thin_c *tc, void (*fn)(struct work_struct *)) { struct noflush_work w; - INIT_WORK(&w.worker, fn); + INIT_WORK_ONSTACK(&w.worker, fn); w.tc = tc; atomic_set(&w.complete, 0); init_waitqueue_head(&w.wait); -- GitLab From 6ba736dd02e7b3658c344efeb2f4a096a6785d83 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Apr 2014 18:38:21 +0200 Subject: [PATCH 762/797] ALSA: hda - Suppress CORBRP clear on Nvidia controller chips The recent commit (ca460f86521) changed the CORB RP reset procedure to follow the specification with a couple of sanity checks. Unfortunately, Nvidia controller chips seem not following this way, and spew the warning messages like: snd_hda_intel 0000:00:10.1: CORB reset timeout#1, CORBRP = 0 This patch adds the workaround for such chips. It just skips the new reset procedure for the known broken chips. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_controller.c | 34 ++++++++++++++++++---------------- sound/pci/hda/hda_intel.c | 3 ++- sound/pci/hda/hda_priv.h | 1 + 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 248b90abb882..480bbddbd801 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -1059,24 +1059,26 @@ static void azx_init_cmd_io(struct azx *chip) /* reset the corb hw read pointer */ azx_writew(chip, CORBRP, ICH6_CORBRP_RST); - for (timeout = 1000; timeout > 0; timeout--) { - if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST) - break; - udelay(1); - } - if (timeout <= 0) - dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n", - azx_readw(chip, CORBRP)); + if (!(chip->driver_caps & AZX_DCAPS_CORBRP_SELF_CLEAR)) { + for (timeout = 1000; timeout > 0; timeout--) { + if ((azx_readw(chip, CORBRP) & ICH6_CORBRP_RST) == ICH6_CORBRP_RST) + break; + udelay(1); + } + if (timeout <= 0) + dev_err(chip->card->dev, "CORB reset timeout#1, CORBRP = %d\n", + azx_readw(chip, CORBRP)); - azx_writew(chip, CORBRP, 0); - for (timeout = 1000; timeout > 0; timeout--) { - if (azx_readw(chip, CORBRP) == 0) - break; - udelay(1); + azx_writew(chip, CORBRP, 0); + for (timeout = 1000; timeout > 0; timeout--) { + if (azx_readw(chip, CORBRP) == 0) + break; + udelay(1); + } + if (timeout <= 0) + dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n", + azx_readw(chip, CORBRP)); } - if (timeout <= 0) - dev_err(chip->card->dev, "CORB reset timeout#2, CORBRP = %d\n", - azx_readw(chip, CORBRP)); /* enable corb dma */ azx_writeb(chip, CORBCTL, ICH6_CORBCTL_RUN); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index d6bca62ef387..b540ad71eb0d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -249,7 +249,8 @@ enum { /* quirks for Nvidia */ #define AZX_DCAPS_PRESET_NVIDIA \ (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI |\ - AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT) + AZX_DCAPS_ALIGN_BUFSIZE | AZX_DCAPS_NO_64BIT |\ + AZX_DCAPS_CORBRP_SELF_CLEAR) #define AZX_DCAPS_PRESET_CTHDA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_4K_BDLE_BOUNDARY) diff --git a/sound/pci/hda/hda_priv.h b/sound/pci/hda/hda_priv.h index ba38b819f984..4a7cb01fa912 100644 --- a/sound/pci/hda/hda_priv.h +++ b/sound/pci/hda/hda_priv.h @@ -189,6 +189,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ #define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 powerwell support */ +#define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */ /* position fix mode */ enum { -- GitLab From 3eba563e280101209bad27d40bfc83ddf1489234 Mon Sep 17 00:00:00 2001 From: Kieran Clancy Date: Wed, 30 Apr 2014 00:21:20 +0930 Subject: [PATCH 763/797] ACPI / EC: Process rather than discard events in acpi_ec_clear Address a regression caused by commit ad332c8a4533: (ACPI / EC: Clear stale EC events on Samsung systems) After the earlier patch, there was found to be a race condition on some earlier Samsung systems (N150/N210/N220). The function acpi_ec_clear was sometimes discarding a new EC event before its GPE was triggered by the system. In the case of these systems, this meant that the "lid open" event was not registered on resume if that was the cause of the wake, leading to problems when attempting to close the lid to suspend again. After testing on a number of Samsung systems, both those affected by the previous EC bug and those affected by the race condition, it seemed that the best course of action was to process rather than discard the events. On Samsung systems which accumulate stale EC events, there does not seem to be any adverse side-effects of running the associated _Q methods. This patch adds an argument to the static function acpi_ec_sync_query so that it may be used within the acpi_ec_clear loop in place of acpi_ec_query_unlocked which was used previously. With thanks to Stefan Biereigel for reporting the issue, and for all the people who helped test the new patch on affected systems. Fixes: ad332c8a4533 (ACPI / EC: Clear stale EC events on Samsung systems) References: https://lkml.kernel.org/r/532FE3B2.9060808@biereigel-wb.de References: https://bugzilla.kernel.org/show_bug.cgi?id=44161#c173 Reported-by: Stefan Biereigel Signed-off-by: Kieran Clancy Tested-by: Stefan Biereigel Tested-by: Dennis Jansen Tested-by: Nicolas Porcel Tested-by: Maurizio D'Addona Tested-by: Juan Manuel Cabo Tested-by: Giannis Koutsou Tested-by: Kieran Clancy Cc: 3.14+ # 3.14+ Signed-off-by: Rafael J. Wysocki --- drivers/acpi/ec.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index d7d32c28829b..ad11ba4a412d 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -206,13 +206,13 @@ static void advance_transaction(struct acpi_ec *ec, u8 status) spin_unlock_irqrestore(&ec->lock, flags); } -static int acpi_ec_sync_query(struct acpi_ec *ec); +static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data); static int ec_check_sci_sync(struct acpi_ec *ec, u8 state) { if (state & ACPI_EC_FLAG_SCI) { if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags)) - return acpi_ec_sync_query(ec); + return acpi_ec_sync_query(ec, NULL); } return 0; } @@ -443,10 +443,8 @@ acpi_handle ec_get_handle(void) EXPORT_SYMBOL(ec_get_handle); -static int acpi_ec_query_unlocked(struct acpi_ec *ec, u8 *data); - /* - * Clears stale _Q events that might have accumulated in the EC. + * Process _Q events that might have accumulated in the EC. * Run with locked ec mutex. */ static void acpi_ec_clear(struct acpi_ec *ec) @@ -455,7 +453,7 @@ static void acpi_ec_clear(struct acpi_ec *ec) u8 value = 0; for (i = 0; i < ACPI_EC_CLEAR_MAX; i++) { - status = acpi_ec_query_unlocked(ec, &value); + status = acpi_ec_sync_query(ec, &value); if (status || !value) break; } @@ -582,13 +580,18 @@ static void acpi_ec_run(void *cxt) kfree(handler); } -static int acpi_ec_sync_query(struct acpi_ec *ec) +static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data) { u8 value = 0; int status; struct acpi_ec_query_handler *handler, *copy; - if ((status = acpi_ec_query_unlocked(ec, &value))) + + status = acpi_ec_query_unlocked(ec, &value); + if (data) + *data = value; + if (status) return status; + list_for_each_entry(handler, &ec->list, node) { if (value == handler->query_bit) { /* have custom handler for this bit */ @@ -612,7 +615,7 @@ static void acpi_ec_gpe_query(void *ec_cxt) if (!ec) return; mutex_lock(&ec->mutex); - acpi_ec_sync_query(ec); + acpi_ec_sync_query(ec, NULL); mutex_unlock(&ec->mutex); } -- GitLab From b3413afb4a8995a67f5df6218c6d0ff3a53a6978 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 29 Apr 2014 00:20:34 +0200 Subject: [PATCH 764/797] PNP: Fix compile error in quirks.c Fix the compile error: drivers/pnp/quirks.c:393:2: error: implicit declaration of function 'pcibios_bus_to_resource' that occurs when building with CONFIG_PCI unset. The quirk is only relevent to Intel devices, so we could use "#if defined(CONFIG_X86) && defined(CONFIG_PCI)" instead, but testing CONFIG_X86 is not strictly necessary. Fixes: cb171f7abb9a (PNP: Work around BIOS defects in Intel MCH area reporting) Reported-by: Randy Dunlap Signed-off-by: Bjorn Helgaas Signed-off-by: Rafael J. Wysocki --- drivers/pnp/quirks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 3736bc408adb..ebf0d6710b5a 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -335,7 +335,7 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev) } #endif -#ifdef CONFIG_X86 +#ifdef CONFIG_PCI /* Device IDs of parts that have 32KB MCH space */ static const unsigned int mch_quirk_devices[] = { 0x0154, /* Ivy Bridge */ @@ -440,7 +440,7 @@ static struct pnp_fixup pnp_fixups[] = { #ifdef CONFIG_AMD_NB {"PNP0c01", quirk_amd_mmconfig_area}, #endif -#ifdef CONFIG_X86 +#ifdef CONFIG_PCI {"PNP0c02", quirk_intel_mch}, #endif {""} -- GitLab From 25c8b5c3048cb6c98d402ca8d4735ccf910f727c Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Tue, 15 Apr 2014 15:33:01 +0200 Subject: [PATCH 765/797] drm/exynos: balance framebuffer refcount exynos_drm_crtc_mode_set assigns primary framebuffer to plane without taking reference. Then during framebuffer removal it is dereferenced twice, causing oops. The patch fixes it. Signed-off-by: Andrzej Hajda Signed-off-by: Inki Dae Signed-off-by: Dave Airlie --- drivers/gpu/drm/exynos/exynos_drm_crtc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index e930d4fe29c7..1ef5ab9c9d51 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -145,6 +145,7 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, plane->crtc = crtc; plane->fb = crtc->primary->fb; + drm_framebuffer_reference(plane->fb); return 0; } -- GitLab From e2a75c446e38ddf32ccdeb6e8cf2baa61fd8510f Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 10 Apr 2014 20:24:03 +0900 Subject: [PATCH 766/797] MAINTAINERS: update maintainer entry for Exynos DP driver Recently, Exynos DP driver was moved from drivers/video/exynos/ directory to drivers/gpu/drm/exynos/ directory. So, I update and add maintainer entry for Exynos DP driver. Signed-off-by: Jingoo Han Signed-off-by: Inki Dae Signed-off-by: Dave Airlie --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e67ea2442041..ea44a57f790e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3485,6 +3485,12 @@ S: Maintained F: drivers/extcon/ F: Documentation/extcon/ +EXYNOS DP DRIVER +M: Jingoo Han +L: dri-devel@lists.freedesktop.org +S: Maintained +F: drivers/gpu/drm/exynos/exynos_dp* + EXYNOS MIPI DISPLAY DRIVERS M: Inki Dae M: Donghwa Lee -- GitLab From 293d3f6a70704691c3539bc3630ba1acbabc5c43 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 17 Apr 2014 19:08:40 +0900 Subject: [PATCH 767/797] drm/exynos: dsi: use IS_ERR() to check devm_ioremap_resource() results devm_ioremap_resource() returns an error pointer, not NULL. Thus, the result should be checked with IS_ERR(). Signed-off-by: Jingoo Han Signed-off-by: Inki Dae Signed-off-by: Dave Airlie --- drivers/gpu/drm/exynos/exynos_drm_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dsi.c b/drivers/gpu/drm/exynos/exynos_drm_dsi.c index eb73e3bf2a0c..4ac438187568 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dsi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dsi.c @@ -1426,9 +1426,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dsi->reg_base = devm_ioremap_resource(&pdev->dev, res); - if (!dsi->reg_base) { + if (IS_ERR(dsi->reg_base)) { dev_err(&pdev->dev, "failed to remap io region\n"); - return -EADDRNOTAVAIL; + return PTR_ERR(dsi->reg_base); } dsi->phy = devm_phy_get(&pdev->dev, "dsim"); -- GitLab From b8eade24c9891b8f153c40cf310ef4696c873af9 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Tue, 22 Apr 2014 14:45:32 +0900 Subject: [PATCH 768/797] drm/exynos: use %pad for dma_addr_t Use %pad for dma_addr_t, because a dma_addr_t type can vary based on build options. So, it prevents possible build warnings in printks. Signed-off-by: Jingoo Han Reviewed-by: Daniel Kurtz Signed-off-by: Inki Dae Signed-off-by: Dave Airlie --- drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 2 +- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index c786cd4f457b..2a3ad24276f8 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -263,7 +263,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, buffer->sgt = sgt; exynos_gem_obj->base.import_attach = attach; - DRM_DEBUG_PRIME("dma_addr = 0x%x, size = 0x%lx\n", buffer->dma_addr, + DRM_DEBUG_PRIME("dma_addr = %pad, size = 0x%lx\n", &buffer->dma_addr, buffer->size); return &exynos_gem_obj->base; diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 7afead9c3f30..852f2dadaebd 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -220,7 +220,7 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) win_data->enabled = true; - DRM_DEBUG_KMS("dma_addr = 0x%x\n", win_data->dma_addr); + DRM_DEBUG_KMS("dma_addr = %pad\n", &win_data->dma_addr); if (ctx->vblank_on) schedule_work(&ctx->work); -- GitLab From 6c6c0d5a1c949d2e084706f9e5fb1fccc175b265 Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Tue, 29 Apr 2014 17:55:02 -0500 Subject: [PATCH 769/797] hrtimer: Prevent all reprogramming if hang detected If the last hrtimer interrupt detected a hang it sets hang_detected=1 and programs the clock event device with a delay to let the system make progress. If hang_detected == 1, we prevent reprogramming of the clock event device in hrtimer_reprogram() but not in hrtimer_force_reprogram(). This can lead to the following situation: hrtimer_interrupt() hang_detected = 1; program ce device to Xms from now (hang delay) We have two timers pending: T1 expires 50ms from now T2 expires 5s from now Now T1 gets canceled, which causes hrtimer_force_reprogram() to be invoked, which in turn programs the clock event device to T2 (5 seconds from now). Any hrtimer_start after that will not reprogram the hardware due to hang_detected still being set. So we effectivly block all timers until the T2 event fires and cleans up the hang situation. Add a check for hang_detected to hrtimer_force_reprogram() which prevents the reprogramming of the hang delay in the hardware timer. The subsequent hrtimer_interrupt will resolve all outstanding issues. [ tglx: Rewrote subject and changelog and fixed up the comment in hrtimer_force_reprogram() ] Signed-off-by: Stuart Hayes Link: http://lkml.kernel.org/r/53602DC6.2060101@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Thomas Gleixner --- kernel/hrtimer.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index d55092ceee29..e3724fdac2da 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -569,6 +569,23 @@ hrtimer_force_reprogram(struct hrtimer_cpu_base *cpu_base, int skip_equal) cpu_base->expires_next.tv64 = expires_next.tv64; + /* + * If a hang was detected in the last timer interrupt then we + * leave the hang delay active in the hardware. We want the + * system to make progress. That also prevents the following + * scenario: + * T1 expires 50ms from now + * T2 expires 5s from now + * + * T1 is removed, so this code is called and would reprogram + * the hardware to 5s from now. Any hrtimer_start after that + * will not reprogram the hardware due to hang_detected being + * set. So we'd effectivly block all timers until the T2 event + * fires. + */ + if (cpu_base->hang_detected) + return; + if (cpu_base->expires_next.tv64 != KTIME_MAX) tick_program_event(cpu_base->expires_next, 1); } -- GitLab From 012a45e3f4af68e86d85cce060c6c2fed56498b2 Mon Sep 17 00:00:00 2001 From: Leon Ma Date: Wed, 30 Apr 2014 16:43:10 +0800 Subject: [PATCH 770/797] hrtimer: Prevent remote enqueue of leftmost timers If a cpu is idle and starts an hrtimer which is not pinned on that same cpu, the nohz code might target the timer to a different cpu. In the case that we switch the cpu base of the timer we already have a sanity check in place, which determines whether the timer is earlier than the current leftmost timer on the target cpu. In that case we enqueue the timer on the current cpu because we cannot reprogram the clock event device on the target. If the timers base is already the target CPU we do not have this sanity check in place so we enqueue the timer as the leftmost timer in the target cpus rb tree, but we cannot reprogram the clock event device on the target cpu. So the timer expires late and subsequently prevents the reprogramming of the target cpu clock event device until the previously programmed event fires or a timer with an earlier expiry time gets enqueued on the target cpu itself. Add the same target check as we have for the switch base case and start the timer on the current cpu if it would become the leftmost timer on the target. [ tglx: Rewrote subject and changelog ] Signed-off-by: Leon Ma Link: http://lkml.kernel.org/r/1398847391-5994-1-git-send-email-xindong.ma@intel.com Cc: stable@vger.kernel.org Signed-off-by: Thomas Gleixner --- kernel/hrtimer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index e3724fdac2da..6b715c0af1b1 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -234,6 +234,11 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base, goto again; } timer->base = new_base; + } else { + if (cpu != this_cpu && hrtimer_check_target(timer, new_base)) { + cpu = this_cpu; + goto again; + } } return new_base; } -- GitLab From 98a01e779f3c66b0b11cd7e64d531c0e41c95762 Mon Sep 17 00:00:00 2001 From: Jiri Bohac Date: Fri, 18 Apr 2014 17:23:11 +0200 Subject: [PATCH 771/797] timer: Prevent overflow in apply_slack On architectures with sizeof(int) < sizeof (long), the computation of mask inside apply_slack() can be undefined if the computed bit is > 32. E.g. with: expires = 0xffffe6f5 and slack = 25, we get: expires_limit = 0x20000000e bit = 33 mask = (1 << 33) - 1 /* undefined */ On x86, mask becomes 1 and and the slack is not applied properly. On s390, mask is -1, expires is set to 0 and the timer fires immediately. Use 1UL << bit to solve that issue. Suggested-by: Deborah Townsend Signed-off-by: Jiri Bohac Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/20140418152310.GA13654@midget.suse.cz Signed-off-by: Thomas Gleixner --- kernel/timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/timer.c b/kernel/timer.c index 87bd529879c2..3bb01a323b2a 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -838,7 +838,7 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires) bit = find_last_bit(&mask, BITS_PER_LONG); - mask = (1 << bit) - 1; + mask = (1UL << bit) - 1; expires_limit = expires_limit & ~(mask); -- GitLab From e27a08f53d081b33c988db954008d879b2ab8b39 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 27 Apr 2014 11:12:21 +0200 Subject: [PATCH 772/797] perf tools: Use LDFLAGS instead of ALL_LDFLAGS We no longer use ALL_LDFLAGS, Replacing with LDFLAGS. Acked-by: Namhyung Kim Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1398675770-3109-1-git-send-email-jolsa@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/Makefile.perf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index e96923310d57..895edd32930c 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -589,7 +589,7 @@ $(GTK_OBJS): $(OUTPUT)%.o: %.c $(LIB_H) $(QUIET_CC)$(CC) -o $@ -c -fPIC $(CFLAGS) $(GTK_CFLAGS) $< $(OUTPUT)libperf-gtk.so: $(GTK_OBJS) $(PERFLIBS) - $(QUIET_LINK)$(CC) -o $@ -shared $(ALL_LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) + $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \ -- GitLab From 2cf9040714f3e63f94935c9f1ed4e5bc54265ddb Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 23 Apr 2014 16:53:25 +0200 Subject: [PATCH 773/797] perf tools: Fix bfd dependency libraries detection There's false assumption in the library detection code assuming -liberty and -lz are always present once bfd is detected. The fails on Ubuntu (14.04) as reported by Ingo. Forcing the bdf dependency libraries detection any time bfd library is detected. Reported-by: Ingo Molnar Tested-by: Ingo Molnar Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1398676935-6615-1-git-send-email-jolsa@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/config/Makefile | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index a71fb395e38f..a57d59e7fe4b 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -194,7 +194,10 @@ VF_FEATURE_TESTS = \ stackprotector-all \ timerfd \ libunwind-debug-frame \ - bionic + bionic \ + liberty \ + liberty-z \ + cplus-demangle # Set FEATURE_CHECK_(C|LD)FLAGS-all for all CORE_FEATURE_TESTS features. # If in the future we need per-feature checks/flags for features not @@ -512,7 +515,21 @@ else endif ifeq ($(feature-libbfd), 1) - EXTLIBS += -lbfd -lz -liberty + EXTLIBS += -lbfd + + # call all detections now so we get correct + # status in VF output + $(call feature_check,liberty) + $(call feature_check,liberty-z) + $(call feature_check,cplus-demangle) + + ifeq ($(feature-liberty), 1) + EXTLIBS += -liberty + else + ifeq ($(feature-liberty-z), 1) + EXTLIBS += -liberty -lz + endif + endif endif ifdef NO_DEMANGLE @@ -523,15 +540,10 @@ else CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT else ifneq ($(feature-libbfd), 1) - $(call feature_check,liberty) - ifeq ($(feature-liberty), 1) - EXTLIBS += -lbfd -liberty - else - $(call feature_check,liberty-z) - ifeq ($(feature-liberty-z), 1) - EXTLIBS += -lbfd -liberty -lz - else - $(call feature_check,cplus-demangle) + ifneq ($(feature-liberty), 1) + ifneq ($(feature-liberty-z), 1) + # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT + # or any of 'bfd iberty z' trinity ifeq ($(feature-cplus-demangle), 1) EXTLIBS += -liberty CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT -- GitLab From 611ec127165b572f02823e152d6774e2145305a3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 29 Apr 2014 09:53:40 +0200 Subject: [PATCH 774/797] perf tests: Add static build make test Adding test for building static perf build into the automated suite. Also available via following commands: $ make -f tests/make make_static - make_static: cd . && make -f Makefile DESTDIR=/tmp/tmp.7u5MlB4njo LDFLAGS=-static $ make -f tests/make make_static_O - make_static_O: cd . && make -f Makefile O=/tmp/tmp.Ay6r3wEmtX DESTDIR=/tmp/tmp.vK0KQwO0Vi LDFLAGS=-static Acked-by: David Ahern Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1398760413-7574-1-git-send-email-jolsa@kernel.org Signed-off-by: Jiri Olsa --- tools/perf/tests/make | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 5daeae1cb4c0..2f92d6e7ee00 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -46,6 +46,7 @@ make_install_man := install-man make_install_html := install-html make_install_info := install-info make_install_pdf := install-pdf +make_static := LDFLAGS=-static # all the NO_* variable combined make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 @@ -87,6 +88,7 @@ run += make_install_bin # run += make_install_info # run += make_install_pdf run += make_minimal +run += make_static ifneq ($(call has,ctags),) run += make_tags -- GitLab From 61d4290cc1f10588147b76b385875f06827d47ff Mon Sep 17 00:00:00 2001 From: Richard Yao Date: Sat, 26 Apr 2014 13:17:55 -0400 Subject: [PATCH 775/797] perf machine: Search for modules in %s/lib/modules/%s Modules installed outside of the kernel's build system should go into "%s/lib/modules/%s/extra", but at present, perf will only look at them when they are in "%s/lib/modules/%s/kernel". Lets encourage good citizenship by relaxing this requirement to "%s/lib/modules/%s". This way open source modules that are out-of-tree have no incentive to start populating a directory reserved for in-kernel modules and I can stop hex-editing my system's perf binary when profiling OSS out-of-tree modules. Feedback from Namhyung Kim correctly revealed that the hex-edits that I had been doing meant that perf was also traversing the build and source symlinks in %s/lib/modules/%s. That is undesireable, so we explicitly exclude them from traversal with a minor tweak to the traversal routine. Signed-off-by: Richard Yao Acked-by: Namhyung kim Link: http://lkml.kernel.org/r/1398532675-13684-1-git-send-email-ryao@gentoo.org Signed-off-by: Jiri Olsa --- tools/perf/util/machine.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index a53cd0b8c151..27c2a5efe450 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -717,7 +717,7 @@ static char *get_kernel_version(const char *root_dir) } static int map_groups__set_modules_path_dir(struct map_groups *mg, - const char *dir_name) + const char *dir_name, int depth) { struct dirent *dent; DIR *dir = opendir(dir_name); @@ -742,7 +742,15 @@ static int map_groups__set_modules_path_dir(struct map_groups *mg, !strcmp(dent->d_name, "..")) continue; - ret = map_groups__set_modules_path_dir(mg, path); + /* Do not follow top-level source and build symlinks */ + if (depth == 0) { + if (!strcmp(dent->d_name, "source") || + !strcmp(dent->d_name, "build")) + continue; + } + + ret = map_groups__set_modules_path_dir(mg, path, + depth + 1); if (ret < 0) goto out; } else { @@ -786,11 +794,11 @@ static int machine__set_modules_path(struct machine *machine) if (!version) return -1; - snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", + snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s", machine->root_dir, version); free(version); - return map_groups__set_modules_path_dir(&machine->kmaps, modules_path); + return map_groups__set_modules_path_dir(&machine->kmaps, modules_path, 0); } static int machine__create_module(void *arg, const char *name, u64 start) -- GitLab From 603940b6b8b1347ec13a628165c00194ebc17ed2 Mon Sep 17 00:00:00 2001 From: Xia Kaixu Date: Sat, 26 Apr 2014 15:55:12 +0800 Subject: [PATCH 776/797] perf tools: Remove extra '/' character in events file path The array debugfs_known_mountpoints[] will cause extra '/' character output. Remove it. pre: $ perf probe -l /sys/kernel/debug//tracing/uprobe_events file does not exist - please rebuild kernel with CONFIG_UPROBE_EVENTS. post: $ perf probe -l /sys/kernel/debug/tracing/uprobe_events file does not exist - please rebuild kernel with CONFIG_UPROBE_EVENTS. Signed-off-by: Xia Kaixu Acked-by: Namhyung Kim Link: http://lkml.kernel.org/r/535B6660.2060001@huawei.com Signed-off-by: Jiri Olsa --- tools/lib/api/fs/debugfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/api/fs/debugfs.c b/tools/lib/api/fs/debugfs.c index 7c4347962353..a74fba6d7743 100644 --- a/tools/lib/api/fs/debugfs.c +++ b/tools/lib/api/fs/debugfs.c @@ -12,8 +12,8 @@ char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; static const char * const debugfs_known_mountpoints[] = { - "/sys/kernel/debug/", - "/debug/", + "/sys/kernel/debug", + "/debug", 0, }; -- GitLab From 6392b4ebdc1acfbed605d68c437ff5597d0a8d95 Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sun, 27 Apr 2014 18:51:05 +0200 Subject: [PATCH 777/797] perf x86: Fix perf to use non-executable stack, again arch/x86/tests/regs_load.S is missing the linker note about the stack requirements, therefore making the linker fall back to an executable stack. As this object gets linked against the final perf binary, it'll needlessly end up with an executable stack. Fix this by adding the appropriate linker note. Also add a global linker flag to prevent future regressions, as suggested by Jiri. This way perf won't get an executable stack even if we fail to add the .GNU-stack linker note to future assembler files. Though, doing so might create regressions the other way around, when (statically) linking against libraries needing an executable stack. But, apparently, regressing in that direction is wanted as it is an indicator of poor code quality -- or just missing linker notes. Fixes: 3c8b06f981 ("perf tests x86: Introduce perf_regs_load function") Signed-off-by: Mathias Krause Acked-by: Ingo Molnar Cc: Arnaldo Carvalho de Melo Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1398617466-22749-1-git-send-email-minipli@googlemail.com Signed-off-by: Jiri Olsa --- tools/perf/arch/x86/tests/regs_load.S | 8 +++++++- tools/perf/config/Makefile | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/tests/regs_load.S b/tools/perf/arch/x86/tests/regs_load.S index 99167bf644ea..60875d5c556c 100644 --- a/tools/perf/arch/x86/tests/regs_load.S +++ b/tools/perf/arch/x86/tests/regs_load.S @@ -1,4 +1,3 @@ - #include #define AX 0 @@ -90,3 +89,10 @@ ENTRY(perf_regs_load) ret ENDPROC(perf_regs_load) #endif + +/* + * We need to provide note.GNU-stack section, saying that we want + * NOT executable stack. Otherwise the final linking will assume that + * the ELF stack should not be restricted at all and set it RWX. + */ +.section .note.GNU-stack,"",@progbits diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index a57d59e7fe4b..802cf544202b 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -117,6 +117,10 @@ CFLAGS += -Wall CFLAGS += -Wextra CFLAGS += -std=gnu99 +# Enforce a non-executable stack, as we may regress (again) in the future by +# adding assembler files missing the .GNU-stack linker note. +LDFLAGS += -Wl,-z,noexecstack + EXTLIBS = -lelf -lpthread -lrt -lm -ldl ifneq ($(OUTPUT),) -- GitLab From 9a126728165eef9b1e9349fe57b9747ac6c6f7e3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 30 Apr 2014 16:39:44 +0200 Subject: [PATCH 778/797] perf tests x86: Fix stack map lookup in dwarf unwind test Previous commit 'perf x86: Fix perf to use non-executable stack, again' moved stack map into MAP__VARIABLE map type again. Fixing the dwarf unwind test stack map lookup appropriately. Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Jean Pihet Link: http://lkml.kernel.org/n/tip-ttzyhbe4zls24z7ednkmhvxl@git.kernel.org Signed-off-by: Jiri Olsa --- tools/perf/arch/x86/tests/dwarf-unwind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/arch/x86/tests/dwarf-unwind.c b/tools/perf/arch/x86/tests/dwarf-unwind.c index b8c0102c70c8..83bc2385e6d3 100644 --- a/tools/perf/arch/x86/tests/dwarf-unwind.c +++ b/tools/perf/arch/x86/tests/dwarf-unwind.c @@ -23,7 +23,7 @@ static int sample_ustack(struct perf_sample *sample, sp = (unsigned long) regs[PERF_REG_X86_SP]; - map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp); + map = map_groups__find(&thread->mg, MAP__VARIABLE, (u64) sp); if (!map) { pr_debug("failed to get stack map\n"); free(buf); -- GitLab From 8aa9e85adac609588eeec356e5a85059b3b819ba Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Wed, 30 Apr 2014 15:26:45 +0530 Subject: [PATCH 779/797] ARC: !PREEMPT: Ensure Return to kernel mode is IRQ safe There was a very small race window where resume to kernel mode from a Exception Path (or pure kernel mode which is true for most of ARC exceptions anyways), was not disabling interrupts in restore_regs, clobbering the exception regs Anton found the culprit call flow (after many sleepless nights) | 1. we got a Trap from user land | 2. started to service it. | 3. While doing some stuff on user-land memory (I think it is padzero()), | we got a DataTlbMiss | 4. On return from it we are taking "resume_kernel_mode" path | 5. NEED_RESHED is not set, so we go to "return from exception" path in | restore regs. | 6. there seems to be IRQ happening Signed-off-by: Vineet Gupta Cc: #3.10, 3.12, 3.13, 3.14 Cc: Anton Kolesov Cc: Francois Bedard Signed-off-by: Linus Torvalds --- arch/arc/kernel/entry.S | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S index 819dd5f7eb05..29b82adbf0b4 100644 --- a/arch/arc/kernel/entry.S +++ b/arch/arc/kernel/entry.S @@ -614,11 +614,13 @@ resume_user_mode_begin: resume_kernel_mode: -#ifdef CONFIG_PREEMPT - - ; This is a must for preempt_schedule_irq() + ; Disable Interrupts from this point on + ; CONFIG_PREEMPT: This is a must for preempt_schedule_irq() + ; !CONFIG_PREEMPT: To ensure restore_regs is intr safe IRQ_DISABLE r9 +#ifdef CONFIG_PREEMPT + ; Can't preempt if preemption disabled GET_CURR_THR_INFO_FROM_SP r10 ld r8, [r10, THREAD_INFO_PREEMPT_COUNT] -- GitLab From 8c836fa85bebfea26ceff024b5d1c518bf63f3d8 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Wed, 30 Apr 2014 13:28:17 -0400 Subject: [PATCH 780/797] MAINTAINERS: email address change for Jeff Layton jlayton@redhat.com -> jlayton@poochiereds.net Signed-off-by: Jeff Layton --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index ea44a57f790e..37a36aa94177 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3556,7 +3556,7 @@ F: include/scsi/libfcoe.h F: include/uapi/scsi/fc/ FILE LOCKING (flock() and fcntl()/lockf()) -M: Jeff Layton +M: Jeff Layton M: J. Bruce Fields L: linux-fsdevel@vger.kernel.org S: Maintained -- GitLab From a8d22396302b7e4e5f0a594c1c1594388c29edaf Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 30 Apr 2014 22:36:33 +0200 Subject: [PATCH 781/797] PNP / ACPI: Do not return errors if _DIS or _SRS are not present The ACPI PNP subsystem returns errors from pnpacpi_set_resources() and pnpacpi_disable_resources() if the _SRS or _DIS methods are not present, respectively, but it should not do that, because those methods are optional. For this reason, modify pnpacpi_set_resources() and pnpacpi_disable_resources(), respectively, to ignore missing _SRS or _DIS. This problem has been uncovered by commit 202317a573b2 (ACPI / scan: Add acpi_device objects for all device nodes in the namespace) and manifested itself by causing serial port suspend to fail on some systems. Fixes: 202317a573b2 (ACPI / scan: Add acpi_device objects for all device nodes in the namespace) References: https://bugzilla.kernel.org/show_bug.cgi?id=74371 Reported-by: wxg4net Reported-and-tested-by: Cc: 3.14+ # 3.14+ Signed-off-by: Rafael J. Wysocki --- drivers/pnp/pnpacpi/core.c | 44 ++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9f611cbbc294..c31aa07b3ba5 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -83,8 +83,7 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) { struct acpi_device *acpi_dev; acpi_handle handle; - struct acpi_buffer buffer; - int ret; + int ret = 0; pnp_dbg(&dev->dev, "set resources\n"); @@ -97,19 +96,26 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) if (WARN_ON_ONCE(acpi_dev != dev->data)) dev->data = acpi_dev; - ret = pnpacpi_build_resource_template(dev, &buffer); - if (ret) - return ret; - ret = pnpacpi_encode_resources(dev, &buffer); - if (ret) { + if (acpi_has_method(handle, METHOD_NAME__SRS)) { + struct acpi_buffer buffer; + + ret = pnpacpi_build_resource_template(dev, &buffer); + if (ret) + return ret; + + ret = pnpacpi_encode_resources(dev, &buffer); + if (!ret) { + acpi_status status; + + status = acpi_set_current_resources(handle, &buffer); + if (ACPI_FAILURE(status)) + ret = -EIO; + } kfree(buffer.pointer); - return ret; } - if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer))) - ret = -EINVAL; - else if (acpi_bus_power_manageable(handle)) + if (!ret && acpi_bus_power_manageable(handle)) ret = acpi_bus_set_power(handle, ACPI_STATE_D0); - kfree(buffer.pointer); + return ret; } @@ -117,7 +123,7 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) { struct acpi_device *acpi_dev; acpi_handle handle; - int ret; + acpi_status status; dev_dbg(&dev->dev, "disable resources\n"); @@ -128,13 +134,15 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) } /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ - ret = 0; if (acpi_bus_power_manageable(handle)) acpi_bus_set_power(handle, ACPI_STATE_D3_COLD); - /* continue even if acpi_bus_set_power() fails */ - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL))) - ret = -ENODEV; - return ret; + + /* continue even if acpi_bus_set_power() fails */ + status = acpi_evaluate_object(handle, "_DIS", NULL, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) + return -ENODEV; + + return 0; } #ifdef CONFIG_ACPI_SLEEP -- GitLab From 4985c32ee4241d1aba1beeac72294faa46aaff10 Mon Sep 17 00:00:00 2001 From: Lan Tianyu Date: Wed, 30 Apr 2014 15:46:33 +0800 Subject: [PATCH 782/797] ACPI / processor: Fix failure of loading acpi-cpufreq driver According commit d640113fe (ACPI: processor: fix acpi_get_cpuid for UP processor), BIOS may not provide _MAT or MADT tables and acpi_get_apicid() always returns -1. For these cases, original code will pass apic_id with vaule of -1 to acpi_map_cpuid() and it will check the acpi_id. If acpi_id is equal to zero, ignores apic_id and return zero for CPU0. Commit b981513 (ACPI / scan: bail out early if failed to parse APIC ID for CPU) changed the behavior. Return ENODEV when find apic_id is less than zero after calling acpi_get_apicid(). This causes acpi-cpufreq driver fails to be loaded on some machines. This patch is to fix it. Fixes: b981513f806d (ACPI / scan: bail out early if failed to parse APIC ID for CPU) References: https://bugzilla.kernel.org/show_bug.cgi?id=73781 Cc: 3.14+ # 3.14+ Reported-and-tested-by: KATO Hiroshi Reported-and-tested-by: Stuart Foster Signed-off-by: Lan Tianyu Signed-off-by: Rafael J. Wysocki --- drivers/acpi/acpi_processor.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index c29c2c3ec0ad..b06f5f55ada9 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -170,6 +170,9 @@ static int acpi_processor_hotadd_init(struct acpi_processor *pr) acpi_status status; int ret; + if (pr->apic_id == -1) + return -ENODEV; + status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta); if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) return -ENODEV; @@ -260,10 +263,8 @@ static int acpi_processor_get_info(struct acpi_device *device) } apic_id = acpi_get_apicid(pr->handle, device_declaration, pr->acpi_id); - if (apic_id < 0) { + if (apic_id < 0) acpi_handle_debug(pr->handle, "failed to get CPU APIC ID.\n"); - return -ENODEV; - } pr->apic_id = apic_id; cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); -- GitLab From c0940e95f7a78be0525c8d31df0b1f71e149e57e Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 30 Apr 2014 14:08:14 -0700 Subject: [PATCH 783/797] Revert "hwmon: (coretemp) Refine TjMax detection" This reverts commit 9fb6c9c73b11bef65ba80a362547fd116c1e1c9d. Tjmax on some Intel CPUs is below 85 degrees C. One known example is L5630 with Tjmax of 71 degrees C. There are other Xeon processors with Tjmax of 70 or 80 degrees C. Also, the Intel IA32 System Programming document states that the temperature target is in bits 23:16 of MSR 0x1a2 (MSR_TEMPERATURE_TARGET), which is 8 bits, not 7. So even if turbostat uses similar checks to validate Tjmax, there is no evidence that the checks are actually required. On the contrary, the checks are known to cause problems and therefore need to be removed. This fixes https://bugzilla.kernel.org/show_bug.cgi?id=75071. Fixes: 9fb6c9c hwmon: (coretemp) Refine TjMax detection Reviewed-by: Jean Delvare Cc: stable@vger.kernel.org # 3.14+ Signed-off-by: Guenter Roeck --- drivers/hwmon/coretemp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index 6d02e3b06375..d76f0b70c6e0 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -365,12 +365,12 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev) if (cpu_has_tjmax(c)) dev_warn(dev, "Unable to read TjMax from CPU %u\n", id); } else { - val = (eax >> 16) & 0x7f; + val = (eax >> 16) & 0xff; /* * If the TjMax is not plausible, an assumption * will be used */ - if (val >= 85) { + if (val) { dev_dbg(dev, "TjMax is %d degrees C\n", val); return val * 1000; } -- GitLab From 754320d6e166d3a12cb4810a452bde00afbd4e9a Mon Sep 17 00:00:00 2001 From: Leon Yu Date: Thu, 1 May 2014 03:31:28 +0000 Subject: [PATCH 784/797] aio: fix potential leak in aio_run_iocb(). iovec should be reclaimed whenever caller of rw_copy_check_uvector() returns, but it doesn't hold when failure happens right after aio_setup_vectored_rw(). Fix that in a such way to avoid hairy goto. Signed-off-by: Leon Yu Signed-off-by: Benjamin LaHaise Cc: stable@vger.kernel.org --- fs/aio.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 2adbb0398ab9..a0ed6c7d2cd2 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -1327,10 +1327,8 @@ static ssize_t aio_run_iocb(struct kiocb *req, unsigned opcode, &iovec, compat) : aio_setup_single_vector(req, rw, buf, &nr_segs, iovec); - if (ret) - return ret; - - ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); + if (!ret) + ret = rw_verify_area(rw, file, &req->ki_pos, req->ki_nbytes); if (ret < 0) { if (iovec != &inline_vec) kfree(iovec); -- GitLab From 789ce9dca8007ab5d7c72b9a174a29243817ac32 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Wed, 30 Apr 2014 14:22:19 -0700 Subject: [PATCH 785/797] word-at-a-time: simplify big-endian zero_bytemask macro This is simpler and cleaner. Depending on architecture, a smart compiler may or may not generate the same code. Acked-by: Will Deacon Signed-off-by: Linus Torvalds --- include/asm-generic/word-at-a-time.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-generic/word-at-a-time.h b/include/asm-generic/word-at-a-time.h index d96deb443f18..94f9ea8abcae 100644 --- a/include/asm-generic/word-at-a-time.h +++ b/include/asm-generic/word-at-a-time.h @@ -50,7 +50,7 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct } #ifndef zero_bytemask -#define zero_bytemask(mask) (~0ul << __fls(mask) << 1) +#define zero_bytemask(mask) (~1ul << __fls(mask)) #endif #endif /* _ASM_WORD_AT_A_TIME_H */ -- GitLab From b7e1bd964812808710b48a5f9a58f7ddfb1d4e59 Mon Sep 17 00:00:00 2001 From: Vineet Gupta Date: Fri, 18 Apr 2014 13:38:35 +0530 Subject: [PATCH 786/797] Hexagon: Delete stale barrier.h Commit 93ea02bb8435 ("arch: Clean up asm/barrier.h implementations") wired generic barrier.h for hexagon, but failed to delete the existing file. Cc: Richard Kuo Cc: Peter Zijlstra Signed-off-by: Vineet Gupta Compile-tested-by: Guenter Roeck Signed-off-by: Linus Torvalds --- arch/hexagon/include/asm/barrier.h | 37 ------------------------------ 1 file changed, 37 deletions(-) delete mode 100644 arch/hexagon/include/asm/barrier.h diff --git a/arch/hexagon/include/asm/barrier.h b/arch/hexagon/include/asm/barrier.h deleted file mode 100644 index 4e863daea25b..000000000000 --- a/arch/hexagon/include/asm/barrier.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Memory barrier definitions for the Hexagon architecture - * - * Copyright (c) 2010-2011, 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. - * - * 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. - */ - -#ifndef _ASM_BARRIER_H -#define _ASM_BARRIER_H - -#define rmb() barrier() -#define read_barrier_depends() barrier() -#define wmb() barrier() -#define mb() barrier() -#define smp_rmb() barrier() -#define smp_read_barrier_depends() barrier() -#define smp_wmb() barrier() -#define smp_mb() barrier() - -/* Set a value and use a memory barrier. Used by the scheduler somewhere. */ -#define set_mb(var, value) \ - do { var = value; mb(); } while (0) - -#endif /* _ASM_BARRIER_H */ -- GitLab From e0d8898d76a785453bfaf6cd08b830a7d5189f78 Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sun, 27 Apr 2014 16:20:47 -0400 Subject: [PATCH 787/797] parisc: remove _STK_LIM_MAX override There are only a couple of architectures that override _STK_LIM_MAX to a non-infinity value. This changes the stack allocation semantics in subtle ways. For example, GNU make changes its stack allocation to the hard maximum defined by _STK_LIM_MAX. As a results, threads executed by processes running under make are allocated a stack size of _STK_LIM_MAX rather than a sensible default value. This causes various thread stress tests to fail when they can't muster more than about 50 threads. The attached change implements the default behavior used by the majority of architectures. Signed-off-by: John David Anglin Reviewed-by: Carlos O'Donell Cc: stable@vger.kernel.org # 3.14 Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/resource.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/parisc/include/uapi/asm/resource.h b/arch/parisc/include/uapi/asm/resource.h index 8b06343b62ed..090483c47dbb 100644 --- a/arch/parisc/include/uapi/asm/resource.h +++ b/arch/parisc/include/uapi/asm/resource.h @@ -1,7 +1,6 @@ #ifndef _ASM_PARISC_RESOURCE_H #define _ASM_PARISC_RESOURCE_H -#define _STK_LIM_MAX 10 * _STK_LIM #include #endif -- GitLab From 8a415e534dbda905b829320f90c9ce5f7359debf Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 29 Apr 2014 16:13:22 +0200 Subject: [PATCH 788/797] parisc: Use generic uapi/asm/resource.h file Signed-off-by: Helge Deller --- arch/parisc/include/uapi/asm/Kbuild | 3 ++- arch/parisc/include/uapi/asm/resource.h | 6 ------ 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 arch/parisc/include/uapi/asm/resource.h diff --git a/arch/parisc/include/uapi/asm/Kbuild b/arch/parisc/include/uapi/asm/Kbuild index a580642555b6..348356c99514 100644 --- a/arch/parisc/include/uapi/asm/Kbuild +++ b/arch/parisc/include/uapi/asm/Kbuild @@ -1,6 +1,8 @@ # UAPI Header export list include include/uapi/asm-generic/Kbuild.asm +generic-y += resource.h + header-y += bitsperlong.h header-y += byteorder.h header-y += errno.h @@ -13,7 +15,6 @@ header-y += msgbuf.h header-y += pdc.h header-y += posix_types.h header-y += ptrace.h -header-y += resource.h header-y += sembuf.h header-y += setup.h header-y += shmbuf.h diff --git a/arch/parisc/include/uapi/asm/resource.h b/arch/parisc/include/uapi/asm/resource.h deleted file mode 100644 index 090483c47dbb..000000000000 --- a/arch/parisc/include/uapi/asm/resource.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _ASM_PARISC_RESOURCE_H -#define _ASM_PARISC_RESOURCE_H - -#include - -#endif -- GitLab From 131cd131a9ff63d4b84f3fe15073a2984ac30066 Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Thu, 1 May 2014 16:14:24 -0400 Subject: [PATCH 789/797] dm cache: fix writethrough mode quiescing in cache_map Commit 2ee57d58735 ("dm cache: add passthrough mode") inadvertently removed the deferred set reference that was taken in cache_map()'s writethrough mode support. Restore taking this reference. This issue was found with code inspection. Signed-off-by: Mike Snitzer Acked-by: Joe Thornber Cc: stable@vger.kernel.org # 3.13+ --- drivers/md/dm-cache-target.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 1bf4a71919ec..9380be7b1895 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2488,6 +2488,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio) } else { inc_hit_counter(cache, bio); + pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); if (bio_data_dir(bio) == WRITE && writethrough_mode(&cache->features) && !is_dirty(cache, lookup_result.cblock)) -- GitLab From 561a4fe851ccab9dd0d14989ab566f9392d9f8b5 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (Red Hat)" Date: Fri, 2 May 2014 13:30:04 -0400 Subject: [PATCH 790/797] tracing: Use rcu_dereference_sched() for trace event triggers As trace event triggers are now part of the mainline kernel, I added my trace event trigger tests to my test suite I run on all my kernels. Now these tests get run under different config options, and one of those options is CONFIG_PROVE_RCU, which checks under lockdep that the rcu locking primitives are being used correctly. This triggered the following splat: =============================== [ INFO: suspicious RCU usage. ] 3.15.0-rc2-test+ #11 Not tainted ------------------------------- kernel/trace/trace_events_trigger.c:80 suspicious rcu_dereference_check() usage! other info that might help us debug this: rcu_scheduler_active = 1, debug_locks = 0 4 locks held by swapper/1/0: #0: ((&(&j_cdbs->work)->timer)){..-...}, at: [] call_timer_fn+0x5/0x1be #1: (&(&pool->lock)->rlock){-.-...}, at: [] __queue_work+0x140/0x283 #2: (&p->pi_lock){-.-.-.}, at: [] try_to_wake_up+0x2e/0x1e8 #3: (&rq->lock){-.-.-.}, at: [] try_to_wake_up+0x1a0/0x1e8 stack backtrace: CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.15.0-rc2-test+ #11 Hardware name: /DG965MQ, BIOS MQ96510J.86A.0372.2006.0605.1717 06/05/2006 0000000000000001 ffff88007e083b98 ffffffff819f53a5 0000000000000006 ffff88007b0942c0 ffff88007e083bc8 ffffffff81081307 ffff88007ad96d20 0000000000000000 ffff88007af2d840 ffff88007b2e701c ffff88007e083c18 Call Trace: [] dump_stack+0x4f/0x7c [] lockdep_rcu_suspicious+0x107/0x110 [] event_triggers_call+0x99/0x108 [] ftrace_event_buffer_commit+0x42/0xa4 [] ftrace_raw_event_sched_wakeup_template+0x71/0x7c [] ttwu_do_wakeup+0x7f/0xff [] ttwu_do_activate.constprop.126+0x5c/0x61 [] try_to_wake_up+0x1ac/0x1e8 [] wake_up_process+0x36/0x3b [] wake_up_worker+0x24/0x26 [] insert_work+0x5c/0x65 [] __queue_work+0x26c/0x283 [] ? __queue_work+0x283/0x283 [] delayed_work_timer_fn+0x1e/0x20 [] call_timer_fn+0xdf/0x1be^M [] ? call_timer_fn+0x5/0x1be [] ? __queue_work+0x283/0x283 [] run_timer_softirq+0x1a4/0x22f^M [] __do_softirq+0x17b/0x31b^M [] irq_exit+0x42/0x97 [] smp_apic_timer_interrupt+0x37/0x44 [] apic_timer_interrupt+0x6f/0x80 [] ? default_idle+0x21/0x32 [] ? default_idle+0x1f/0x32 [] arch_cpu_idle+0xf/0x11 [] cpu_startup_entry+0x1a3/0x213 [] start_secondary+0x212/0x219 The cause is that the triggers are protected by rcu_read_lock_sched() but the data is dereferenced with rcu_dereference() which expects it to be protected with rcu_read_lock(). The proper reference should be rcu_dereference_sched(). Cc: Tom Zanussi Cc: stable@vger.kernel.org # 3.14+ Signed-off-by: Steven Rostedt --- kernel/trace/trace_events_trigger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 925f537f07d1..4747b476a030 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -77,7 +77,7 @@ event_triggers_call(struct ftrace_event_file *file, void *rec) data->ops->func(data); continue; } - filter = rcu_dereference(data->filter); + filter = rcu_dereference_sched(data->filter); if (filter && !filter_match_preds(filter, rec)) continue; if (data->cmd_ops->post_trigger) { -- GitLab From da6e4cb67c6dd1f72257c0a4a97c26dc4e80d3a7 Mon Sep 17 00:00:00 2001 From: Dave Anderson Date: Tue, 15 Apr 2014 18:53:24 +0100 Subject: [PATCH 791/797] arm64: Fix for the arm64 kern_addr_valid() function Fix for the arm64 kern_addr_valid() function to recognize virtual addresses in the kernel logical memory map. The function fails as written because it does not check whether the addresses in that region are mapped at the pmd level to 2MB or 512MB pages, continues the page table walk to the pte level, and issues a garbage value to pfn_valid(). Tested on 4K-page and 64K-page kernels. Signed-off-by: Dave Anderson Signed-off-by: Catalin Marinas --- arch/arm64/mm/mmu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 6b7e89569a3a..0a472c41a67f 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -374,6 +374,9 @@ int kern_addr_valid(unsigned long addr) if (pmd_none(*pmd)) return 0; + if (pmd_sect(*pmd)) + return pfn_valid(pmd_pfn(*pmd)); + pte = pte_offset_kernel(pmd, addr); if (pte_none(*pte)) return 0; -- GitLab From f774b7d10e2155e52b92dfce2f8cb099a6d6d0e6 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Mon, 28 Apr 2014 19:50:06 +0100 Subject: [PATCH 792/797] arm64: fixmap: fix missing sub-page offset for earlyprintk Commit d57c33c5daa4 (add generic fixmap.h) added (among other similar things) set_fixmap_io to deal with early ioremap of devices. More recently, commit bf4b558eba92 (arm64: add early_ioremap support) converted the arm64 earlyprintk to use set_fixmap_io. A side effect of this conversion is that my virtual machines have stopped booting when I pass "earlyprintk=uart8250-8bit,0x3f8" to the guest kernel. Turns out that the new earlyprintk code doesn't care at all about sub-page offsets, and just assumes that the earlyprintk device will be page-aligned. Obviously, that doesn't play well with the above example. Further investigation shows that set_fixmap_io uses __set_fixmap instead of __set_fixmap_offset. A fix is to introduce a set_fixmap_offset_io that uses the latter, and to remove the superflous call to fix_to_virt (which only returns the value that set_fixmap_io has already given us). With this applied, my VMs are back in business. Tested on a Cortex-A57 platform with kvmtool as platform emulation. Cc: Will Deacon Acked-by: Mark Salter Acked-by: Arnd Bergmann Signed-off-by: Marc Zyngier Signed-off-by: Catalin Marinas --- arch/arm64/kernel/early_printk.c | 6 ++---- include/asm-generic/fixmap.h | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kernel/early_printk.c b/arch/arm64/kernel/early_printk.c index ffbbdde7aba1..2dc36d00addf 100644 --- a/arch/arm64/kernel/early_printk.c +++ b/arch/arm64/kernel/early_printk.c @@ -143,10 +143,8 @@ static int __init setup_early_printk(char *buf) } /* no options parsing yet */ - if (paddr) { - set_fixmap_io(FIX_EARLYCON_MEM_BASE, paddr); - early_base = (void __iomem *)fix_to_virt(FIX_EARLYCON_MEM_BASE); - } + if (paddr) + early_base = (void __iomem *)set_fixmap_offset_io(FIX_EARLYCON_MEM_BASE, paddr); printch = match->printch; early_console = &early_console_dev; diff --git a/include/asm-generic/fixmap.h b/include/asm-generic/fixmap.h index 5a64ca4621f3..f23174fb9ec4 100644 --- a/include/asm-generic/fixmap.h +++ b/include/asm-generic/fixmap.h @@ -93,5 +93,8 @@ static inline unsigned long virt_to_fix(const unsigned long vaddr) #define set_fixmap_io(idx, phys) \ __set_fixmap(idx, phys, FIXMAP_PAGE_IO) +#define set_fixmap_offset_io(idx, phys) \ + __set_fixmap_offset(idx, phys, FIXMAP_PAGE_IO) + #endif /* __ASSEMBLY__ */ #endif /* __ASM_GENERIC_FIXMAP_H */ -- GitLab From c7a4a7658d689f664050c45493d79adf053f226e Mon Sep 17 00:00:00 2001 From: Ritesh Harjani Date: Wed, 23 Apr 2014 06:29:46 +0100 Subject: [PATCH 793/797] arm64: Make default dma_ops to be noncoherent Currently arm64 dma_ops is by default made coherent which makes it opposite in default policy from arm. Make default dma_ops to be noncoherent (same as arm), as currently there aren't any dma-capable drivers which assumes coherent ops Signed-off-by: Ritesh Harjani Acked-by: Will Deacon Signed-off-by: Catalin Marinas --- arch/arm64/mm/dma-mapping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 0ba347e59f06..1f65963a9c04 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -311,7 +311,7 @@ static int __init swiotlb_late_init(void) { size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); - dma_ops = &coherent_swiotlb_dma_ops; + dma_ops = &noncoherent_swiotlb_dma_ops; return swiotlb_late_init_with_default_size(swiotlb_size); } -- GitLab From 6ecba8eb51b7d23fda66388a5420be7d8688b186 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 25 Apr 2014 15:31:45 +0100 Subject: [PATCH 794/797] arm64: Use bus notifiers to set per-device coherent DMA ops Recently, the default DMA ops have been changed to non-coherent for alignment with 32-bit ARM platforms (and DT files). This patch adds bus notifiers to be able to set the coherent DMA ops (with no cache maintenance) for devices explicitly marked as coherent via the "dma-coherent" DT property. Signed-off-by: Catalin Marinas --- arch/arm64/kernel/setup.c | 2 +- arch/arm64/mm/dma-mapping.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 93e7df8968fe..7ec784653b29 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -396,7 +396,7 @@ static int __init arm64_device_init(void) of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); return 0; } -arch_initcall(arm64_device_init); +arch_initcall_sync(arm64_device_init); static DEFINE_PER_CPU(struct cpu, cpu_data); diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index 1f65963a9c04..c851eb44dc50 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -22,8 +22,11 @@ #include #include #include +#include +#include #include #include +#include #include @@ -305,17 +308,45 @@ struct dma_map_ops coherent_swiotlb_dma_ops = { }; EXPORT_SYMBOL(coherent_swiotlb_dma_ops); +static int dma_bus_notifier(struct notifier_block *nb, + unsigned long event, void *_dev) +{ + struct device *dev = _dev; + + if (event != BUS_NOTIFY_ADD_DEVICE) + return NOTIFY_DONE; + + if (of_property_read_bool(dev->of_node, "dma-coherent")) + set_dma_ops(dev, &coherent_swiotlb_dma_ops); + + return NOTIFY_OK; +} + +static struct notifier_block platform_bus_nb = { + .notifier_call = dma_bus_notifier, +}; + +static struct notifier_block amba_bus_nb = { + .notifier_call = dma_bus_notifier, +}; + extern int swiotlb_late_init_with_default_size(size_t default_size); static int __init swiotlb_late_init(void) { size_t swiotlb_size = min(SZ_64M, MAX_ORDER_NR_PAGES << PAGE_SHIFT); + /* + * These must be registered before of_platform_populate(). + */ + bus_register_notifier(&platform_bus_type, &platform_bus_nb); + bus_register_notifier(&amba_bustype, &amba_bus_nb); + dma_ops = &noncoherent_swiotlb_dma_ops; return swiotlb_late_init_with_default_size(swiotlb_size); } -subsys_initcall(swiotlb_late_init); +arch_initcall(swiotlb_late_init); #define PREALLOC_DMA_DEBUG_ENTRIES 4096 -- GitLab From 7a8d1ec16dfbb7785e82ccc97b0076cc34911701 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 25 Apr 2014 16:39:49 +0100 Subject: [PATCH 795/797] arm64: Mark the Applied Micro X-Gene SATA controller as DMA coherent Since the default DMA ops for arm64 are non-coherent, mark the X-Gene controller explicitly as dma-coherent to avoid additional cache maintenance. Signed-off-by: Catalin Marinas Cc: Loc Ho --- Documentation/devicetree/bindings/ata/apm-xgene.txt | 3 +++ arch/arm64/boot/dts/apm-storm.dtsi | 3 +++ 2 files changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/ata/apm-xgene.txt b/Documentation/devicetree/bindings/ata/apm-xgene.txt index 7bcfbf59810e..a668f0e7d001 100644 --- a/Documentation/devicetree/bindings/ata/apm-xgene.txt +++ b/Documentation/devicetree/bindings/ata/apm-xgene.txt @@ -24,6 +24,7 @@ Required properties: * "sata-phy" for the SATA 6.0Gbps PHY Optional properties: +- dma-coherent : Present if dma operations are coherent - status : Shall be "ok" if enabled or "disabled" if disabled. Default is "ok". @@ -55,6 +56,7 @@ Example: <0x0 0x1f22e000 0x0 0x1000>, <0x0 0x1f227000 0x0 0x1000>; interrupts = <0x0 0x87 0x4>; + dma-coherent; status = "ok"; clocks = <&sataclk 0>; phys = <&phy2 0>; @@ -69,6 +71,7 @@ Example: <0x0 0x1f23e000 0x0 0x1000>, <0x0 0x1f237000 0x0 0x1000>; interrupts = <0x0 0x88 0x4>; + dma-coherent; status = "ok"; clocks = <&sataclk 0>; phys = <&phy3 0>; diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi index 93f4b2dd9248..f8c40a66e65d 100644 --- a/arch/arm64/boot/dts/apm-storm.dtsi +++ b/arch/arm64/boot/dts/apm-storm.dtsi @@ -307,6 +307,7 @@ <0x0 0x1f21e000 0x0 0x1000>, <0x0 0x1f217000 0x0 0x1000>; interrupts = <0x0 0x86 0x4>; + dma-coherent; status = "disabled"; clocks = <&sata01clk 0>; phys = <&phy1 0>; @@ -321,6 +322,7 @@ <0x0 0x1f22e000 0x0 0x1000>, <0x0 0x1f227000 0x0 0x1000>; interrupts = <0x0 0x87 0x4>; + dma-coherent; status = "ok"; clocks = <&sata23clk 0>; phys = <&phy2 0>; @@ -334,6 +336,7 @@ <0x0 0x1f23d000 0x0 0x1000>, <0x0 0x1f23e000 0x0 0x1000>; interrupts = <0x0 0x88 0x4>; + dma-coherent; status = "ok"; clocks = <&sata45clk 0>; phys = <&phy3 0>; -- GitLab From e715eb2e73918f4cefbba0b717ff8902e8030b39 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 28 Apr 2014 17:08:37 +0100 Subject: [PATCH 796/797] vexpress: Initialise the sysregs before setting up the clocks Following arm64 commit bc3ee18a7a57 (arm64: init: Move of_clk_init to time_init()), vexpress_osc_of_setup() is called via of_clk_init() long before initcalls are issued. Initialising the vexpress oscillators requires the vespress sysregs to be already initialised, so this patch adds an explicit call to vexpress_sysreg_of_early_init() in vexpress oscillator setup function. Signed-off-by: Catalin Marinas Tested-by: Will Deacon Acked-by: Will Deacon Tested-by: Pawel Moll Acked-by: Pawel Moll Cc: Mike Turquette --- drivers/clk/versatile/clk-vexpress-osc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index a535c7bf8574..422391242b39 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c @@ -100,6 +100,8 @@ void __init vexpress_osc_of_setup(struct device_node *node) struct clk *clk; u32 range[2]; + vexpress_sysreg_of_early_init(); + osc = kzalloc(sizeof(*osc), GFP_KERNEL); if (!osc) return; -- GitLab From 89ca3b881987f5a4be4c5dbaa7f0df12bbdde2fd Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 4 May 2014 18:14:42 -0700 Subject: [PATCH 797/797] Linux 3.15-rc4 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 041c685e11ea..28a7259e0f3b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 3 PATCHLEVEL = 15 SUBLEVEL = 0 -EXTRAVERSION = -rc3 +EXTRAVERSION = -rc4 NAME = Shuffling Zombie Juror # *DOCUMENTATION* -- GitLab