From 21b195c05cf6a6cc49777d6992772bcf01502186 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 23 Dec 2021 20:31:37 +0800 Subject: [PATCH 001/124] workqueue: Remove the mb() pair between wq_worker_sleeping() and insert_work() In wq_worker_sleeping(), the access to worklist is protected by the pool->lock, so the memory barrier is unneeded. Signed-off-by: Lai Jiangshan Signed-off-by: Tejun Heo --- kernel/workqueue.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 33f1106b4f99..29b070106f34 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -918,10 +918,6 @@ void wq_worker_sleeping(struct task_struct *task) } /* - * The counterpart of the following dec_and_test, implied mb, - * worklist not empty test sequence is in insert_work(). - * Please read comment there. - * * NOT_RUNNING is clear. This means that we're bound to and * running on the local cpu w/ rq lock held and preemption * disabled, which in turn means that none else could be @@ -1372,13 +1368,6 @@ static void insert_work(struct pool_workqueue *pwq, struct work_struct *work, list_add_tail(&work->entry, head); get_pwq(pwq); - /* - * Ensure either wq_worker_sleeping() sees the above - * list_add_tail() or we see zero nr_running to avoid workers lying - * around lazily while there are works to be processed. - */ - smp_mb(); - if (__need_more_worker(pool)) wake_up_worker(pool); } From 2c1f1a9180bfacbc3c8e5b10075640cc810cf9c0 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 23 Dec 2021 20:31:38 +0800 Subject: [PATCH 002/124] workqueue: Change the comments of the synchronization about the idle_list The access to idle_list in wq_worker_sleeping() is changed to be protected by pool->lock, so the comments above idle_list can be changed to "L:" which is the meaning of "access with pool->lock held". And the outdated comments in wq_worker_sleeping() is removed since the function is not called with rq lock held any more, idle_list is dereferenced with pool lock now. Signed-off-by: Lai Jiangshan Signed-off-by: Tejun Heo --- kernel/workqueue.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 29b070106f34..b3207722671c 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -162,7 +162,7 @@ struct worker_pool { int nr_workers; /* L: total number of workers */ int nr_idle; /* L: currently idle workers */ - struct list_head idle_list; /* X: list of idle workers */ + struct list_head idle_list; /* L: list of idle workers */ struct timer_list idle_timer; /* L: worker idle timeout */ struct timer_list mayday_timer; /* L: SOS timer for workers */ @@ -826,7 +826,7 @@ static bool too_many_workers(struct worker_pool *pool) * Wake up functions. */ -/* Return the first idle worker. Safe with preemption disabled */ +/* Return the first idle worker. Called with pool->lock held. */ static struct worker *first_idle_worker(struct worker_pool *pool) { if (unlikely(list_empty(&pool->idle_list))) @@ -917,13 +917,6 @@ void wq_worker_sleeping(struct task_struct *task) return; } - /* - * NOT_RUNNING is clear. This means that we're bound to and - * running on the local cpu w/ rq lock held and preemption - * disabled, which in turn means that none else could be - * manipulating idle_list, so dereferencing idle_list without pool - * lock is safe. - */ if (atomic_dec_and_test(&pool->nr_running) && !list_empty(&pool->worklist)) { next = first_idle_worker(pool); From cc5bff38463e0894dd596befa99f9d6860e15f5e Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 23 Dec 2021 20:31:39 +0800 Subject: [PATCH 003/124] workqueue: Use wake_up_worker() in wq_worker_sleeping() instead of open code The wakeup code in wq_worker_sleeping() is the same as wake_up_worker(). Signed-off-by: Lai Jiangshan Signed-off-by: Tejun Heo --- kernel/workqueue.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b3207722671c..69cbe9e62bf1 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -887,7 +887,7 @@ void wq_worker_running(struct task_struct *task) */ void wq_worker_sleeping(struct task_struct *task) { - struct worker *next, *worker = kthread_data(task); + struct worker *worker = kthread_data(task); struct worker_pool *pool; /* @@ -918,11 +918,8 @@ void wq_worker_sleeping(struct task_struct *task) } if (atomic_dec_and_test(&pool->nr_running) && - !list_empty(&pool->worklist)) { - next = first_idle_worker(pool); - if (next) - wake_up_process(next->task); - } + !list_empty(&pool->worklist)) + wake_up_worker(pool); raw_spin_unlock_irq(&pool->lock); } From bc35f7ef96284b8c963991357a9278a6beafca54 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Thu, 23 Dec 2021 20:31:40 +0800 Subject: [PATCH 004/124] workqueue: Convert the type of pool->nr_running to int It is only modified in associated CPU, so it doesn't need to be atomic. tj: Comment updated. Signed-off-by: Lai Jiangshan Signed-off-by: Tejun Heo --- kernel/workqueue.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 69cbe9e62bf1..835d25e65bb2 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -154,8 +154,13 @@ struct worker_pool { unsigned long watchdog_ts; /* L: watchdog timestamp */ - /* The current concurrency level. */ - atomic_t nr_running; + /* + * The counter is incremented in a process context on the associated CPU + * w/ preemption disabled, and decremented or reset in the same context + * but w/ pool->lock held. The readers grab pool->lock and are + * guaranteed to see if the counter reached zero. + */ + int nr_running; struct list_head worklist; /* L: list of pending works */ @@ -777,7 +782,7 @@ static bool work_is_canceling(struct work_struct *work) static bool __need_more_worker(struct worker_pool *pool) { - return !atomic_read(&pool->nr_running); + return !pool->nr_running; } /* @@ -802,8 +807,7 @@ static bool may_start_working(struct worker_pool *pool) /* Do I need to keep working? Called from currently running workers. */ static bool keep_working(struct worker_pool *pool) { - return !list_empty(&pool->worklist) && - atomic_read(&pool->nr_running) <= 1; + return !list_empty(&pool->worklist) && (pool->nr_running <= 1); } /* Do we need a new worker? Called from manager. */ @@ -873,7 +877,7 @@ void wq_worker_running(struct task_struct *task) */ preempt_disable(); if (!(worker->flags & WORKER_NOT_RUNNING)) - atomic_inc(&worker->pool->nr_running); + worker->pool->nr_running++; preempt_enable(); worker->sleeping = 0; } @@ -917,8 +921,8 @@ void wq_worker_sleeping(struct task_struct *task) return; } - if (atomic_dec_and_test(&pool->nr_running) && - !list_empty(&pool->worklist)) + pool->nr_running--; + if (need_more_worker(pool)) wake_up_worker(pool); raw_spin_unlock_irq(&pool->lock); } @@ -973,7 +977,7 @@ static inline void worker_set_flags(struct worker *worker, unsigned int flags) /* If transitioning into NOT_RUNNING, adjust nr_running. */ if ((flags & WORKER_NOT_RUNNING) && !(worker->flags & WORKER_NOT_RUNNING)) { - atomic_dec(&pool->nr_running); + pool->nr_running--; } worker->flags |= flags; @@ -1005,7 +1009,7 @@ static inline void worker_clr_flags(struct worker *worker, unsigned int flags) */ if ((flags & WORKER_NOT_RUNNING) && (oflags & WORKER_NOT_RUNNING)) if (!(worker->flags & WORKER_NOT_RUNNING)) - atomic_inc(&pool->nr_running); + pool->nr_running++; } /** @@ -1806,8 +1810,7 @@ static void worker_enter_idle(struct worker *worker) mod_timer(&pool->idle_timer, jiffies + IDLE_WORKER_TIMEOUT); /* Sanity check nr_running. */ - WARN_ON_ONCE(pool->nr_workers == pool->nr_idle && - atomic_read(&pool->nr_running)); + WARN_ON_ONCE(pool->nr_workers == pool->nr_idle && pool->nr_running); } /** @@ -4985,7 +4988,7 @@ static void unbind_workers(int cpu) * an unbound (in terms of concurrency management) pool which * are served by workers tied to the pool. */ - atomic_set(&pool->nr_running, 0); + pool->nr_running = 0; /* * With concurrency management just turned off, a busy From 4148be7de0a3316edd1af45609d354cac0e6a021 Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Sat, 8 Jan 2022 00:38:16 +0000 Subject: [PATCH 005/124] cgroup: rstat: use same convention to assign cgroup_base_stat In function cgroup_base_stat_flush(), we update cgroup_base_stat by getting rstatc->bstat and adjust delta to related fields. There are two convention to assign cgroup_base_stat in this function: * rstat2 = rstat1 * rstat2.cputime = rstat1.cputime The second convention may make audience think just field "cputime" is updated, while cputime is the only field in cgroup_base_stat. Let's use the same convention to eliminate this confusion. Signed-off-by: Wei Yang Signed-off-by: Tejun Heo --- kernel/cgroup/rstat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c index 9d331ba44870..0b32fa62e93c 100644 --- a/kernel/cgroup/rstat.c +++ b/kernel/cgroup/rstat.c @@ -325,7 +325,7 @@ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu) /* fetch the current per-cpu values */ do { seq = __u64_stats_fetch_begin(&rstatc->bsync); - cur.cputime = rstatc->bstat.cputime; + cur = rstatc->bstat; } while (__u64_stats_fetch_retry(&rstatc->bsync, seq)); /* propagate percpu delta to global */ From 95b99f353cf3d9d753796975f2093b13f75e0fbd Mon Sep 17 00:00:00 2001 From: Wei Yang Date: Sat, 8 Jan 2022 00:38:17 +0000 Subject: [PATCH 006/124] cgroup: rstat: retrieve current bstat to delta directly Instead of retrieve current bstat to cur and copy it to delta, let's use delta directly. This saves one copy operation and has the same code convention as propagating delta to parent. Signed-off-by: Wei Yang Signed-off-by: Tejun Heo --- kernel/cgroup/rstat.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/kernel/cgroup/rstat.c b/kernel/cgroup/rstat.c index 0b32fa62e93c..29ea74f0eab3 100644 --- a/kernel/cgroup/rstat.c +++ b/kernel/cgroup/rstat.c @@ -315,7 +315,7 @@ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu) { struct cgroup_rstat_cpu *rstatc = cgroup_rstat_cpu(cgrp, cpu); struct cgroup *parent = cgroup_parent(cgrp); - struct cgroup_base_stat cur, delta; + struct cgroup_base_stat delta; unsigned seq; /* Root-level stats are sourced from system-wide CPU stats */ @@ -325,11 +325,10 @@ static void cgroup_base_stat_flush(struct cgroup *cgrp, int cpu) /* fetch the current per-cpu values */ do { seq = __u64_stats_fetch_begin(&rstatc->bsync); - cur = rstatc->bstat; + delta = rstatc->bstat; } while (__u64_stats_fetch_retry(&rstatc->bsync, seq)); /* propagate percpu delta to global */ - delta = cur; cgroup_base_stat_sub(&delta, &rstatc->last_bstat); cgroup_base_stat_add(&cgrp->bstat, &delta); cgroup_base_stat_add(&rstatc->last_bstat, &delta); From ffacbd11e2580a93546733d2e4e320c181f76844 Mon Sep 17 00:00:00 2001 From: Yang Li Date: Sat, 8 Jan 2022 14:38:12 +0800 Subject: [PATCH 007/124] cgroup: Fix cgroup_can_fork() and cgroup_post_fork() kernel-doc comment Add the description of @kargs in cgroup_can_fork() and cgroup_post_fork() kernel-doc comment to remove warnings found by running scripts/kernel-doc, which is caused by using 'make W=1'. kernel/cgroup/cgroup.c:6235: warning: Function parameter or member 'kargs' not described in 'cgroup_can_fork' kernel/cgroup/cgroup.c:6296: warning: Function parameter or member 'kargs' not described in 'cgroup_post_fork' Reported-by: Abaci Robot Signed-off-by: Yang Li Signed-off-by: Tejun Heo --- kernel/cgroup/cgroup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index b31e1465868a..37c49e1a672f 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -6224,6 +6224,7 @@ static void cgroup_css_set_put_fork(struct kernel_clone_args *kargs) /** * cgroup_can_fork - called on a new task before the process is exposed * @child: the child process + * @kargs: the arguments passed to create the child process * * This prepares a new css_set for the child process which the child will * be attached to in cgroup_post_fork(). @@ -6286,6 +6287,7 @@ void cgroup_cancel_fork(struct task_struct *child, /** * cgroup_post_fork - finalize cgroup setup for the child process * @child: the child process + * @kargs: the arguments passed to create the child process * * Attach the child process to its css_set calling the subsystem fork() * callbacks. From 7b3391057fa1921ba84ef17852a6998c0af27e4d Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 13 Jan 2022 08:59:26 -0800 Subject: [PATCH 008/124] kunit: add example test case showing off all the expect macros Currently, these macros are only really documented near the bottom of https://www.kernel.org/doc/html/latest/dev-tools/kunit/api/test.html#c.KUNIT_FAIL. E.g. it's likely someone might just not realize that KUNIT_EXPECT_STREQ() exists and instead use KUNIT_EXPECT_FALSE(strcmp()) or similar. This can also serve as a basic smoketest that the KUnit assert machinery still works for all the macros. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Reviewed-by: David Gow Signed-off-by: Shuah Khan --- lib/kunit/kunit-example-test.c | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c index 51099b0ca29c..4bbf37c04eba 100644 --- a/lib/kunit/kunit-example-test.c +++ b/lib/kunit/kunit-example-test.c @@ -69,6 +69,47 @@ static void example_mark_skipped_test(struct kunit *test) /* This line should run */ kunit_info(test, "You should see this line."); } + +/* + * This test shows off all the types of KUNIT_EXPECT macros. + */ +static void example_all_expect_macros_test(struct kunit *test) +{ + /* Boolean assertions */ + KUNIT_EXPECT_TRUE(test, true); + KUNIT_EXPECT_FALSE(test, false); + + /* Integer assertions */ + KUNIT_EXPECT_EQ(test, 1, 1); /* check == */ + KUNIT_EXPECT_GE(test, 1, 1); /* check >= */ + KUNIT_EXPECT_LE(test, 1, 1); /* check <= */ + KUNIT_EXPECT_NE(test, 1, 0); /* check != */ + KUNIT_EXPECT_GT(test, 1, 0); /* check > */ + KUNIT_EXPECT_LT(test, 0, 1); /* check < */ + + /* Pointer assertions */ + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, test); + KUNIT_EXPECT_PTR_EQ(test, NULL, NULL); + KUNIT_EXPECT_PTR_NE(test, test, NULL); + + /* String assertions */ + KUNIT_EXPECT_STREQ(test, "hi", "hi"); + KUNIT_EXPECT_STRNEQ(test, "hi", "bye"); + + /* + * There are also ASSERT variants of all of the above that abort test + * execution if they fail. Useful for memory allocations, etc. + */ + KUNIT_ASSERT_GT(test, sizeof(char), 0); + + /* + * There are also _MSG variants of all of the above that let you include + * additional text on failure. + */ + KUNIT_EXPECT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!"); + KUNIT_ASSERT_GT_MSG(test, sizeof(int), 0, "Your ints are 0-bit?!"); +} + /* * Here we make a list of all the test cases we want to add to the test suite * below. @@ -83,6 +124,7 @@ static struct kunit_case example_test_cases[] = { KUNIT_CASE(example_simple_test), KUNIT_CASE(example_skip_test), KUNIT_CASE(example_mark_skipped_test), + KUNIT_CASE(example_all_expect_macros_test), {} }; From 4fdacef8ac5a5382eeb1bc6fc2632d71a09d52cd Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 13 Jan 2022 08:59:27 -0800 Subject: [PATCH 009/124] kunit: move check if assertion passed into the macros Currently the code always calls kunit_do_assertion() even though it does nothing when `pass` is true. This change moves the `if(!(pass))` check into the macro instead and renames the function to kunit_do_failed_assertion(). I feel this a bit easier to read and understand. This has the potential upside of avoiding a function call that does nothing most of the time (assuming your tests are passing) but comes with the downside of generating a bit more code and branches. We try to mitigate the branches by tagging them with `unlikely()`. This also means we don't have to initialize structs that we don't need, which will become a tiny bit more expensive if we switch over to using static variables to try and reduce stack usage. (There's runtime code to check if the variable has been initialized yet or not). Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Reviewed-by: David Gow Signed-off-by: Shuah Khan --- include/kunit/test.h | 21 +++++++++++---------- lib/kunit/test.c | 13 ++++--------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index b26400731c02..12cabd15449a 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -770,18 +771,18 @@ void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...); */ #define KUNIT_SUCCEED(test) do {} while (0) -void kunit_do_assertion(struct kunit *test, - struct kunit_assert *assert, - bool pass, - const char *fmt, ...); +void kunit_do_failed_assertion(struct kunit *test, + struct kunit_assert *assert, + const char *fmt, ...); #define KUNIT_ASSERTION(test, pass, assert_class, INITIALIZER, fmt, ...) do { \ - struct assert_class __assertion = INITIALIZER; \ - kunit_do_assertion(test, \ - &__assertion.assert, \ - pass, \ - fmt, \ - ##__VA_ARGS__); \ + if (unlikely(!(pass))) { \ + struct assert_class __assertion = INITIALIZER; \ + kunit_do_failed_assertion(test, \ + &__assertion.assert, \ + fmt, \ + ##__VA_ARGS__); \ + } \ } while (0) diff --git a/lib/kunit/test.c b/lib/kunit/test.c index c7ed4aabec04..3a52c321c280 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -275,16 +275,11 @@ static void __noreturn kunit_abort(struct kunit *test) WARN_ONCE(true, "Throw could not abort from test!\n"); } -void kunit_do_assertion(struct kunit *test, - struct kunit_assert *assert, - bool pass, - const char *fmt, ...) +void kunit_do_failed_assertion(struct kunit *test, + struct kunit_assert *assert, + const char *fmt, ...) { va_list args; - - if (pass) - return; - va_start(args, fmt); assert->message.fmt = fmt; @@ -297,7 +292,7 @@ void kunit_do_assertion(struct kunit *test, if (assert->type == KUNIT_ASSERTION) kunit_abort(test); } -EXPORT_SYMBOL_GPL(kunit_do_assertion); +EXPORT_SYMBOL_GPL(kunit_do_failed_assertion); void kunit_init_test(struct kunit *test, const char *name, char *log) { From a91e9ade402c48ee35cd1e4b671e3938db798d17 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 13 Jan 2022 08:59:28 -0800 Subject: [PATCH 010/124] kunit: drop unused kunit* field in kunit_assert The `struct kunit* test` field in kunit_assert is unused. Note: string_stream needs it, but it has its own `test` field. I assume `test` in `kunit_assert` predates this and was leftover after some refactoring. This patch removes the field and cleans up the macros to avoid needlessly passing around `test`. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Reviewed-by: David Gow Signed-off-by: Shuah Khan --- include/kunit/assert.h | 45 ++++++++++++------------------------------ include/kunit/test.h | 14 +++++-------- 2 files changed, 18 insertions(+), 41 deletions(-) diff --git a/include/kunit/assert.h b/include/kunit/assert.h index ccbc36c0b02f..f568166ef034 100644 --- a/include/kunit/assert.h +++ b/include/kunit/assert.h @@ -30,7 +30,6 @@ enum kunit_assert_type { /** * struct kunit_assert - Data for printing a failed assertion or expectation. - * @test: the test case this expectation/assertion is associated with. * @type: the type (either an expectation or an assertion) of this kunit_assert. * @line: the source code line number that the expectation/assertion is at. * @file: the file path of the source file that the expectation/assertion is in. @@ -41,7 +40,6 @@ enum kunit_assert_type { * format a string to a user reporting the failure. */ struct kunit_assert { - struct kunit *test; enum kunit_assert_type type; int line; const char *file; @@ -60,14 +58,12 @@ struct kunit_assert { /** * KUNIT_INIT_ASSERT_STRUCT() - Initializer for a &struct kunit_assert. - * @kunit: The test case that this expectation/assertion is associated with. * @assert_type: The type (assertion or expectation) of this kunit_assert. * @fmt: The formatting function which builds a string out of this kunit_assert. * * The base initializer for a &struct kunit_assert. */ -#define KUNIT_INIT_ASSERT_STRUCT(kunit, assert_type, fmt) { \ - .test = kunit, \ +#define KUNIT_INIT_ASSERT_STRUCT(assert_type, fmt) { \ .type = assert_type, \ .file = __FILE__, \ .line = __LINE__, \ @@ -96,15 +92,13 @@ void kunit_fail_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_FAIL_ASSERT_STRUCT() - Initializer for &struct kunit_fail_assert. - * @test: The test case that this expectation/assertion is associated with. * @type: The type (assertion or expectation) of this kunit_assert. * * Initializes a &struct kunit_fail_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_FAIL_ASSERT_STRUCT(test, type) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(test, \ - type, \ +#define KUNIT_INIT_FAIL_ASSERT_STRUCT(type) { \ + .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ kunit_fail_assert_format) \ } @@ -129,7 +123,6 @@ void kunit_unary_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_UNARY_ASSERT_STRUCT() - Initializes &struct kunit_unary_assert. - * @test: The test case that this expectation/assertion is associated with. * @type: The type (assertion or expectation) of this kunit_assert. * @cond: A string representation of the expression asserted true or false. * @expect_true: True if of type KUNIT_{EXPECT|ASSERT}_TRUE, false otherwise. @@ -137,9 +130,8 @@ void kunit_unary_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_unary_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_UNARY_ASSERT_STRUCT(test, type, cond, expect_true) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(test, \ - type, \ +#define KUNIT_INIT_UNARY_ASSERT_STRUCT(type, cond, expect_true) { \ + .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ kunit_unary_assert_format), \ .condition = cond, \ .expected_true = expect_true \ @@ -167,7 +159,6 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_PTR_NOT_ERR_ASSERT_STRUCT() - Initializes a * &struct kunit_ptr_not_err_assert. - * @test: The test case that this expectation/assertion is associated with. * @type: The type (assertion or expectation) of this kunit_assert. * @txt: A string representation of the expression passed to the expectation. * @val: The actual evaluated pointer value of the expression. @@ -175,9 +166,8 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_ptr_not_err_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_PTR_NOT_ERR_STRUCT(test, type, txt, val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(test, \ - type, \ +#define KUNIT_INIT_PTR_NOT_ERR_STRUCT(type, txt, val) { \ + .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ kunit_ptr_not_err_assert_format), \ .text = txt, \ .value = val \ @@ -212,7 +202,6 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_BINARY_ASSERT_STRUCT() - Initializes a * &struct kunit_binary_assert. - * @test: The test case that this expectation/assertion is associated with. * @type: The type (assertion or expectation) of this kunit_assert. * @op_str: A string representation of the comparison operator (e.g. "=="). * @left_str: A string representation of the expression in the left slot. @@ -223,15 +212,13 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_binary_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_BINARY_ASSERT_STRUCT(test, \ - type, \ +#define KUNIT_INIT_BINARY_ASSERT_STRUCT(type, \ op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(test, \ - type, \ + .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ kunit_binary_assert_format), \ .operation = op_str, \ .left_text = left_str, \ @@ -269,7 +256,6 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT() - Initializes a * &struct kunit_binary_ptr_assert. - * @test: The test case that this expectation/assertion is associated with. * @type: The type (assertion or expectation) of this kunit_assert. * @op_str: A string representation of the comparison operator (e.g. "=="). * @left_str: A string representation of the expression in the left slot. @@ -280,15 +266,13 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_binary_ptr_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT(test, \ - type, \ +#define KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT(type, \ op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(test, \ - type, \ + .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ kunit_binary_ptr_assert_format), \ .operation = op_str, \ .left_text = left_str, \ @@ -326,7 +310,6 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_BINARY_STR_ASSERT_STRUCT() - Initializes a * &struct kunit_binary_str_assert. - * @test: The test case that this expectation/assertion is associated with. * @type: The type (assertion or expectation) of this kunit_assert. * @op_str: A string representation of the comparison operator (e.g. "=="). * @left_str: A string representation of the expression in the left slot. @@ -337,15 +320,13 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_binary_str_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(test, \ - type, \ +#define KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(type, \ op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(test, \ - type, \ + .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ kunit_binary_str_assert_format), \ .operation = op_str, \ .left_text = left_str, \ diff --git a/include/kunit/test.h b/include/kunit/test.h index 12cabd15449a..25ea3bce6663 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -790,7 +790,7 @@ void kunit_do_failed_assertion(struct kunit *test, KUNIT_ASSERTION(test, \ false, \ kunit_fail_assert, \ - KUNIT_INIT_FAIL_ASSERT_STRUCT(test, assert_type), \ + KUNIT_INIT_FAIL_ASSERT_STRUCT(assert_type), \ fmt, \ ##__VA_ARGS__) @@ -820,8 +820,7 @@ void kunit_do_failed_assertion(struct kunit *test, KUNIT_ASSERTION(test, \ !!(condition) == !!expected_true, \ kunit_unary_assert, \ - KUNIT_INIT_UNARY_ASSERT_STRUCT(test, \ - assert_type, \ + KUNIT_INIT_UNARY_ASSERT_STRUCT(assert_type, \ #condition, \ expected_true), \ fmt, \ @@ -879,8 +878,7 @@ do { \ KUNIT_ASSERTION(test, \ __left op __right, \ assert_class, \ - ASSERT_CLASS_INIT(test, \ - assert_type, \ + ASSERT_CLASS_INIT(assert_type, \ #op, \ #left, \ __left, \ @@ -1234,8 +1232,7 @@ do { \ KUNIT_ASSERTION(test, \ strcmp(__left, __right) op 0, \ kunit_binary_str_assert, \ - KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(test, \ - assert_type, \ + KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(assert_type, \ #op, \ #left, \ __left, \ @@ -1294,8 +1291,7 @@ do { \ KUNIT_ASSERTION(test, \ !IS_ERR_OR_NULL(__ptr), \ kunit_ptr_not_err_assert, \ - KUNIT_INIT_PTR_NOT_ERR_STRUCT(test, \ - assert_type, \ + KUNIT_INIT_PTR_NOT_ERR_STRUCT(assert_type, \ #ptr, \ __ptr), \ fmt, \ From dd640d70874bd27fb081d444252677766321c32f Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 13 Jan 2022 08:59:29 -0800 Subject: [PATCH 011/124] kunit: factor out kunit_base_assert_format() call into kunit_fail() We call this function first thing for all the assertion `format()` functions. This is the part that prints the file and line number and assertion type (EXPECTATION, ASSERTION). Having it as part of the format functions lets us have the flexibility to not print that information (or print it differently) for new assertion types, but I think this we don't need that. And in the future, we'd like to consider factoring that data (file, line#, type) out of the kunit_assert struct and into a `static` variable, as Linus suggested [1], so we'd need to extract it anyways. [1] https://groups.google.com/g/kunit-dev/c/i3fZXgvBrfA/m/VULQg1z6BAAJ Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- lib/kunit/assert.c | 6 ------ lib/kunit/test.c | 1 + 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c index b972bda61c0c..4d9a1295efc7 100644 --- a/lib/kunit/assert.c +++ b/lib/kunit/assert.c @@ -40,7 +40,6 @@ EXPORT_SYMBOL_GPL(kunit_assert_print_msg); void kunit_fail_assert_format(const struct kunit_assert *assert, struct string_stream *stream) { - kunit_base_assert_format(assert, stream); string_stream_add(stream, "%pV", &assert->message); } EXPORT_SYMBOL_GPL(kunit_fail_assert_format); @@ -52,7 +51,6 @@ void kunit_unary_assert_format(const struct kunit_assert *assert, unary_assert = container_of(assert, struct kunit_unary_assert, assert); - kunit_base_assert_format(assert, stream); if (unary_assert->expected_true) string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n", @@ -73,7 +71,6 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert, assert); - kunit_base_assert_format(assert, stream); if (!ptr_assert->value) { string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n", @@ -119,7 +116,6 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, binary_assert = container_of(assert, struct kunit_binary_assert, assert); - kunit_base_assert_format(assert, stream); string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", binary_assert->left_text, @@ -147,7 +143,6 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, binary_assert = container_of(assert, struct kunit_binary_ptr_assert, assert); - kunit_base_assert_format(assert, stream); string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", binary_assert->left_text, @@ -187,7 +182,6 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, binary_assert = container_of(assert, struct kunit_binary_str_assert, assert); - kunit_base_assert_format(assert, stream); string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", binary_assert->left_text, diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 3a52c321c280..345a9dd88c27 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -255,6 +255,7 @@ static void kunit_fail(struct kunit *test, struct kunit_assert *assert) return; } + kunit_base_assert_format(assert, stream); assert->format(assert, stream); kunit_print_string_stream(test, stream); From 21957f90b28f6bc118c055e3e564d45f6e4df45d Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 13 Jan 2022 08:59:30 -0800 Subject: [PATCH 012/124] kunit: split out part of kunit_assert into a static const This is per Linus's suggestion in [1]. The issue there is that every KUNIT_EXPECT/KUNIT_ASSERT puts a kunit_assert object onto the stack. Normally we rely on compilers to elide this, but when that doesn't work out, this blows up the stack usage of kunit test functions. We can move some data off the stack by making it static. This change introduces a new `struct kunit_loc` to hold the file and line number and then just passing assert_type (EXPECT or ASSERT) as an argument. In [1], it was suggested to also move out the format string as well, but users could theoretically craft a format string at runtime, so we can't. This change leaves a copy of `assert_type` in kunit_assert for now because cleaning up all the macros to not pass it around is a bit more involved. Here's an example of the expanded code for KUNIT_FAIL(): if (__builtin_expect(!!(!(false)), 0)) { static const struct kunit_loc loc = { .file = ... }; struct kunit_fail_assert __assertion = { .assert = { .type ... }; kunit_do_failed_assertion(test, &loc, KUNIT_EXPECTATION, &__assertion.assert, ...); }; [1] https://groups.google.com/g/kunit-dev/c/i3fZXgvBrfA/m/VULQg1z6BAAJ Signed-off-by: Daniel Latypov Suggested-by: Linus Torvalds Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/assert.h | 25 +++++++++++++++++-------- include/kunit/test.h | 12 +++++++++++- lib/kunit/assert.c | 9 +++++---- lib/kunit/test.c | 15 +++++++++------ 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/include/kunit/assert.h b/include/kunit/assert.h index f568166ef034..0da1bbdd1ee8 100644 --- a/include/kunit/assert.h +++ b/include/kunit/assert.h @@ -28,11 +28,21 @@ enum kunit_assert_type { KUNIT_EXPECTATION, }; +/** + * struct kunit_loc - Identifies the source location of a line of code. + * @line: the line number in the file. + * @file: the file name. + */ +struct kunit_loc { + int line; + const char *file; +}; + +#define KUNIT_CURRENT_LOC { .file = __FILE__, .line = __LINE__ } + /** * struct kunit_assert - Data for printing a failed assertion or expectation. * @type: the type (either an expectation or an assertion) of this kunit_assert. - * @line: the source code line number that the expectation/assertion is at. - * @file: the file path of the source file that the expectation/assertion is in. * @message: an optional message to provide additional context. * @format: a function which formats the data in this kunit_assert to a string. * @@ -40,9 +50,9 @@ enum kunit_assert_type { * format a string to a user reporting the failure. */ struct kunit_assert { + // TODO(dlatypov@google.com): delete this unused field when we've + // updated all the related KUNIT_INIT_ASSERT* macros. enum kunit_assert_type type; - int line; - const char *file; struct va_format message; void (*format)(const struct kunit_assert *assert, struct string_stream *stream); @@ -65,14 +75,13 @@ struct kunit_assert { */ #define KUNIT_INIT_ASSERT_STRUCT(assert_type, fmt) { \ .type = assert_type, \ - .file = __FILE__, \ - .line = __LINE__, \ .message = KUNIT_INIT_VA_FMT_NULL, \ .format = fmt \ } -void kunit_base_assert_format(const struct kunit_assert *assert, - struct string_stream *stream); +void kunit_assert_prologue(const struct kunit_loc *loc, + enum kunit_assert_type type, + struct string_stream *stream); void kunit_assert_print_msg(const struct kunit_assert *assert, struct string_stream *stream); diff --git a/include/kunit/test.h b/include/kunit/test.h index 25ea3bce6663..7b752175e614 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -772,13 +772,18 @@ void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...); #define KUNIT_SUCCEED(test) do {} while (0) void kunit_do_failed_assertion(struct kunit *test, + const struct kunit_loc *loc, + enum kunit_assert_type type, struct kunit_assert *assert, const char *fmt, ...); -#define KUNIT_ASSERTION(test, pass, assert_class, INITIALIZER, fmt, ...) do { \ +#define KUNIT_ASSERTION(test, assert_type, pass, assert_class, INITIALIZER, fmt, ...) do { \ if (unlikely(!(pass))) { \ + static const struct kunit_loc loc = KUNIT_CURRENT_LOC; \ struct assert_class __assertion = INITIALIZER; \ kunit_do_failed_assertion(test, \ + &loc, \ + assert_type, \ &__assertion.assert, \ fmt, \ ##__VA_ARGS__); \ @@ -788,6 +793,7 @@ void kunit_do_failed_assertion(struct kunit *test, #define KUNIT_FAIL_ASSERTION(test, assert_type, fmt, ...) \ KUNIT_ASSERTION(test, \ + assert_type, \ false, \ kunit_fail_assert, \ KUNIT_INIT_FAIL_ASSERT_STRUCT(assert_type), \ @@ -818,6 +824,7 @@ void kunit_do_failed_assertion(struct kunit *test, fmt, \ ...) \ KUNIT_ASSERTION(test, \ + assert_type, \ !!(condition) == !!expected_true, \ kunit_unary_assert, \ KUNIT_INIT_UNARY_ASSERT_STRUCT(assert_type, \ @@ -876,6 +883,7 @@ do { \ typeof(right) __right = (right); \ \ KUNIT_ASSERTION(test, \ + assert_type, \ __left op __right, \ assert_class, \ ASSERT_CLASS_INIT(assert_type, \ @@ -1230,6 +1238,7 @@ do { \ const char *__right = (right); \ \ KUNIT_ASSERTION(test, \ + assert_type, \ strcmp(__left, __right) op 0, \ kunit_binary_str_assert, \ KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(assert_type, \ @@ -1289,6 +1298,7 @@ do { \ typeof(ptr) __ptr = (ptr); \ \ KUNIT_ASSERTION(test, \ + assert_type, \ !IS_ERR_OR_NULL(__ptr), \ kunit_ptr_not_err_assert, \ KUNIT_INIT_PTR_NOT_ERR_STRUCT(assert_type, \ diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c index 4d9a1295efc7..9f4492a8e24e 100644 --- a/lib/kunit/assert.c +++ b/lib/kunit/assert.c @@ -10,12 +10,13 @@ #include "string-stream.h" -void kunit_base_assert_format(const struct kunit_assert *assert, +void kunit_assert_prologue(const struct kunit_loc *loc, + enum kunit_assert_type type, struct string_stream *stream) { const char *expect_or_assert = NULL; - switch (assert->type) { + switch (type) { case KUNIT_EXPECTATION: expect_or_assert = "EXPECTATION"; break; @@ -25,9 +26,9 @@ void kunit_base_assert_format(const struct kunit_assert *assert, } string_stream_add(stream, "%s FAILED at %s:%d\n", - expect_or_assert, assert->file, assert->line); + expect_or_assert, loc->file, loc->line); } -EXPORT_SYMBOL_GPL(kunit_base_assert_format); +EXPORT_SYMBOL_GPL(kunit_assert_prologue); void kunit_assert_print_msg(const struct kunit_assert *assert, struct string_stream *stream) diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 345a9dd88c27..7dec3248562f 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -240,7 +240,8 @@ static void kunit_print_string_stream(struct kunit *test, } } -static void kunit_fail(struct kunit *test, struct kunit_assert *assert) +static void kunit_fail(struct kunit *test, const struct kunit_loc *loc, + enum kunit_assert_type type, struct kunit_assert *assert) { struct string_stream *stream; @@ -250,12 +251,12 @@ static void kunit_fail(struct kunit *test, struct kunit_assert *assert) if (!stream) { WARN(true, "Could not allocate stream to print failed assertion in %s:%d\n", - assert->file, - assert->line); + loc->file, + loc->line); return; } - kunit_base_assert_format(assert, stream); + kunit_assert_prologue(loc, type, stream); assert->format(assert, stream); kunit_print_string_stream(test, stream); @@ -277,6 +278,8 @@ static void __noreturn kunit_abort(struct kunit *test) } void kunit_do_failed_assertion(struct kunit *test, + const struct kunit_loc *loc, + enum kunit_assert_type type, struct kunit_assert *assert, const char *fmt, ...) { @@ -286,11 +289,11 @@ void kunit_do_failed_assertion(struct kunit *test, assert->message.fmt = fmt; assert->message.va = &args; - kunit_fail(test, assert); + kunit_fail(test, loc, type, assert); va_end(args); - if (assert->type == KUNIT_ASSERTION) + if (type == KUNIT_ASSERTION) kunit_abort(test); } EXPORT_SYMBOL_GPL(kunit_do_failed_assertion); From 05a7da89c15ddb3fc7618a16f5941eca68fc441c Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 13 Jan 2022 08:59:31 -0800 Subject: [PATCH 013/124] kunit: drop unused assert_type from kunit_assert and clean up macros This field has been split out from kunit_assert to make the struct less heavy along with the filename and line number. This change drops the assert_type field and cleans up all the macros that were plumbing assert_type into kunit_assert. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/assert.h | 48 ++++++++++++------------------------------ include/kunit/test.h | 14 +++++------- 2 files changed, 19 insertions(+), 43 deletions(-) diff --git a/include/kunit/assert.h b/include/kunit/assert.h index 0da1bbdd1ee8..f2b3ae5cc2de 100644 --- a/include/kunit/assert.h +++ b/include/kunit/assert.h @@ -42,7 +42,6 @@ struct kunit_loc { /** * struct kunit_assert - Data for printing a failed assertion or expectation. - * @type: the type (either an expectation or an assertion) of this kunit_assert. * @message: an optional message to provide additional context. * @format: a function which formats the data in this kunit_assert to a string. * @@ -50,9 +49,6 @@ struct kunit_loc { * format a string to a user reporting the failure. */ struct kunit_assert { - // TODO(dlatypov@google.com): delete this unused field when we've - // updated all the related KUNIT_INIT_ASSERT* macros. - enum kunit_assert_type type; struct va_format message; void (*format)(const struct kunit_assert *assert, struct string_stream *stream); @@ -68,13 +64,11 @@ struct kunit_assert { /** * KUNIT_INIT_ASSERT_STRUCT() - Initializer for a &struct kunit_assert. - * @assert_type: The type (assertion or expectation) of this kunit_assert. * @fmt: The formatting function which builds a string out of this kunit_assert. * * The base initializer for a &struct kunit_assert. */ -#define KUNIT_INIT_ASSERT_STRUCT(assert_type, fmt) { \ - .type = assert_type, \ +#define KUNIT_INIT_ASSERT_STRUCT(fmt) { \ .message = KUNIT_INIT_VA_FMT_NULL, \ .format = fmt \ } @@ -100,15 +94,13 @@ void kunit_fail_assert_format(const struct kunit_assert *assert, struct string_stream *stream); /** - * KUNIT_INIT_FAIL_ASSERT_STRUCT() - Initializer for &struct kunit_fail_assert. - * @type: The type (assertion or expectation) of this kunit_assert. + * KUNIT_INIT_FAIL_ASSERT_STRUCT - Initializer for &struct kunit_fail_assert. * * Initializes a &struct kunit_fail_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_FAIL_ASSERT_STRUCT(type) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ - kunit_fail_assert_format) \ +#define KUNIT_INIT_FAIL_ASSERT_STRUCT { \ + .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_fail_assert_format) \ } /** @@ -132,16 +124,14 @@ void kunit_unary_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_UNARY_ASSERT_STRUCT() - Initializes &struct kunit_unary_assert. - * @type: The type (assertion or expectation) of this kunit_assert. * @cond: A string representation of the expression asserted true or false. * @expect_true: True if of type KUNIT_{EXPECT|ASSERT}_TRUE, false otherwise. * * Initializes a &struct kunit_unary_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_UNARY_ASSERT_STRUCT(type, cond, expect_true) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ - kunit_unary_assert_format), \ +#define KUNIT_INIT_UNARY_ASSERT_STRUCT(cond, expect_true) { \ + .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_unary_assert_format), \ .condition = cond, \ .expected_true = expect_true \ } @@ -168,16 +158,14 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_PTR_NOT_ERR_ASSERT_STRUCT() - Initializes a * &struct kunit_ptr_not_err_assert. - * @type: The type (assertion or expectation) of this kunit_assert. * @txt: A string representation of the expression passed to the expectation. * @val: The actual evaluated pointer value of the expression. * * Initializes a &struct kunit_ptr_not_err_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_PTR_NOT_ERR_STRUCT(type, txt, val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ - kunit_ptr_not_err_assert_format), \ +#define KUNIT_INIT_PTR_NOT_ERR_STRUCT(txt, val) { \ + .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_ptr_not_err_assert_format), \ .text = txt, \ .value = val \ } @@ -211,7 +199,6 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_BINARY_ASSERT_STRUCT() - Initializes a * &struct kunit_binary_assert. - * @type: The type (assertion or expectation) of this kunit_assert. * @op_str: A string representation of the comparison operator (e.g. "=="). * @left_str: A string representation of the expression in the left slot. * @left_val: The actual evaluated value of the expression in the left slot. @@ -221,14 +208,12 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_binary_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_BINARY_ASSERT_STRUCT(type, \ - op_str, \ +#define KUNIT_INIT_BINARY_ASSERT_STRUCT(op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ - kunit_binary_assert_format), \ + .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_binary_assert_format), \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ @@ -275,14 +260,12 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_binary_ptr_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT(type, \ - op_str, \ +#define KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT(op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ - kunit_binary_ptr_assert_format), \ + .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_binary_ptr_assert_format), \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ @@ -319,7 +302,6 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, /** * KUNIT_INIT_BINARY_STR_ASSERT_STRUCT() - Initializes a * &struct kunit_binary_str_assert. - * @type: The type (assertion or expectation) of this kunit_assert. * @op_str: A string representation of the comparison operator (e.g. "=="). * @left_str: A string representation of the expression in the left slot. * @left_val: The actual evaluated value of the expression in the left slot. @@ -329,14 +311,12 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, * Initializes a &struct kunit_binary_str_assert. Intended to be used in * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ -#define KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(type, \ - op_str, \ +#define KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(type, \ - kunit_binary_str_assert_format), \ + .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_binary_str_assert_format), \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ diff --git a/include/kunit/test.h b/include/kunit/test.h index 7b752175e614..5964af750d93 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -796,7 +796,7 @@ void kunit_do_failed_assertion(struct kunit *test, assert_type, \ false, \ kunit_fail_assert, \ - KUNIT_INIT_FAIL_ASSERT_STRUCT(assert_type), \ + KUNIT_INIT_FAIL_ASSERT_STRUCT, \ fmt, \ ##__VA_ARGS__) @@ -827,8 +827,7 @@ void kunit_do_failed_assertion(struct kunit *test, assert_type, \ !!(condition) == !!expected_true, \ kunit_unary_assert, \ - KUNIT_INIT_UNARY_ASSERT_STRUCT(assert_type, \ - #condition, \ + KUNIT_INIT_UNARY_ASSERT_STRUCT(#condition, \ expected_true), \ fmt, \ ##__VA_ARGS__) @@ -886,8 +885,7 @@ do { \ assert_type, \ __left op __right, \ assert_class, \ - ASSERT_CLASS_INIT(assert_type, \ - #op, \ + ASSERT_CLASS_INIT(#op, \ #left, \ __left, \ #right, \ @@ -1241,8 +1239,7 @@ do { \ assert_type, \ strcmp(__left, __right) op 0, \ kunit_binary_str_assert, \ - KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(assert_type, \ - #op, \ + KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(#op, \ #left, \ __left, \ #right, \ @@ -1301,8 +1298,7 @@ do { \ assert_type, \ !IS_ERR_OR_NULL(__ptr), \ kunit_ptr_not_err_assert, \ - KUNIT_INIT_PTR_NOT_ERR_STRUCT(assert_type, \ - #ptr, \ + KUNIT_INIT_PTR_NOT_ERR_STRUCT(#ptr, \ __ptr), \ fmt, \ ##__VA_ARGS__); \ From 6709d0fe55933d3ac944f3cdd5b66d9786092f90 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 18 Jan 2022 14:35:02 -0800 Subject: [PATCH 014/124] kunit: make KUNIT_EXPECT_EQ() use KUNIT_EXPECT_EQ_MSG(), etc. There's quite a few macros in play for KUnit assertions. The current macro chain looks like: KUNIT_EXPECT_EQ => KUNIT_BINARY_EQ_ASSERTION => KUNIT_BINARY_EQ_MSG_ASSERTION KUNIT_EXPECT_EQ_MSG => KUNIT_BINARY_EQ_MSG_ASSERTION KUNIT_ASSERT_EQ => KUNIT_BINARY_EQ_ASSERTION => KUNIT_BINARY_EQ_MSG_ASSERTION KUNIT_ASSERT_EQ_MSG => KUNIT_BINARY_EQ_MSG_ASSERTION After this change: KUNIT_EXPECT_EQ => KUNIT_EXPECT_EQ_MSG => KUNIT_BINARY_EQ_MSG_ASSERTION KUNIT_ASSERT_EQ => KUNIT_ASSERT_EQ_MSG => KUNIT_BINARY_EQ_MSG_ASSERTION and we can drop the intermediate KUNIT_BINARY_EQ_ASSERTION. This change does this for all the other macros as well. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 168 +++++++------------------------------------ 1 file changed, 26 insertions(+), 142 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index 5964af750d93..b032dd6816d2 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -840,9 +840,6 @@ void kunit_do_failed_assertion(struct kunit *test, fmt, \ ##__VA_ARGS__) -#define KUNIT_TRUE_ASSERTION(test, assert_type, condition) \ - KUNIT_TRUE_MSG_ASSERTION(test, assert_type, condition, NULL) - #define KUNIT_FALSE_MSG_ASSERTION(test, assert_type, condition, fmt, ...) \ KUNIT_UNARY_ASSERTION(test, \ assert_type, \ @@ -851,9 +848,6 @@ void kunit_do_failed_assertion(struct kunit *test, fmt, \ ##__VA_ARGS__) -#define KUNIT_FALSE_ASSERTION(test, assert_type, condition) \ - KUNIT_FALSE_MSG_ASSERTION(test, assert_type, condition, NULL) - /* * A factory macro for defining the assertions and expectations for the basic * comparisons defined for the built in types. @@ -1000,13 +994,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_EQ_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1022,13 +1009,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_EQ_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_NE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_NE_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1039,13 +1019,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_NE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_NE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1061,13 +1034,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_NE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_LT_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_LT_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1078,13 +1044,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_LT_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_LT_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_PTR_LT_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1100,13 +1059,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_LT_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_PTR_LT_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_LE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_LE_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1117,13 +1069,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_LE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_LE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_PTR_LE_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1139,13 +1084,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_LE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_PTR_LE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_GT_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_GT_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1156,13 +1094,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_GT_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_GT_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_PTR_GT_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1178,13 +1109,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_GT_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_PTR_GT_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_GE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_GE_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1195,13 +1119,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_GE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_GE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_PTR_GE_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1217,13 +1134,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_GE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_PTR_GE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_STR_ASSERTION(test, \ assert_type, \ left, \ @@ -1260,13 +1170,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_STR_EQ_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_STR_EQ_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1279,13 +1182,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_STR_NE_ASSERTION(test, assert_type, left, right) \ - KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - NULL) - #define KUNIT_PTR_NOT_ERR_OR_NULL_MSG_ASSERTION(test, \ assert_type, \ ptr, \ @@ -1304,12 +1200,6 @@ do { \ ##__VA_ARGS__); \ } while (0) -#define KUNIT_PTR_NOT_ERR_OR_NULL_ASSERTION(test, assert_type, ptr) \ - KUNIT_PTR_NOT_ERR_OR_NULL_MSG_ASSERTION(test, \ - assert_type, \ - ptr, \ - NULL) - /** * KUNIT_EXPECT_TRUE() - Causes a test failure when the expression is not true. * @test: The test context object. @@ -1322,7 +1212,7 @@ do { \ * *expectation failure*. */ #define KUNIT_EXPECT_TRUE(test, condition) \ - KUNIT_TRUE_ASSERTION(test, KUNIT_EXPECTATION, condition) + KUNIT_EXPECT_TRUE_MSG(test, condition, NULL) #define KUNIT_EXPECT_TRUE_MSG(test, condition, fmt, ...) \ KUNIT_TRUE_MSG_ASSERTION(test, \ @@ -1341,7 +1231,7 @@ do { \ * KUNIT_EXPECT_TRUE() for more information. */ #define KUNIT_EXPECT_FALSE(test, condition) \ - KUNIT_FALSE_ASSERTION(test, KUNIT_EXPECTATION, condition) + KUNIT_EXPECT_FALSE_MSG(test, condition, NULL) #define KUNIT_EXPECT_FALSE_MSG(test, condition, fmt, ...) \ KUNIT_FALSE_MSG_ASSERTION(test, \ @@ -1362,7 +1252,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_EQ(test, left, right) \ - KUNIT_BINARY_EQ_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_EQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_EQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ @@ -1384,10 +1274,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_PTR_EQ(test, left, right) \ - KUNIT_BINARY_PTR_EQ_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right) + KUNIT_EXPECT_PTR_EQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_PTR_EQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ @@ -1409,7 +1296,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_NE(test, left, right) \ - KUNIT_BINARY_NE_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_NE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_NE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_NE_MSG_ASSERTION(test, \ @@ -1431,10 +1318,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_PTR_NE(test, left, right) \ - KUNIT_BINARY_PTR_NE_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right) + KUNIT_EXPECT_PTR_NE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_PTR_NE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ @@ -1456,7 +1340,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_LT(test, left, right) \ - KUNIT_BINARY_LT_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_LT_MSG(test, left, right, NULL) #define KUNIT_EXPECT_LT_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_LT_MSG_ASSERTION(test, \ @@ -1478,7 +1362,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_LE(test, left, right) \ - KUNIT_BINARY_LE_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_LE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_LE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_LE_MSG_ASSERTION(test, \ @@ -1500,7 +1384,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_GT(test, left, right) \ - KUNIT_BINARY_GT_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_GT_MSG(test, left, right, NULL) #define KUNIT_EXPECT_GT_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_GT_MSG_ASSERTION(test, \ @@ -1522,7 +1406,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_GE(test, left, right) \ - KUNIT_BINARY_GE_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_GE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_GE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_GE_MSG_ASSERTION(test, \ @@ -1544,7 +1428,7 @@ do { \ * for more information. */ #define KUNIT_EXPECT_STREQ(test, left, right) \ - KUNIT_BINARY_STR_EQ_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_STREQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_STREQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_STR_EQ_MSG_ASSERTION(test, \ @@ -1566,7 +1450,7 @@ do { \ * for more information. */ #define KUNIT_EXPECT_STRNEQ(test, left, right) \ - KUNIT_BINARY_STR_NE_ASSERTION(test, KUNIT_EXPECTATION, left, right) + KUNIT_EXPECT_STRNEQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_STRNEQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ @@ -1587,7 +1471,7 @@ do { \ * more information. */ #define KUNIT_EXPECT_NOT_ERR_OR_NULL(test, ptr) \ - KUNIT_PTR_NOT_ERR_OR_NULL_ASSERTION(test, KUNIT_EXPECTATION, ptr) + KUNIT_EXPECT_NOT_ERR_OR_NULL_MSG(test, ptr, NULL) #define KUNIT_EXPECT_NOT_ERR_OR_NULL_MSG(test, ptr, fmt, ...) \ KUNIT_PTR_NOT_ERR_OR_NULL_MSG_ASSERTION(test, \ @@ -1611,7 +1495,7 @@ do { \ * this is otherwise known as an *assertion failure*. */ #define KUNIT_ASSERT_TRUE(test, condition) \ - KUNIT_TRUE_ASSERTION(test, KUNIT_ASSERTION, condition) + KUNIT_ASSERT_TRUE_MSG(test, condition, NULL) #define KUNIT_ASSERT_TRUE_MSG(test, condition, fmt, ...) \ KUNIT_TRUE_MSG_ASSERTION(test, \ @@ -1630,7 +1514,7 @@ do { \ * (see KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_FALSE(test, condition) \ - KUNIT_FALSE_ASSERTION(test, KUNIT_ASSERTION, condition) + KUNIT_ASSERT_FALSE_MSG(test, condition, NULL) #define KUNIT_ASSERT_FALSE_MSG(test, condition, fmt, ...) \ KUNIT_FALSE_MSG_ASSERTION(test, \ @@ -1650,7 +1534,7 @@ do { \ * failure (see KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_EQ(test, left, right) \ - KUNIT_BINARY_EQ_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_EQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_EQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ @@ -1671,7 +1555,7 @@ do { \ * failure (see KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_PTR_EQ(test, left, right) \ - KUNIT_BINARY_PTR_EQ_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_PTR_EQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_PTR_EQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ @@ -1692,7 +1576,7 @@ do { \ * failure (see KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_NE(test, left, right) \ - KUNIT_BINARY_NE_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_NE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_NE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_NE_MSG_ASSERTION(test, \ @@ -1714,7 +1598,7 @@ do { \ * failure (see KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_PTR_NE(test, left, right) \ - KUNIT_BINARY_PTR_NE_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_PTR_NE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_PTR_NE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ @@ -1735,7 +1619,7 @@ do { \ * is not met. */ #define KUNIT_ASSERT_LT(test, left, right) \ - KUNIT_BINARY_LT_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_LT_MSG(test, left, right, NULL) #define KUNIT_ASSERT_LT_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_LT_MSG_ASSERTION(test, \ @@ -1756,7 +1640,7 @@ do { \ * KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_LE(test, left, right) \ - KUNIT_BINARY_LE_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_LE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_LE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_LE_MSG_ASSERTION(test, \ @@ -1778,7 +1662,7 @@ do { \ * is not met. */ #define KUNIT_ASSERT_GT(test, left, right) \ - KUNIT_BINARY_GT_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_GT_MSG(test, left, right, NULL) #define KUNIT_ASSERT_GT_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_GT_MSG_ASSERTION(test, \ @@ -1800,7 +1684,7 @@ do { \ * is not met. */ #define KUNIT_ASSERT_GE(test, left, right) \ - KUNIT_BINARY_GE_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_GE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_GE_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_GE_MSG_ASSERTION(test, \ @@ -1821,7 +1705,7 @@ do { \ * assertion failure (see KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_STREQ(test, left, right) \ - KUNIT_BINARY_STR_EQ_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_STREQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_STREQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_STR_EQ_MSG_ASSERTION(test, \ @@ -1843,7 +1727,7 @@ do { \ * for more information. */ #define KUNIT_ASSERT_STRNEQ(test, left, right) \ - KUNIT_BINARY_STR_NE_ASSERTION(test, KUNIT_ASSERTION, left, right) + KUNIT_ASSERT_STRNEQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_STRNEQ_MSG(test, left, right, fmt, ...) \ KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ @@ -1864,7 +1748,7 @@ do { \ * KUNIT_ASSERT_TRUE()) when the assertion is not met. */ #define KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr) \ - KUNIT_PTR_NOT_ERR_OR_NULL_ASSERTION(test, KUNIT_ASSERTION, ptr) + KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr, NULL) #define KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr, fmt, ...) \ KUNIT_PTR_NOT_ERR_OR_NULL_MSG_ASSERTION(test, \ From c5855907d388321c1089023489e49ba9a5e9afc7 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 18 Jan 2022 14:35:03 -0800 Subject: [PATCH 015/124] kunit: drop unused intermediate macros for ptr inequality checks We have the intermediate macros for KUNIT_EXPECT_PTR_GT() and friends, but these macros don't exist. I can see niche usecases for these macros existing, but since we've been fine without them for so long, let's drop this dead code. Users can instead cast the pointers and use the other GT/LT macros. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 60 -------------------------------------------- 1 file changed, 60 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index b032dd6816d2..c021945a75e3 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -1044,21 +1044,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_LT_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_LT_MSG_ASSERTION(test, \ - kunit_binary_ptr_assert, \ - KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_LE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_LE_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1069,21 +1054,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_LE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_LE_MSG_ASSERTION(test, \ - kunit_binary_ptr_assert, \ - KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_GT_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_GT_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1094,21 +1064,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_GT_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_GT_MSG_ASSERTION(test, \ - kunit_binary_ptr_assert, \ - KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_GE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_GE_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -1119,21 +1074,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_GE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_GE_MSG_ASSERTION(test, \ - kunit_binary_ptr_assert, \ - KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_STR_ASSERTION(test, \ assert_type, \ left, \ From 955df7d85e58b8090f1fd2d10b4b2713e99b552c Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 18 Jan 2022 14:35:04 -0800 Subject: [PATCH 016/124] kunit: reduce layering in string assertion macros The current macro chain looks like: KUNIT_EXPECT_STREQ => KUNIT_EXPECT_STREQ_MSG => KUNIT_BINARY_STR_EQ_MSG_ASSERTION => KUNIT_BINARY_STR_ASSERTION. KUNIT_ASSERT_STREQ => KUNIT_ASSERT_STREQ_MSG => KUNIT_BINARY_STR_EQ_MSG_ASSERTION => KUNIT_BINARY_STR_ASSERTION. After this change: KUNIT_EXPECT_STREQ => KUNIT_EXPECT_STREQ_MSG => KUNIT_BINARY_STR_ASSERTION. KUNIT_ASSERT_STREQ => KUNIT_ASSERT_STREQ_MSG => KUNIT_BINARY_STR_ASSERTION. All the intermediate macro did was pass in "==" or "!=", so it seems better to just drop them at the cost of a bit more copy-paste. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 68 +++++++++++++------------------------------- 1 file changed, 20 insertions(+), 48 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index c021945a75e3..d5dc1ef68bfe 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -1098,30 +1098,6 @@ do { \ ##__VA_ARGS__); \ } while (0) -#define KUNIT_BINARY_STR_EQ_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BINARY_STR_ASSERTION(test, \ - assert_type, \ - left, ==, right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BINARY_STR_ASSERTION(test, \ - assert_type, \ - left, !=, right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_PTR_NOT_ERR_OR_NULL_MSG_ASSERTION(test, \ assert_type, \ ptr, \ @@ -1371,12 +1347,11 @@ do { \ KUNIT_EXPECT_STREQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_STREQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_STR_EQ_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_STR_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, ==, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_STRNEQ() - Expects that strings @left and @right are not equal. @@ -1393,12 +1368,11 @@ do { \ KUNIT_EXPECT_STRNEQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_STRNEQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_STR_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, !=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_NOT_ERR_OR_NULL() - Expects that @ptr is not null and not err. @@ -1648,12 +1622,11 @@ do { \ KUNIT_ASSERT_STREQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_STREQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_STR_EQ_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_STR_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, ==, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_STRNEQ() - Expects that strings @left and @right are not equal. @@ -1670,12 +1643,11 @@ do { \ KUNIT_ASSERT_STRNEQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_STRNEQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_STR_NE_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_STR_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, !=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_NOT_ERR_OR_NULL() - Assertion that @ptr is not null and not err. From 40f39777ce4f8e65ca16c10f1b895bbe8306a42f Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 18 Jan 2022 14:35:05 -0800 Subject: [PATCH 017/124] kunit: decrease macro layering for integer asserts Introduce a KUNIT_BINARY_INT_ASSERTION for the likes of KUNIT_EXPECT_LT. This is analagous to KUNIT_BINARY_STR_ASSERTION. Note: this patch leaves the EQ/NE macros untouched since those share some intermediate macros for the pointer-based macros. The current macro chain looks like: KUNIT_EXPECT_LT_MSG => KUNIT_BASE_LT_MSG_ASSERTION => KUNIT_BASE_BINARY_ASSERTION KUNIT_EXPECT_GT_MSG => KUNIT_BASE_GT_MSG_ASSERTION => KUNIT_BASE_BINARY_ASSERTION After this change: KUNIT_EXPECT_LT_MSG => KUNIT_BINARY_INT_ASSERTION => KUNIT_BASE_BINARY_ASSERTION KUNIT_EXPECT_GT_MSG => KUNIT_BINARY_INT_ASSERTION => KUNIT_BASE_BINARY_ASSERTION I.e. we've traded all the unique intermediary macros for a single shared KUNIT_BINARY_INT_ASSERTION. The only difference is that users of KUNIT_BINARY_INT_ASSERTION also need to pass the operation (==, <, etc.). Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 207 ++++++++++++------------------------------- 1 file changed, 55 insertions(+), 152 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index d5dc1ef68bfe..48cf520b69ce 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -920,70 +920,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BASE_LT_MSG_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_BINARY_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, <, right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BASE_LE_MSG_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_BINARY_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, <=, right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BASE_GT_MSG_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_BINARY_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, >, right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BASE_GE_MSG_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_BINARY_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, >=, right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_EQ_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ KUNIT_BASE_EQ_MSG_ASSERTION(test, \ kunit_binary_assert, \ @@ -994,6 +930,21 @@ do { \ fmt, \ ##__VA_ARGS__) +#define KUNIT_BINARY_INT_ASSERTION(test, \ + assert_type, \ + left, \ + op, \ + right, \ + fmt, \ + ...) \ + KUNIT_BASE_BINARY_ASSERTION(test, \ + kunit_binary_assert, \ + KUNIT_INIT_BINARY_ASSERT_STRUCT, \ + assert_type, \ + left, op, right, \ + fmt, \ + ##__VA_ARGS__) + #define KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ assert_type, \ left, \ @@ -1034,46 +985,6 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_LT_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ - KUNIT_BASE_LT_MSG_ASSERTION(test, \ - kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_LE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ - KUNIT_BASE_LE_MSG_ASSERTION(test, \ - kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_GT_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ - KUNIT_BASE_GT_MSG_ASSERTION(test, \ - kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_GE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ - KUNIT_BASE_GE_MSG_ASSERTION(test, \ - kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_STR_ASSERTION(test, \ assert_type, \ left, \ @@ -1259,12 +1170,11 @@ do { \ KUNIT_EXPECT_LT_MSG(test, left, right, NULL) #define KUNIT_EXPECT_LT_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_LT_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, <, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_LE() - Expects that @left is less than or equal to @right. @@ -1281,12 +1191,11 @@ do { \ KUNIT_EXPECT_LE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_LE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_LE_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, <=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_GT() - An expectation that @left is greater than @right. @@ -1303,12 +1212,11 @@ do { \ KUNIT_EXPECT_GT_MSG(test, left, right, NULL) #define KUNIT_EXPECT_GT_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_GT_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, >, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_GE() - Expects that @left is greater than or equal to @right. @@ -1325,12 +1233,11 @@ do { \ KUNIT_EXPECT_GE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_GE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_GE_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, >=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_STREQ() - Expects that strings @left and @right are equal. @@ -1536,12 +1443,11 @@ do { \ KUNIT_ASSERT_LT_MSG(test, left, right, NULL) #define KUNIT_ASSERT_LT_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_LT_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, <, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_LE() - An assertion that @left is less than or equal to @right. * @test: The test context object. @@ -1557,12 +1463,11 @@ do { \ KUNIT_ASSERT_LE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_LE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_LE_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, <=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_GT() - An assertion that @left is greater than @right. @@ -1579,12 +1484,11 @@ do { \ KUNIT_ASSERT_GT_MSG(test, left, right, NULL) #define KUNIT_ASSERT_GT_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_GT_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, >, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_GE() - Assertion that @left is greater than or equal to @right. @@ -1601,12 +1505,11 @@ do { \ KUNIT_ASSERT_GE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_GE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_GE_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, >=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_STREQ() - An assertion that strings @left and @right are equal. From 6125a5c70acddd9fc1fb7329047a254c74d0173c Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 18 Jan 2022 14:35:06 -0800 Subject: [PATCH 018/124] kunit: decrease macro layering for EQ/NE asserts Introduce KUNIT_BINARY_PTR_ASSERTION to match KUNIT_BINARY_INT_ASSERTION and make KUNIT_EXPECT_EQ and KUNIT_EXPECT_PTREQ use these instead of shared intermediate macros that only remove the need to type "==" or "!=". The current macro chain looks like: KUNIT_EXPECT_EQ_MSG => KUNIT_BINARY_EQ_MSG_ASSERTION => KUNIT_BASE_EQ_MSG_ASSERTION => KUNIT_BASE_BINARY_ASSERTION KUNIT_EXPECT_PTR_EQ_MSG => KUNIT_BINARY_PTR_EQ_MSG_ASSERTION => KUNIT_BASE_EQ_MSG_ASSERTION => KUNIT_BASE_BINARY_ASSERTION After this change: KUNIT_EXPECT_EQ_MSG => KUNIT_BINARY_INT_ASSERTION => KUNIT_BASE_BINARY_ASSERTION KUNIT_EXPECT_PTR_EQ_MSG => KUNIT_BINARY_PTR_ASSERTION => KUNIT_BASE_BINARY_ASSERTION Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 173 ++++++++++++------------------------------- 1 file changed, 49 insertions(+), 124 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index 48cf520b69ce..bf82c313223b 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -888,48 +888,6 @@ do { \ ##__VA_ARGS__); \ } while (0) -#define KUNIT_BASE_EQ_MSG_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_BINARY_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, ==, right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BASE_NE_MSG_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_BINARY_ASSERTION(test, \ - assert_class, \ - ASSERT_CLASS_INIT, \ - assert_type, \ - left, !=, right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_EQ_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ - KUNIT_BASE_EQ_MSG_ASSERTION(test, \ - kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - #define KUNIT_BINARY_INT_ASSERTION(test, \ assert_type, \ left, \ @@ -945,43 +903,18 @@ do { \ fmt, \ ##__VA_ARGS__) -#define KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_EQ_MSG_ASSERTION(test, \ +#define KUNIT_BINARY_PTR_ASSERTION(test, \ + assert_type, \ + left, \ + op, \ + right, \ + fmt, \ + ...) \ + KUNIT_BASE_BINARY_ASSERTION(test, \ kunit_binary_ptr_assert, \ KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_NE_MSG_ASSERTION(test, assert_type, left, right, fmt, ...)\ - KUNIT_BASE_NE_MSG_ASSERTION(test, \ - kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) - -#define KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ - assert_type, \ - left, \ - right, \ - fmt, \ - ...) \ - KUNIT_BASE_NE_MSG_ASSERTION(test, \ - kunit_binary_ptr_assert, \ - KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ - assert_type, \ - left, \ - right, \ + left, op, right, \ fmt, \ ##__VA_ARGS__) @@ -1082,12 +1015,11 @@ do { \ KUNIT_EXPECT_EQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_EQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, ==, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_PTR_EQ() - Expects that pointers @left and @right are equal. @@ -1104,12 +1036,11 @@ do { \ KUNIT_EXPECT_PTR_EQ_MSG(test, left, right, NULL) #define KUNIT_EXPECT_PTR_EQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_PTR_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, ==, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_NE() - An expectation that @left and @right are not equal. @@ -1126,12 +1057,11 @@ do { \ KUNIT_EXPECT_NE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_NE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_NE_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, !=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_PTR_NE() - Expects that pointers @left and @right are not equal. @@ -1148,12 +1078,11 @@ do { \ KUNIT_EXPECT_PTR_NE_MSG(test, left, right, NULL) #define KUNIT_EXPECT_PTR_NE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ - KUNIT_EXPECTATION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_PTR_ASSERTION(test, \ + KUNIT_EXPECTATION, \ + left, !=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_EXPECT_LT() - An expectation that @left is less than @right. @@ -1358,12 +1287,11 @@ do { \ KUNIT_ASSERT_EQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_EQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_EQ_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, ==, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_PTR_EQ() - Asserts that pointers @left and @right are equal. @@ -1379,12 +1307,11 @@ do { \ KUNIT_ASSERT_PTR_EQ_MSG(test, left, right, NULL) #define KUNIT_ASSERT_PTR_EQ_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_PTR_EQ_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_PTR_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, ==, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_NE() - An assertion that @left and @right are not equal. @@ -1400,12 +1327,11 @@ do { \ KUNIT_ASSERT_NE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_NE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_NE_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_INT_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, !=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_PTR_NE() - Asserts that pointers @left and @right are not equal. @@ -1422,12 +1348,11 @@ do { \ KUNIT_ASSERT_PTR_NE_MSG(test, left, right, NULL) #define KUNIT_ASSERT_PTR_NE_MSG(test, left, right, fmt, ...) \ - KUNIT_BINARY_PTR_NE_MSG_ASSERTION(test, \ - KUNIT_ASSERTION, \ - left, \ - right, \ - fmt, \ - ##__VA_ARGS__) + KUNIT_BINARY_PTR_ASSERTION(test, \ + KUNIT_ASSERTION, \ + left, !=, right, \ + fmt, \ + ##__VA_ARGS__) /** * KUNIT_ASSERT_LT() - An assertion that @left is less than @right. * @test: The test context object. From 8818a5342cb499b6959e821bf64c854e6a06bc82 Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Mon, 17 Jan 2022 02:01:34 +0000 Subject: [PATCH 019/124] ata: pata_platform: Make use of platform_get_mem_or_io() Make use of platform_get_mem_or_io() to simplify the code. While at it, drop use of unlikely() from pata_platform_probe() as it isn't a hotpath. Signed-off-by: Lad Prabhakar Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_platform.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c index 87c7c90676ca..21fb059859bd 100644 --- a/drivers/ata/pata_platform.c +++ b/drivers/ata/pata_platform.c @@ -200,22 +200,16 @@ static int pata_platform_probe(struct platform_device *pdev) /* * Get the I/O base first */ - io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (io_res == NULL) { - io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(io_res == NULL)) - return -EINVAL; - } + io_res = platform_get_mem_or_io(pdev, 0); + if (!io_res) + return -EINVAL; /* * Then the CTL base */ - ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); - if (ctl_res == NULL) { - ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (unlikely(ctl_res == NULL)) - return -EINVAL; - } + ctl_res = platform_get_mem_or_io(pdev, 1); + if (!ctl_res) + return -EINVAL; /* * And the IRQ From 9ab844253aeddcac8f21e2d5c496fa2a7b6baf64 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 23 Jan 2022 22:16:22 +0000 Subject: [PATCH 020/124] ata: pata_atiixp: make static read-only arrays const The static arrays pio_timings and mwdma_timings are read-only so it make sense to make them const. Signed-off-by: Colin Ian King Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_atiixp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c index c3a65ccd4b79..efdb94cff68b 100644 --- a/drivers/ata/pata_atiixp.c +++ b/drivers/ata/pata_atiixp.c @@ -102,7 +102,7 @@ static int atiixp_prereset(struct ata_link *link, unsigned long deadline) static void atiixp_set_pio_timing(struct ata_port *ap, struct ata_device *adev, int pio) { - static u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 }; + static const u8 pio_timings[5] = { 0x5D, 0x47, 0x34, 0x22, 0x20 }; struct pci_dev *pdev = to_pci_dev(ap->host->dev); int dn = 2 * ap->port_no + adev->devno; @@ -149,7 +149,7 @@ static void atiixp_set_piomode(struct ata_port *ap, struct ata_device *adev) static void atiixp_set_dmamode(struct ata_port *ap, struct ata_device *adev) { - static u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 }; + static const u8 mwdma_timings[5] = { 0x77, 0x21, 0x20 }; struct pci_dev *pdev = to_pci_dev(ap->host->dev); int dma = adev->dma_mode; From 217ca30fbf4b5e976d9170b85b5ed06f3511ef98 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Sun, 23 Jan 2022 22:22:46 +0000 Subject: [PATCH 021/124] ata: pata_pdc202xx_old: make static read-only array pio_timing const The static array pio_timing is read-only so it make sense to make it const. Signed-off-by: Colin Ian King Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_pdc202xx_old.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c index b99849095853..f894ff2de0a9 100644 --- a/drivers/ata/pata_pdc202xx_old.c +++ b/drivers/ata/pata_pdc202xx_old.c @@ -78,7 +78,7 @@ static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *a { struct pci_dev *pdev = to_pci_dev(ap->host->dev); int port = 0x60 + 8 * ap->port_no + 4 * adev->devno; - static u16 pio_timing[5] = { + static const u16 pio_timing[5] = { 0x0913, 0x050C , 0x0308, 0x0206, 0x0104 }; u8 r_ap, r_bp; From 7fdbacfad7c8c3c268bd86be6dee676d4eec8bc0 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 25 Jan 2022 10:14:36 +0900 Subject: [PATCH 022/124] ata: libata-scsi: Cleanup ata_get_xlat_func() Remove the unnecessary "break" after the return statement in the MODE_SELECT/MODE_SELECT_10 case. Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- drivers/ata/libata-scsi.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index ed8be585a98f..c73e94c06147 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3933,7 +3933,6 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) case MODE_SELECT: case MODE_SELECT_10: return ata_scsi_mode_select_xlat; - break; case ZBC_IN: return ata_scsi_zbc_in_xlat; From 261e150799305e546753554babccab83a0d50627 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 25 Jan 2022 10:21:25 +0900 Subject: [PATCH 023/124] ata: libata-scsi: Simplify ata_scsi_mode_select_xlat() Use get_unaligned_be16() instead of using hardcoded accesses to 16-bits big endian cdb fields. Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- drivers/ata/libata-scsi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c73e94c06147..515c5599cece 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3672,7 +3672,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) goto invalid_fld; } - len = (cdb[7] << 8) + cdb[8]; + len = get_unaligned_be16(&cdb[7]); hdr_len = 8; } @@ -3698,7 +3698,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) if (six_byte) bd_len = p[3]; else - bd_len = (p[6] << 8) + p[7]; + bd_len = get_unaligned_be16(&p[6]); len -= hdr_len; p += hdr_len; @@ -3722,7 +3722,7 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) goto invalid_param_len; spg = p[1]; - pg_len = (p[2] << 8) | p[3]; + pg_len = get_unaligned_be16(&p[2]); p += 4; len -= 4; } else { From 6e163f9b866a96ed6070f0653da477b3501d902a Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Tue, 25 Jan 2022 10:26:33 +0900 Subject: [PATCH 024/124] ata: libata-scsi: Simplify scsi_XX_lba_len() In scsi_10_lba_len() and scsi_16_lba_len() functions, use get_unaligned_bexx() to access a cdb LBA and length fields instead of hardcoding the byte retrieval. With these simplification, the functions can also be declared inline. Signed-off-by: Damien Le Moal Reviewed-by: Hannes Reinecke --- drivers/ata/libata-scsi.c | 40 ++++++--------------------------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 515c5599cece..eb40c3796a3f 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1314,21 +1314,10 @@ static void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen) * @plba: the LBA * @plen: the transfer length */ -static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen) +static inline void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen) { - u64 lba = 0; - u32 len = 0; - - lba |= ((u64)cdb[2]) << 24; - lba |= ((u64)cdb[3]) << 16; - lba |= ((u64)cdb[4]) << 8; - lba |= ((u64)cdb[5]); - - len |= ((u32)cdb[7]) << 8; - len |= ((u32)cdb[8]); - - *plba = lba; - *plen = len; + *plba = get_unaligned_be32(&cdb[2]); + *plen = get_unaligned_be16(&cdb[7]); } /** @@ -1341,27 +1330,10 @@ static void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen) * @plba: the LBA * @plen: the transfer length */ -static void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen) +static inline void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen) { - u64 lba = 0; - u32 len = 0; - - lba |= ((u64)cdb[2]) << 56; - lba |= ((u64)cdb[3]) << 48; - lba |= ((u64)cdb[4]) << 40; - lba |= ((u64)cdb[5]) << 32; - lba |= ((u64)cdb[6]) << 24; - lba |= ((u64)cdb[7]) << 16; - lba |= ((u64)cdb[8]) << 8; - lba |= ((u64)cdb[9]); - - len |= ((u32)cdb[10]) << 24; - len |= ((u32)cdb[11]) << 16; - len |= ((u32)cdb[12]) << 8; - len |= ((u32)cdb[13]); - - *plba = lba; - *plen = len; + *plba = get_unaligned_be64(&cdb[2]); + *plen = get_unaligned_be32(&cdb[10]); } /** From 95dcbc55fe4ffe262795bea02a42695c85a22dc4 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 18 Jan 2022 11:09:18 -0800 Subject: [PATCH 025/124] kunit: tool: drop mostly unused KunitResult.result field This field is only used to pass along the parsed Test object from parse_tests(). Everywhere else the `result` field is ignored. Instead make parse_tests() explicitly return a KunitResult and Test so we can retire the `result` field. Signed-off-by: Daniel Latypov Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- tools/testing/kunit/kunit.py | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/tools/testing/kunit/kunit.py b/tools/testing/kunit/kunit.py index 7a706f96f68d..9274c6355809 100755 --- a/tools/testing/kunit/kunit.py +++ b/tools/testing/kunit/kunit.py @@ -17,7 +17,7 @@ assert sys.version_info >= (3, 7), "Python version is too old" from dataclasses import dataclass from enum import Enum, auto -from typing import Any, Iterable, Sequence, List, Optional +from typing import Iterable, List, Optional, Sequence, Tuple import kunit_json import kunit_kernel @@ -32,7 +32,6 @@ class KunitStatus(Enum): @dataclass class KunitResult: status: KunitStatus - result: Any elapsed_time: float @dataclass @@ -82,10 +81,8 @@ def config_tests(linux: kunit_kernel.LinuxSourceTree, config_end = time.time() if not success: return KunitResult(KunitStatus.CONFIG_FAILURE, - 'could not configure kernel', config_end - config_start) return KunitResult(KunitStatus.SUCCESS, - 'configured kernel successfully', config_end - config_start) def build_tests(linux: kunit_kernel.LinuxSourceTree, @@ -100,14 +97,11 @@ def build_tests(linux: kunit_kernel.LinuxSourceTree, build_end = time.time() if not success: return KunitResult(KunitStatus.BUILD_FAILURE, - 'could not build kernel', build_end - build_start) if not success: return KunitResult(KunitStatus.BUILD_FAILURE, - 'could not build kernel', build_end - build_start) return KunitResult(KunitStatus.SUCCESS, - 'built kernel successfully', build_end - build_start) def config_and_build_tests(linux: kunit_kernel.LinuxSourceTree, @@ -173,14 +167,14 @@ def exec_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) - filter_glob=filter_glob, build_dir=request.build_dir) - result = parse_tests(request, run_result) + _, test_result = parse_tests(request, run_result) # run_kernel() doesn't block on the kernel exiting. # That only happens after we get the last line of output from `run_result`. # So exec_time here actually contains parsing + execution time, which is fine. test_end = time.time() exec_time += test_end - test_start - test_counts.add_subtest_counts(result.result.counts) + test_counts.add_subtest_counts(test_result.counts) if len(filter_globs) == 1 and test_counts.crashed > 0: bd = request.build_dir @@ -189,7 +183,7 @@ def exec_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitExecRequest) - bd, bd, kunit_kernel.get_outfile_path(bd), bd, sys.argv[0])) kunit_status = _map_to_overall_status(test_counts.get_status()) - return KunitResult(status=kunit_status, result=result, elapsed_time=exec_time) + return KunitResult(status=kunit_status, elapsed_time=exec_time) def _map_to_overall_status(test_status: kunit_parser.TestStatus) -> KunitStatus: if test_status in (kunit_parser.TestStatus.SUCCESS, kunit_parser.TestStatus.SKIPPED): @@ -197,7 +191,7 @@ def _map_to_overall_status(test_status: kunit_parser.TestStatus) -> KunitStatus: else: return KunitStatus.TEST_FAILURE -def parse_tests(request: KunitParseRequest, input_data: Iterable[str]) -> KunitResult: +def parse_tests(request: KunitParseRequest, input_data: Iterable[str]) -> Tuple[KunitResult, kunit_parser.Test]: parse_start = time.time() test_result = kunit_parser.Test() @@ -231,11 +225,9 @@ def parse_tests(request: KunitParseRequest, input_data: Iterable[str]) -> KunitR print(json_obj) if test_result.status != kunit_parser.TestStatus.SUCCESS: - return KunitResult(KunitStatus.TEST_FAILURE, test_result, - parse_end - parse_start) + return KunitResult(KunitStatus.TEST_FAILURE, parse_end - parse_start), test_result - return KunitResult(KunitStatus.SUCCESS, test_result, - parse_end - parse_start) + return KunitResult(KunitStatus.SUCCESS, parse_end - parse_start), test_result def run_tests(linux: kunit_kernel.LinuxSourceTree, request: KunitRequest) -> KunitResult: @@ -513,7 +505,7 @@ def main(argv, linux=None): request = KunitParseRequest(raw_output=cli_args.raw_output, build_dir='', json=cli_args.json) - result = parse_tests(request, kunit_output) + result, _ = parse_tests(request, kunit_output) if result.status != KunitStatus.SUCCESS: sys.exit(1) else: From 6419abb80e82c603bbec6d7f5af6c2f79fa5c4ae Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 25 Jan 2022 13:00:09 -0800 Subject: [PATCH 026/124] kunit: remove va_format from kunit_assert The concern is that having a lot of redundant fields in kunit_assert can blow up stack usage if the compiler doesn't optimize them away [1]. The comment on this field implies that it was meant to be initialized when the expect/assert was declared, but this only happens when we run kunit_do_failed_assertion(). We don't need to access it outside of that function, so move it out of the struct and make it a local variable there. This change also takes the chance to reduce the number of macros by inlining the now simplified KUNIT_INIT_ASSERT_STRUCT() macro. [1] https://groups.google.com/g/kunit-dev/c/i3fZXgvBrfA/m/VULQg1z6BAAJ Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/assert.h | 43 +++++++++++++----------------------------- lib/kunit/assert.c | 27 +++++++++++++++----------- lib/kunit/test.c | 12 +++++++----- 3 files changed, 36 insertions(+), 46 deletions(-) diff --git a/include/kunit/assert.h b/include/kunit/assert.h index f2b3ae5cc2de..0b3704db54b6 100644 --- a/include/kunit/assert.h +++ b/include/kunit/assert.h @@ -42,44 +42,21 @@ struct kunit_loc { /** * struct kunit_assert - Data for printing a failed assertion or expectation. - * @message: an optional message to provide additional context. * @format: a function which formats the data in this kunit_assert to a string. * * Represents a failed expectation/assertion. Contains all the data necessary to * format a string to a user reporting the failure. */ struct kunit_assert { - struct va_format message; void (*format)(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); }; -/** - * KUNIT_INIT_VA_FMT_NULL - Default initializer for struct va_format. - * - * Used inside a struct initialization block to initialize struct va_format to - * default values where fmt and va are null. - */ -#define KUNIT_INIT_VA_FMT_NULL { .fmt = NULL, .va = NULL } - -/** - * KUNIT_INIT_ASSERT_STRUCT() - Initializer for a &struct kunit_assert. - * @fmt: The formatting function which builds a string out of this kunit_assert. - * - * The base initializer for a &struct kunit_assert. - */ -#define KUNIT_INIT_ASSERT_STRUCT(fmt) { \ - .message = KUNIT_INIT_VA_FMT_NULL, \ - .format = fmt \ -} - void kunit_assert_prologue(const struct kunit_loc *loc, enum kunit_assert_type type, struct string_stream *stream); -void kunit_assert_print_msg(const struct kunit_assert *assert, - struct string_stream *stream); - /** * struct kunit_fail_assert - Represents a plain fail expectation/assertion. * @assert: The parent of this type. @@ -91,6 +68,7 @@ struct kunit_fail_assert { }; void kunit_fail_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); /** @@ -100,7 +78,7 @@ void kunit_fail_assert_format(const struct kunit_assert *assert, * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ #define KUNIT_INIT_FAIL_ASSERT_STRUCT { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_fail_assert_format) \ + .assert = { .format = kunit_fail_assert_format }, \ } /** @@ -120,6 +98,7 @@ struct kunit_unary_assert { }; void kunit_unary_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); /** @@ -131,7 +110,7 @@ void kunit_unary_assert_format(const struct kunit_assert *assert, * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ #define KUNIT_INIT_UNARY_ASSERT_STRUCT(cond, expect_true) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_unary_assert_format), \ + .assert = { .format = kunit_unary_assert_format }, \ .condition = cond, \ .expected_true = expect_true \ } @@ -153,6 +132,7 @@ struct kunit_ptr_not_err_assert { }; void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); /** @@ -165,7 +145,7 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. */ #define KUNIT_INIT_PTR_NOT_ERR_STRUCT(txt, val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_ptr_not_err_assert_format), \ + .assert = { .format = kunit_ptr_not_err_assert_format }, \ .text = txt, \ .value = val \ } @@ -194,6 +174,7 @@ struct kunit_binary_assert { }; void kunit_binary_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); /** @@ -213,7 +194,7 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_binary_assert_format), \ + .assert = { .format = kunit_binary_assert_format }, \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ @@ -245,6 +226,7 @@ struct kunit_binary_ptr_assert { }; void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); /** @@ -265,7 +247,7 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_binary_ptr_assert_format), \ + .assert = { .format = kunit_binary_ptr_assert_format }, \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ @@ -297,6 +279,7 @@ struct kunit_binary_str_assert { }; void kunit_binary_str_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream); /** @@ -316,7 +299,7 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, left_val, \ right_str, \ right_val) { \ - .assert = KUNIT_INIT_ASSERT_STRUCT(kunit_binary_str_assert_format), \ + .assert = { .format = kunit_binary_str_assert_format }, \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c index 9f4492a8e24e..c9c7ee0dfafa 100644 --- a/lib/kunit/assert.c +++ b/lib/kunit/assert.c @@ -30,22 +30,23 @@ void kunit_assert_prologue(const struct kunit_loc *loc, } EXPORT_SYMBOL_GPL(kunit_assert_prologue); -void kunit_assert_print_msg(const struct kunit_assert *assert, - struct string_stream *stream) +static void kunit_assert_print_msg(const struct va_format *message, + struct string_stream *stream) { - if (assert->message.fmt) - string_stream_add(stream, "\n%pV", &assert->message); + if (message->fmt) + string_stream_add(stream, "\n%pV", message); } -EXPORT_SYMBOL_GPL(kunit_assert_print_msg); void kunit_fail_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream) { - string_stream_add(stream, "%pV", &assert->message); + string_stream_add(stream, "%pV", message); } EXPORT_SYMBOL_GPL(kunit_fail_assert_format); void kunit_unary_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream) { struct kunit_unary_assert *unary_assert; @@ -60,11 +61,12 @@ void kunit_unary_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n", unary_assert->condition); - kunit_assert_print_msg(assert, stream); + kunit_assert_print_msg(message, stream); } EXPORT_SYMBOL_GPL(kunit_unary_assert_format); void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream) { struct kunit_ptr_not_err_assert *ptr_assert; @@ -82,7 +84,7 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, ptr_assert->text, PTR_ERR(ptr_assert->value)); } - kunit_assert_print_msg(assert, stream); + kunit_assert_print_msg(message, stream); } EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format); @@ -110,6 +112,7 @@ static bool is_literal(struct kunit *test, const char *text, long long value, } void kunit_binary_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream) { struct kunit_binary_assert *binary_assert; @@ -132,11 +135,12 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld", binary_assert->right_text, binary_assert->right_value); - kunit_assert_print_msg(assert, stream); + kunit_assert_print_msg(message, stream); } EXPORT_SYMBOL_GPL(kunit_binary_assert_format); void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream) { struct kunit_binary_ptr_assert *binary_assert; @@ -155,7 +159,7 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px", binary_assert->right_text, binary_assert->right_value); - kunit_assert_print_msg(assert, stream); + kunit_assert_print_msg(message, stream); } EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format); @@ -176,6 +180,7 @@ static bool is_str_literal(const char *text, const char *value) } void kunit_binary_str_assert_format(const struct kunit_assert *assert, + const struct va_format *message, struct string_stream *stream) { struct kunit_binary_str_assert *binary_assert; @@ -196,6 +201,6 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"", binary_assert->right_text, binary_assert->right_value); - kunit_assert_print_msg(assert, stream); + kunit_assert_print_msg(message, stream); } EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format); diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 7dec3248562f..3bca3bf5c15b 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -241,7 +241,8 @@ static void kunit_print_string_stream(struct kunit *test, } static void kunit_fail(struct kunit *test, const struct kunit_loc *loc, - enum kunit_assert_type type, struct kunit_assert *assert) + enum kunit_assert_type type, struct kunit_assert *assert, + const struct va_format *message) { struct string_stream *stream; @@ -257,7 +258,7 @@ static void kunit_fail(struct kunit *test, const struct kunit_loc *loc, } kunit_assert_prologue(loc, type, stream); - assert->format(assert, stream); + assert->format(assert, message, stream); kunit_print_string_stream(test, stream); @@ -284,12 +285,13 @@ void kunit_do_failed_assertion(struct kunit *test, const char *fmt, ...) { va_list args; + struct va_format message; va_start(args, fmt); - assert->message.fmt = fmt; - assert->message.va = &args; + message.fmt = fmt; + message.va = &args; - kunit_fail(test, loc, type, assert); + kunit_fail(test, loc, type, assert, &message); va_end(args); From 064ff292aca500d6b911dca6abe1ece22620d475 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 25 Jan 2022 13:00:10 -0800 Subject: [PATCH 027/124] kunit: consolidate KUNIT_INIT_BINARY_ASSERT_STRUCT macros We currently have 2 other versions of KUNIT_INIT_BINARY_ASSERT_STRUCT. The only differences are that * the format funcition they pass is different * the types of left_val/right_val should be different (integral, pointer, string). The latter doesn't actually matter since these macros are just plumbing them along to KUNIT_ASSERTION where they will get type checked. So combine them all into a single KUNIT_INIT_BINARY_ASSERT_STRUCT that now also takes the format function as a parameter. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/assert.h | 68 +++++++----------------------------------- include/kunit/test.h | 20 +++++++------ 2 files changed, 22 insertions(+), 66 deletions(-) diff --git a/include/kunit/assert.h b/include/kunit/assert.h index 0b3704db54b6..649bfac9f406 100644 --- a/include/kunit/assert.h +++ b/include/kunit/assert.h @@ -178,23 +178,28 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, struct string_stream *stream); /** - * KUNIT_INIT_BINARY_ASSERT_STRUCT() - Initializes a - * &struct kunit_binary_assert. + * KUNIT_INIT_BINARY_ASSERT_STRUCT() - Initializes a binary assert like + * kunit_binary_assert, kunit_binary_ptr_assert, etc. + * + * @format_func: a function which formats the assert to a string. * @op_str: A string representation of the comparison operator (e.g. "=="). * @left_str: A string representation of the expression in the left slot. * @left_val: The actual evaluated value of the expression in the left slot. * @right_str: A string representation of the expression in the right slot. * @right_val: The actual evaluated value of the expression in the right slot. * - * Initializes a &struct kunit_binary_assert. Intended to be used in - * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. + * Initializes a binary assert like kunit_binary_assert, + * kunit_binary_ptr_assert, etc. This relies on these structs having the same + * fields but with different types for left_val/right_val. + * This is ultimately used by binary assertion macros like KUNIT_EXPECT_EQ, etc. */ -#define KUNIT_INIT_BINARY_ASSERT_STRUCT(op_str, \ +#define KUNIT_INIT_BINARY_ASSERT_STRUCT(format_func, \ + op_str, \ left_str, \ left_val, \ right_str, \ right_val) { \ - .assert = { .format = kunit_binary_assert_format }, \ + .assert = { .format = format_func }, \ .operation = op_str, \ .left_text = left_str, \ .left_value = left_val, \ @@ -229,32 +234,6 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream); -/** - * KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT() - Initializes a - * &struct kunit_binary_ptr_assert. - * @type: The type (assertion or expectation) of this kunit_assert. - * @op_str: A string representation of the comparison operator (e.g. "=="). - * @left_str: A string representation of the expression in the left slot. - * @left_val: The actual evaluated value of the expression in the left slot. - * @right_str: A string representation of the expression in the right slot. - * @right_val: The actual evaluated value of the expression in the right slot. - * - * Initializes a &struct kunit_binary_ptr_assert. Intended to be used in - * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. - */ -#define KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT(op_str, \ - left_str, \ - left_val, \ - right_str, \ - right_val) { \ - .assert = { .format = kunit_binary_ptr_assert_format }, \ - .operation = op_str, \ - .left_text = left_str, \ - .left_value = left_val, \ - .right_text = right_str, \ - .right_value = right_val \ -} - /** * struct kunit_binary_str_assert - An expectation/assertion that compares two * string values (for example, KUNIT_EXPECT_STREQ(test, foo, "bar")). @@ -282,29 +261,4 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream); -/** - * KUNIT_INIT_BINARY_STR_ASSERT_STRUCT() - Initializes a - * &struct kunit_binary_str_assert. - * @op_str: A string representation of the comparison operator (e.g. "=="). - * @left_str: A string representation of the expression in the left slot. - * @left_val: The actual evaluated value of the expression in the left slot. - * @right_str: A string representation of the expression in the right slot. - * @right_val: The actual evaluated value of the expression in the right slot. - * - * Initializes a &struct kunit_binary_str_assert. Intended to be used in - * KUNIT_EXPECT_* and KUNIT_ASSERT_* macros. - */ -#define KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(op_str, \ - left_str, \ - left_val, \ - right_str, \ - right_val) { \ - .assert = { .format = kunit_binary_str_assert_format }, \ - .operation = op_str, \ - .left_text = left_str, \ - .left_value = left_val, \ - .right_text = right_str, \ - .right_value = right_val \ -} - #endif /* _KUNIT_ASSERT_H */ diff --git a/include/kunit/test.h b/include/kunit/test.h index bf82c313223b..a93dfb8ff393 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -864,7 +864,7 @@ void kunit_do_failed_assertion(struct kunit *test, */ #define KUNIT_BASE_BINARY_ASSERTION(test, \ assert_class, \ - ASSERT_CLASS_INIT, \ + format_func, \ assert_type, \ left, \ op, \ @@ -879,11 +879,12 @@ do { \ assert_type, \ __left op __right, \ assert_class, \ - ASSERT_CLASS_INIT(#op, \ - #left, \ - __left, \ - #right, \ - __right), \ + KUNIT_INIT_BINARY_ASSERT_STRUCT(format_func, \ + #op, \ + #left, \ + __left, \ + #right, \ + __right), \ fmt, \ ##__VA_ARGS__); \ } while (0) @@ -897,7 +898,7 @@ do { \ ...) \ KUNIT_BASE_BINARY_ASSERTION(test, \ kunit_binary_assert, \ - KUNIT_INIT_BINARY_ASSERT_STRUCT, \ + kunit_binary_assert_format, \ assert_type, \ left, op, right, \ fmt, \ @@ -912,7 +913,7 @@ do { \ ...) \ KUNIT_BASE_BINARY_ASSERTION(test, \ kunit_binary_ptr_assert, \ - KUNIT_INIT_BINARY_PTR_ASSERT_STRUCT, \ + kunit_binary_ptr_assert_format, \ assert_type, \ left, op, right, \ fmt, \ @@ -933,7 +934,8 @@ do { \ assert_type, \ strcmp(__left, __right) op 0, \ kunit_binary_str_assert, \ - KUNIT_INIT_BINARY_STR_ASSERT_STRUCT(#op, \ + KUNIT_INIT_BINARY_ASSERT_STRUCT(kunit_binary_str_assert_format,\ + #op, \ #left, \ __left, \ #right, \ From 2b6861e2372bac68861c54372f68f6016a7484fc Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Tue, 25 Jan 2022 13:00:11 -0800 Subject: [PATCH 028/124] kunit: factor out str constants from binary assertion structs If the compiler doesn't optimize them away, each kunit assertion (use of KUNIT_EXPECT_EQ, etc.) can use 88 bytes of stack space in the worst and most common case. This has led to compiler warnings and a suggestion from Linus to move data from the structs into static const's where possible [1]. This builds upon [2] which did so for the base struct kunit_assert type. That only reduced sizeof(struct kunit_binary_assert) from 88 to 64. Given these are by far the most commonly used asserts, this patch factors out the textual representations of the operands and comparator into another static const, saving 16 more bytes. In detail, KUNIT_EXPECT_EQ(test, 2 + 2, 5) yields the following struct (struct kunit_binary_assert) { .assert = , .operation = "==", .left_text = "2 + 2", .left_value = 4, .right_text = "5", .right_value = 5, } After this change static const struct kunit_binary_assert_text __text = { .operation = "==", .left_text = "2 + 2", .right_text = "5", }; (struct kunit_binary_assert) { .assert = , .text = &__text, .left_value = 4, .right_value = 5, } This also DRYs the code a bit more since these str fields were repeated for the string and pointer versions of kunit_binary_assert. Note: we could name the kunit_binary_assert_text fields left/right instead of left_text/right_text. But that would require changing the macros a bit since they have args called "left" and "right" which would be substituted in `.left = #left` as `.2 + 2 = \"2 + 2\"`. [1] https://groups.google.com/g/kunit-dev/c/i3fZXgvBrfA/m/VULQg1z6BAAJ [2] https://lore.kernel.org/linux-kselftest/20220113165931.451305-6-dlatypov@google.com/ Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/assert.h | 49 +++++++++++++++++++----------------------- include/kunit/test.h | 20 +++++++++++------ lib/kunit/assert.c | 38 ++++++++++++++++---------------- 3 files changed, 54 insertions(+), 53 deletions(-) diff --git a/include/kunit/assert.h b/include/kunit/assert.h index 649bfac9f406..4b52e12c2ae8 100644 --- a/include/kunit/assert.h +++ b/include/kunit/assert.h @@ -150,14 +150,25 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, .value = val \ } +/** + * struct kunit_binary_assert_text - holds strings for &struct + * kunit_binary_assert and friends to try and make the structs smaller. + * @operation: A string representation of the comparison operator (e.g. "=="). + * @left_text: A string representation of the left expression (e.g. "2+2"). + * @right_text: A string representation of the right expression (e.g. "2+2"). + */ +struct kunit_binary_assert_text { + const char *operation; + const char *left_text; + const char *right_text; +}; + /** * struct kunit_binary_assert - An expectation/assertion that compares two * non-pointer values (for example, KUNIT_EXPECT_EQ(test, 1 + 1, 2)). * @assert: The parent of this type. - * @operation: A string representation of the comparison operator (e.g. "=="). - * @left_text: A string representation of the expression in the left slot. + * @text: Holds the textual representations of the operands and op (e.g. "=="). * @left_value: The actual evaluated value of the expression in the left slot. - * @right_text: A string representation of the expression in the right slot. * @right_value: The actual evaluated value of the expression in the right slot. * * Represents an expectation/assertion that compares two non-pointer values. For @@ -166,10 +177,8 @@ void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, */ struct kunit_binary_assert { struct kunit_assert assert; - const char *operation; - const char *left_text; + const struct kunit_binary_assert_text *text; long long left_value; - const char *right_text; long long right_value; }; @@ -182,10 +191,8 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, * kunit_binary_assert, kunit_binary_ptr_assert, etc. * * @format_func: a function which formats the assert to a string. - * @op_str: A string representation of the comparison operator (e.g. "=="). - * @left_str: A string representation of the expression in the left slot. + * @text_: Pointer to a kunit_binary_assert_text. * @left_val: The actual evaluated value of the expression in the left slot. - * @right_str: A string representation of the expression in the right slot. * @right_val: The actual evaluated value of the expression in the right slot. * * Initializes a binary assert like kunit_binary_assert, @@ -194,16 +201,12 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, * This is ultimately used by binary assertion macros like KUNIT_EXPECT_EQ, etc. */ #define KUNIT_INIT_BINARY_ASSERT_STRUCT(format_func, \ - op_str, \ - left_str, \ + text_, \ left_val, \ - right_str, \ right_val) { \ .assert = { .format = format_func }, \ - .operation = op_str, \ - .left_text = left_str, \ + .text = text_, \ .left_value = left_val, \ - .right_text = right_str, \ .right_value = right_val \ } @@ -211,10 +214,8 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, * struct kunit_binary_ptr_assert - An expectation/assertion that compares two * pointer values (for example, KUNIT_EXPECT_PTR_EQ(test, foo, bar)). * @assert: The parent of this type. - * @operation: A string representation of the comparison operator (e.g. "=="). - * @left_text: A string representation of the expression in the left slot. + * @text: Holds the textual representations of the operands and op (e.g. "=="). * @left_value: The actual evaluated value of the expression in the left slot. - * @right_text: A string representation of the expression in the right slot. * @right_value: The actual evaluated value of the expression in the right slot. * * Represents an expectation/assertion that compares two pointer values. For @@ -223,10 +224,8 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, */ struct kunit_binary_ptr_assert { struct kunit_assert assert; - const char *operation; - const char *left_text; + const struct kunit_binary_assert_text *text; const void *left_value; - const char *right_text; const void *right_value; }; @@ -238,10 +237,8 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, * struct kunit_binary_str_assert - An expectation/assertion that compares two * string values (for example, KUNIT_EXPECT_STREQ(test, foo, "bar")). * @assert: The parent of this type. - * @operation: A string representation of the comparison operator (e.g. "=="). - * @left_text: A string representation of the expression in the left slot. + * @text: Holds the textual representations of the operands and comparator. * @left_value: The actual evaluated value of the expression in the left slot. - * @right_text: A string representation of the expression in the right slot. * @right_value: The actual evaluated value of the expression in the right slot. * * Represents an expectation/assertion that compares two string values. For @@ -250,10 +247,8 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, */ struct kunit_binary_str_assert { struct kunit_assert assert; - const char *operation; - const char *left_text; + const struct kunit_binary_assert_text *text; const char *left_value; - const char *right_text; const char *right_value; }; diff --git a/include/kunit/test.h b/include/kunit/test.h index a93dfb8ff393..088ff394ae94 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -874,16 +874,19 @@ void kunit_do_failed_assertion(struct kunit *test, do { \ typeof(left) __left = (left); \ typeof(right) __right = (right); \ + static const struct kunit_binary_assert_text __text = { \ + .operation = #op, \ + .left_text = #left, \ + .right_text = #right, \ + }; \ \ KUNIT_ASSERTION(test, \ assert_type, \ __left op __right, \ assert_class, \ KUNIT_INIT_BINARY_ASSERT_STRUCT(format_func, \ - #op, \ - #left, \ + &__text, \ __left, \ - #right, \ __right), \ fmt, \ ##__VA_ARGS__); \ @@ -928,17 +931,20 @@ do { \ ...) \ do { \ const char *__left = (left); \ - const char *__right = (right); \ + const char *__right = (right); \ + static const struct kunit_binary_assert_text __text = { \ + .operation = #op, \ + .left_text = #left, \ + .right_text = #right, \ + }; \ \ KUNIT_ASSERTION(test, \ assert_type, \ strcmp(__left, __right) op 0, \ kunit_binary_str_assert, \ KUNIT_INIT_BINARY_ASSERT_STRUCT(kunit_binary_str_assert_format,\ - #op, \ - #left, \ + &__text, \ __left, \ - #right, \ __right), \ fmt, \ ##__VA_ARGS__); \ diff --git a/lib/kunit/assert.c b/lib/kunit/assert.c index c9c7ee0dfafa..d00d6d181ee8 100644 --- a/lib/kunit/assert.c +++ b/lib/kunit/assert.c @@ -122,18 +122,18 @@ void kunit_binary_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", - binary_assert->left_text, - binary_assert->operation, - binary_assert->right_text); - if (!is_literal(stream->test, binary_assert->left_text, + binary_assert->text->left_text, + binary_assert->text->operation, + binary_assert->text->right_text); + if (!is_literal(stream->test, binary_assert->text->left_text, binary_assert->left_value, stream->gfp)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n", - binary_assert->left_text, + binary_assert->text->left_text, binary_assert->left_value); - if (!is_literal(stream->test, binary_assert->right_text, + if (!is_literal(stream->test, binary_assert->text->right_text, binary_assert->right_value, stream->gfp)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld", - binary_assert->right_text, + binary_assert->text->right_text, binary_assert->right_value); kunit_assert_print_msg(message, stream); } @@ -150,14 +150,14 @@ void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", - binary_assert->left_text, - binary_assert->operation, - binary_assert->right_text); + binary_assert->text->left_text, + binary_assert->text->operation, + binary_assert->text->right_text); string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n", - binary_assert->left_text, + binary_assert->text->left_text, binary_assert->left_value); string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px", - binary_assert->right_text, + binary_assert->text->right_text, binary_assert->right_value); kunit_assert_print_msg(message, stream); } @@ -190,16 +190,16 @@ void kunit_binary_str_assert_format(const struct kunit_assert *assert, string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", - binary_assert->left_text, - binary_assert->operation, - binary_assert->right_text); - if (!is_str_literal(binary_assert->left_text, binary_assert->left_value)) + binary_assert->text->left_text, + binary_assert->text->operation, + binary_assert->text->right_text); + if (!is_str_literal(binary_assert->text->left_text, binary_assert->left_value)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n", - binary_assert->left_text, + binary_assert->text->left_text, binary_assert->left_value); - if (!is_str_literal(binary_assert->right_text, binary_assert->right_value)) + if (!is_str_literal(binary_assert->text->right_text, binary_assert->right_value)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"", - binary_assert->right_text, + binary_assert->text->right_text, binary_assert->right_value); kunit_assert_print_msg(message, stream); } From c2741453478badf571ef020d160053e8d5e1ba94 Mon Sep 17 00:00:00 2001 From: Daniel Latypov Date: Thu, 27 Jan 2022 13:52:22 -0800 Subject: [PATCH 029/124] kunit: cleanup assertion macro internal variables All the operands should be tagged `const`. We're only assigning them to variables so that we can compare them (e.g. check if left == right, etc.) and avoid evaluating expressions multiple times. There's no need for them to be mutable. Also rename the helper variable `loc` to `__loc` like we do with `__assertion` and `__strs` to avoid potential name collisions with user code. Signed-off-by: Daniel Latypov Reviewed-by: David Gow Reviewed-by: Brendan Higgins Signed-off-by: Shuah Khan --- include/kunit/test.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/kunit/test.h b/include/kunit/test.h index 088ff394ae94..00b9ff7783ab 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h @@ -779,10 +779,10 @@ void kunit_do_failed_assertion(struct kunit *test, #define KUNIT_ASSERTION(test, assert_type, pass, assert_class, INITIALIZER, fmt, ...) do { \ if (unlikely(!(pass))) { \ - static const struct kunit_loc loc = KUNIT_CURRENT_LOC; \ + static const struct kunit_loc __loc = KUNIT_CURRENT_LOC; \ struct assert_class __assertion = INITIALIZER; \ kunit_do_failed_assertion(test, \ - &loc, \ + &__loc, \ assert_type, \ &__assertion.assert, \ fmt, \ @@ -872,8 +872,8 @@ void kunit_do_failed_assertion(struct kunit *test, fmt, \ ...) \ do { \ - typeof(left) __left = (left); \ - typeof(right) __right = (right); \ + const typeof(left) __left = (left); \ + const typeof(right) __right = (right); \ static const struct kunit_binary_assert_text __text = { \ .operation = #op, \ .left_text = #left, \ @@ -956,7 +956,7 @@ do { \ fmt, \ ...) \ do { \ - typeof(ptr) __ptr = (ptr); \ + const typeof(ptr) __ptr = (ptr); \ \ KUNIT_ASSERTION(test, \ assert_type, \ From 2a7b02ea7f8f79e9f048e68f535bb6158034ac96 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Tue, 1 Feb 2022 23:50:10 +0300 Subject: [PATCH 030/124] ata: libata-acpi: kill ata_acpi_on_suspend() Since the commit c05e6ff035c1b25d17364a685432 ("libata-acpi: implement and use ata_acpi_init_gtm()") ata_acpi_on_suspend() just returns 0, so its call from ata_eh_handle_port_suspend() doesn't make sense anymore. Remove the function completely, at last... Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-acpi.c | 21 --------------------- drivers/ata/libata-eh.c | 7 +------ drivers/ata/libata.h | 2 -- 3 files changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 8cfa8c96bb13..b788f5a4565c 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -799,27 +799,6 @@ static int ata_acpi_push_id(struct ata_device *dev) return 0; } -/** - * ata_acpi_on_suspend - ATA ACPI hook called on suspend - * @ap: target ATA port - * - * This function is called when @ap is about to be suspended. All - * devices are already put to sleep but the port_suspend() callback - * hasn't been executed yet. Error return from this function aborts - * suspend. - * - * LOCKING: - * EH context. - * - * RETURNS: - * 0 on success, -errno on failure. - */ -int ata_acpi_on_suspend(struct ata_port *ap) -{ - /* nada */ - return 0; -} - /** * ata_acpi_on_resume - ATA ACPI hook called on resume * @ap: target ATA port diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7951fd946bf9..e31341c9ac61 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3902,11 +3902,6 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) } } - /* tell ACPI we're suspending */ - rc = ata_acpi_on_suspend(ap); - if (rc) - goto out; - /* suspend */ ata_eh_freeze_port(ap); @@ -3914,7 +3909,7 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) rc = ap->ops->port_suspend(ap, ap->pm_mesg); ata_acpi_set_state(ap, ap->pm_mesg); - out: + /* update the flags */ spin_lock_irqsave(ap->lock, flags); diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 51e01acdd241..c9c2496d91ea 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -107,7 +107,6 @@ static inline void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) { } #ifdef CONFIG_ATA_ACPI extern unsigned int ata_acpi_gtf_filter; extern void ata_acpi_dissociate(struct ata_host *host); -extern int ata_acpi_on_suspend(struct ata_port *ap); extern void ata_acpi_on_resume(struct ata_port *ap); extern int ata_acpi_on_devcfg(struct ata_device *dev); extern void ata_acpi_on_disable(struct ata_device *dev); @@ -117,7 +116,6 @@ extern void ata_acpi_bind_dev(struct ata_device *dev); extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev); #else static inline void ata_acpi_dissociate(struct ata_host *host) { } -static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; } static inline void ata_acpi_on_resume(struct ata_port *ap) { } static inline int ata_acpi_on_devcfg(struct ata_device *dev) { return 0; } static inline void ata_acpi_on_disable(struct ata_device *dev) { } From f4a8d4f2b65dd5e3b92b7207f7995a24d13d197e Mon Sep 17 00:00:00 2001 From: Paul Menzel Date: Tue, 1 Feb 2022 08:12:23 +0100 Subject: [PATCH 031/124] ata: ahci: Skip 200 ms debounce delay for Marvell 88SE9235 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 200 ms delay before debouncing the PHY in `sata_link_resume()` is not needed for the Marvell 88SE9235. $ lspci -nn -s 0021:0e:00.0 0021:0e:00.0 SATA controller [0106]: Marvell Technology Group Ltd. 88SE9235 PCIe 2.0 x2 4-port SATA 6 Gb/s Controller [1b4b:9235] (rev 11) So, remove it using the board_ahci_no_debounce_delay board definition. Tested on IBM S822LC with current Linux 5.17-rc1: Currently, without this patch (with 200 ms delay), device probe for ata1 takes 485 ms: [ 3.358158] ata1: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3fe881000100 irq 39 [ 3.358175] ata2: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3fe881000180 irq 39 [ 3.358191] ata3: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3fe881000200 irq 39 [ 3.358207] ata4: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3fe881000280 irq 39 […] [ 3.677542] ata3: SATA link down (SStatus 0 SControl 300) [ 3.677719] ata4: SATA link down (SStatus 0 SControl 300) [ 3.839242] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300) [ 3.839828] ata2.00: ATA-10: ST1000NX0313 00LY266 00LY265IBM, BE33, max UDMA/133 [ 3.840029] ata2.00: 1953525168 sectors, multi 0: LBA48 NCQ (depth 32), AA [ 3.841796] ata2.00: configured for UDMA/133 [ 3.843231] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300) [ 3.844083] ata1.00: ATA-10: ST1000NX0313 00LY266 00LY265IBM, BE33, max UDMA/133 [ 3.844313] ata1.00: 1953525168 sectors, multi 0: LBA48 NCQ (depth 32), AA [ 3.846043] ata1.00: configured for UDMA/133 With this patch (no delay) device probe for ata1 takes 273 ms: [ 3.624259] ata1: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3f e881000100 irq 39 [ 3.624436] ata2: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3f e881000180 irq 39 [ 3.624452] ata3: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3f e881000200 irq 39 [ 3.624468] ata4: SATA max UDMA/133 abar m2048@0x3fe881000000 port 0x3f e881000280 irq 39 […] [ 3.731966] ata3: SATA link down (SStatus 0 SControl 300) [ 3.732069] ata4: SATA link down (SStatus 0 SControl 300) [ 3.897448] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300) [ 3.897678] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300) [ 3.898140] ata1.00: ATA-10: ST1000NX0313 00LY266 00LY265IBM, BE33, max UDMA/133 [ 3.898175] ata2.00: ATA-10: ST1000NX0313 00LY266 00LY265IBM, BE33, max UDMA/133 [ 3.898287] ata1.00: 1953525168 sectors, multi 0: LBA48 NCQ (depth 32), AA [ 3.898349] ata2.00: 1953525168 sectors, multi 0: LBA48 NCQ (depth 32), AA [ 3.900070] ata1.00: configured for UDMA/133 [ 3.900166] ata2.00: configured for UDMA/133 Signed-off-by: Paul Menzel Signed-off-by: Damien Le Moal --- drivers/ata/ahci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index ab5811ef5a53..edca4e8fd44e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -582,6 +582,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { .driver_data = board_ahci_yes_fbs }, { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230), .driver_data = board_ahci_yes_fbs }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9235), + .driver_data = board_ahci_no_debounce_delay }, { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642), /* highpoint rocketraid 642L */ .driver_data = board_ahci_yes_fbs }, { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0645), /* highpoint rocketraid 644L */ From ac1eb6655be440b6c0199f6bc9d20d610fc29d0d Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 2 Feb 2022 23:07:45 +0300 Subject: [PATCH 032/124] ata: libata: ata_{sff|std}_prereset() always return 0 ata_std_prereset() always returns 0, hence the check in ata_sff_prereset() is pointless and thus it also can return only 0 (however, we cannot change the prototypes of ata_{sff|std}_prereset() as they implement the driver's prereset() method). Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-core.c | 2 +- drivers/ata/libata-sff.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 67f88027680a..3ceda1fa243d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3568,7 +3568,7 @@ EXPORT_SYMBOL_GPL(ata_wait_after_reset); * Kernel thread context (may sleep) * * RETURNS: - * 0 on success, -errno otherwise. + * Always 0. */ int ata_std_prereset(struct ata_link *link, unsigned long deadline) { diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 75217828dfe3..c9dbfb3641fc 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1708,16 +1708,15 @@ EXPORT_SYMBOL_GPL(ata_sff_thaw); * Kernel thread context (may sleep) * * RETURNS: - * 0 on success, -errno otherwise. + * Always 0. */ int ata_sff_prereset(struct ata_link *link, unsigned long deadline) { struct ata_eh_context *ehc = &link->eh_context; int rc; - rc = ata_std_prereset(link, deadline); - if (rc) - return rc; + /* The standard prereset is best-effort and always returns 0 */ + ata_std_prereset(link, deadline); /* if we're about to do hardreset, nothing more to do */ if (ehc->i.action & ATA_EH_HARDRESET) From ec87cf3782f7b05ae15e061d36c763c35488f292 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 2 Feb 2022 23:58:21 +0300 Subject: [PATCH 033/124] ata: libata: make ata_host_suspend() *void* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ata_host_suspend() always returns 0, so the result checks in many drivers look pointless. Let's make this function return *void* instead of *int*. Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Signed-off-by: Sergey Shtylyov Acked-by: Uwe Kleine-König Reviewed-by: Hannes Reinecke Signed-off-by: Damien Le Moal --- drivers/ata/ahci.c | 3 ++- drivers/ata/ata_piix.c | 5 +---- drivers/ata/libahci_platform.c | 3 ++- drivers/ata/libata-core.c | 8 ++------ drivers/ata/pata_arasan_cf.c | 3 ++- drivers/ata/pata_cs5520.c | 5 +---- drivers/ata/pata_imx.c | 15 ++++++--------- drivers/ata/pata_macio.c | 6 +----- drivers/ata/pata_mpc52xx.c | 3 ++- drivers/ata/pata_samsung_cf.c | 3 ++- drivers/ata/pata_triflex.c | 5 +---- drivers/ata/sata_fsl.c | 4 +++- drivers/ata/sata_highbank.c | 3 ++- drivers/ata/sata_mv.c | 6 +++--- drivers/ata/sata_rcar.c | 18 ++++++++---------- include/linux/libata.h | 2 +- 16 files changed, 39 insertions(+), 53 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index edca4e8fd44e..51045fd05243 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -891,7 +891,8 @@ static int ahci_pci_device_suspend(struct device *dev) } ahci_pci_disable_interrupts(host); - return ata_host_suspend(host, PMSG_SUSPEND); + ata_host_suspend(host, PMSG_SUSPEND); + return 0; } static int ahci_pci_device_resume(struct device *dev) diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 27b0d903f91f..ade5e894563b 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -993,11 +993,8 @@ static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = pci_get_drvdata(pdev); unsigned long flags; - int rc = 0; - rc = ata_host_suspend(host, mesg); - if (rc) - return rc; + ata_host_suspend(host, mesg); /* Some braindamaged ACPI suspend implementations expect the * controller to be awake on entry; otherwise, it burns cpu diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 18296443ccba..65227ef6b846 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -733,7 +733,8 @@ int ahci_platform_suspend_host(struct device *dev) if (hpriv->flags & AHCI_HFLAG_SUSPEND_PHYS) ahci_platform_disable_phys(hpriv); - return ata_host_suspend(host, PMSG_SUSPEND); + ata_host_suspend(host, PMSG_SUSPEND); + return 0; } EXPORT_SYMBOL_GPL(ahci_platform_suspend_host); diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 3ceda1fa243d..0ddb49f2ece1 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -5170,10 +5170,9 @@ EXPORT_SYMBOL_GPL(ata_sas_port_resume); * * Suspend @host. Actual operation is performed by port suspend. */ -int ata_host_suspend(struct ata_host *host, pm_message_t mesg) +void ata_host_suspend(struct ata_host *host, pm_message_t mesg) { host->dev->power.power_state = mesg; - return 0; } EXPORT_SYMBOL_GPL(ata_host_suspend); @@ -6090,11 +6089,8 @@ EXPORT_SYMBOL_GPL(ata_pci_device_do_resume); int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = pci_get_drvdata(pdev); - int rc = 0; - rc = ata_host_suspend(host, mesg); - if (rc) - return rc; + ata_host_suspend(host, mesg); ata_pci_device_do_suspend(pdev, mesg); diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 24c3d5e1fca3..e89617ed9175 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -937,7 +937,8 @@ static int arasan_cf_suspend(struct device *dev) dmaengine_terminate_all(acdev->dma_chan); cf_exit(acdev); - return ata_host_suspend(host, PMSG_SUSPEND); + ata_host_suspend(host, PMSG_SUSPEND); + return 0; } static int arasan_cf_resume(struct device *dev) diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 24ce8665b1f9..f4289a532f87 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -259,11 +259,8 @@ static int cs5520_reinit_one(struct pci_dev *pdev) static int cs5520_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = pci_get_drvdata(pdev); - int rc = 0; - rc = ata_host_suspend(host, mesg); - if (rc) - return rc; + ata_host_suspend(host, mesg); pci_save_state(pdev); return 0; diff --git a/drivers/ata/pata_imx.c b/drivers/ata/pata_imx.c index 2e538726802b..150939275b1b 100644 --- a/drivers/ata/pata_imx.c +++ b/drivers/ata/pata_imx.c @@ -223,17 +223,14 @@ static int pata_imx_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); struct pata_imx_priv *priv = host->private_data; - int ret; - ret = ata_host_suspend(host, PMSG_SUSPEND); - if (!ret) { - __raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN); - priv->ata_ctl = - __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL); - clk_disable_unprepare(priv->clk); - } + ata_host_suspend(host, PMSG_SUSPEND); - return ret; + __raw_writel(0, priv->host_regs + PATA_IMX_ATA_INT_EN); + priv->ata_ctl = __raw_readl(priv->host_regs + PATA_IMX_ATA_CONTROL); + clk_disable_unprepare(priv->clk); + + return 0; } static int pata_imx_resume(struct device *dev) diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 16e8aa184a75..3c3509f18cdd 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -853,12 +853,8 @@ static int pata_macio_slave_config(struct scsi_device *sdev) #ifdef CONFIG_PM_SLEEP static int pata_macio_do_suspend(struct pata_macio_priv *priv, pm_message_t mesg) { - int rc; - /* First, core libata suspend to do most of the work */ - rc = ata_host_suspend(priv->host, mesg); - if (rc) - return rc; + ata_host_suspend(priv->host, mesg); /* Restore to default timings */ pata_macio_default_timings(priv); diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index f1d352d5f128..c1b138d24b05 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -824,7 +824,8 @@ mpc52xx_ata_suspend(struct platform_device *op, pm_message_t state) { struct ata_host *host = platform_get_drvdata(op); - return ata_host_suspend(host, state); + ata_host_suspend(host, state); + return 0; } static int diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 3da0e8e30286..377cd6bd87ac 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -608,7 +608,8 @@ static int pata_s3c_suspend(struct device *dev) { struct ata_host *host = dev_get_drvdata(dev); - return ata_host_suspend(host, PMSG_SUSPEND); + ata_host_suspend(host, PMSG_SUSPEND); + return 0; } static int pata_s3c_resume(struct device *dev) diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c index 8a033598e7e1..782162d2f3f8 100644 --- a/drivers/ata/pata_triflex.c +++ b/drivers/ata/pata_triflex.c @@ -198,11 +198,8 @@ static const struct pci_device_id triflex[] = { static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = pci_get_drvdata(pdev); - int rc = 0; - rc = ata_host_suspend(host, mesg); - if (rc) - return rc; + ata_host_suspend(host, mesg); /* * We must not disable or powerdown the device. diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index da0152116d9f..cfe93c420488 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1546,7 +1546,9 @@ static int sata_fsl_remove(struct platform_device *ofdev) static int sata_fsl_suspend(struct platform_device *op, pm_message_t state) { struct ata_host *host = platform_get_drvdata(op); - return ata_host_suspend(host, state); + + ata_host_suspend(host, state); + return 0; } static int sata_fsl_resume(struct platform_device *op) diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index b29d3f1d64b0..077bce76c445 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -587,7 +587,8 @@ static int ahci_highbank_suspend(struct device *dev) writel(ctl, mmio + HOST_CTL); readl(mmio + HOST_CTL); /* flush */ - return ata_host_suspend(host, PMSG_SUSPEND); + ata_host_suspend(host, PMSG_SUSPEND); + return 0; } static int ahci_highbank_resume(struct device *dev) diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 53446b997740..3b2a0d228306 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4235,10 +4235,10 @@ static int mv_platform_remove(struct platform_device *pdev) static int mv_platform_suspend(struct platform_device *pdev, pm_message_t state) { struct ata_host *host = platform_get_drvdata(pdev); + if (host) - return ata_host_suspend(host, state); - else - return 0; + ata_host_suspend(host, state); + return 0; } static int mv_platform_resume(struct platform_device *pdev) diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 3d96b6faa3f0..be8bfefed663 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -945,19 +945,17 @@ static int sata_rcar_suspend(struct device *dev) struct ata_host *host = dev_get_drvdata(dev); struct sata_rcar_priv *priv = host->private_data; void __iomem *base = priv->base; - int ret; - ret = ata_host_suspend(host, PMSG_SUSPEND); - if (!ret) { - /* disable interrupts */ - iowrite32(0, base + ATAPI_INT_ENABLE_REG); - /* mask */ - iowrite32(priv->sataint_mask, base + SATAINTMASK_REG); + ata_host_suspend(host, PMSG_SUSPEND); - pm_runtime_put(dev); - } + /* disable interrupts */ + iowrite32(0, base + ATAPI_INT_ENABLE_REG); + /* mask */ + iowrite32(priv->sataint_mask, base + SATAINTMASK_REG); - return ret; + pm_runtime_put(dev); + + return 0; } static int sata_rcar_resume(struct device *dev) diff --git a/include/linux/libata.h b/include/linux/libata.h index 605756f645be..a49e75c4206d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1080,7 +1080,7 @@ extern int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *dev, extern bool ata_link_online(struct ata_link *link); extern bool ata_link_offline(struct ata_link *link); #ifdef CONFIG_PM -extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); +extern void ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern void ata_host_resume(struct ata_host *host); extern void ata_sas_port_suspend(struct ata_port *ap); extern void ata_sas_port_resume(struct ata_port *ap); From a565ed1b9b1dc11cabed10e1c7c1b245c8db1aef Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 7 Feb 2022 17:26:13 +0300 Subject: [PATCH 034/124] pata_hpt3x2n: check channel enable bits The driver's prereset() method still doesn't check the channel enable bits. The bug was there for the entire time the driver has existed. :-/ Alan Cox fixed the HPT37x driver in commit b5bf24b94c65 ("[PATCH] hpt37x: Check the enablebits") but forgot to check the HPT3x2N driver which has the same bug. :-/ Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt3x2n.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 1d9d4eec5b8a..cbe57aba39bc 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.15" +#define DRV_VERSION "0.3.16" enum { HPT_PCI_FAST = (1 << 31), @@ -168,6 +168,13 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) { struct ata_port *ap = link->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); + static const struct pci_bits hpt3x2n_enable_bits[] = { + { 0x50, 1, 0x04, 0x04 }, + { 0x54, 1, 0x04, 0x04 } + }; + + if (!pci_test_config_bits(pdev, &hpt3x2n_enable_bits[ap->port_no])) + return -ENOENT; /* Reset the state machine */ pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); From 5dfb84982ed2e3a77d42f912625c275bc0e82f91 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 7 Feb 2022 23:32:20 +0300 Subject: [PATCH 035/124] pata_hpt3x2n: fix writing to wrong register in hpt3x2n_bmdma_stop() The driver's bmdma_stop() method writes to the wrong PCI config register (0x52 intead of 0x54) when trying to clear the state machine on secondary channel -- "luckily", the write falls on a read-only part of the primary channel MISC. control 3 register, so no collateral damage is done... Alan Cox fixed the HPT37x driver in commit 6929da4427b4 ("[PATCH] hpt37x: Two important bug fixes") but forgot to check the HPT3x2N driver which has the same bug. :-/ Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt3x2n.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index cbe57aba39bc..8772cbb29ee1 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.16" +#define DRV_VERSION "0.3.17" enum { HPT_PCI_FAST = (1 << 31), @@ -251,7 +251,7 @@ static void hpt3x2n_bmdma_stop(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; struct pci_dev *pdev = to_pci_dev(ap->host->dev); - int mscreg = 0x50 + 2 * ap->port_no; + int mscreg = 0x50 + 4 * ap->port_no; u8 bwsr_stat, msc_stat; pci_read_config_byte(pdev, 0x6A, &bwsr_stat); From 183a4bfbd7c86fcb194dc45fdec6e5759c6283a8 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 9 Feb 2022 23:25:34 +0300 Subject: [PATCH 036/124] ata: pata_artop: use *switch* in artop_init_one() This driver uses a string of the *if* statements in artop_init_one() where the *switch* statement would fit better. While fixing this, refactor the 6280 code to e.g. avoid a compound statement inside the *case* section... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_artop.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index ad3c5808aaad..08e88403d0ab 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -28,7 +28,7 @@ #include #define DRV_NAME "pata_artop" -#define DRV_VERSION "0.4.6" +#define DRV_VERSION "0.4.7" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -394,16 +394,19 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) if (rc) return rc; - if (id->driver_data == 0) /* 6210 variant */ + switch (id->driver_data) { + case 0: /* 6210 variant */ ppi[0] = &info_6210; - else if (id->driver_data == 1) /* 6260 */ + break; + case 1: /* 6260 */ ppi[0] = &info_626x; - else if (id->driver_data == 2) { /* 6280 or 6280 + fast */ - unsigned long io = pci_resource_start(pdev, 4); - - ppi[0] = &info_628x; - if (inb(io) & 0x10) + break; + case 2: /* 6280 or 6280 + fast */ + if (inb(pci_resource_start(pdev, 4)) & 0x10) ppi[0] = &info_628x_fast; + else + ppi[0] = &info_628x; + break; } BUG_ON(ppi[0] == NULL); From 7ad3128efe87bd2d5ed1c574109fcad5455c8155 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 9 Feb 2022 23:25:35 +0300 Subject: [PATCH 037/124] ata: pata_artop: use *switch* in atp8xx_fixup() This driver uses a string of the *if* statements in atp8xx_fixup() where a *switch* statement would fit better... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_artop.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index 08e88403d0ab..20a8f31a3f57 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -28,7 +28,7 @@ #include #define DRV_NAME "pata_artop" -#define DRV_VERSION "0.4.7" +#define DRV_VERSION "0.4.8" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -315,12 +315,15 @@ static struct ata_port_operations artop6260_ops = { static void atp8xx_fixup(struct pci_dev *pdev) { - if (pdev->device == 0x0005) + u8 reg; + + switch (pdev->device) { + case 0x0005: /* BIOS may have left us in UDMA, clear it before libata probe */ pci_write_config_byte(pdev, 0x54, 0); - else if (pdev->device == 0x0008 || pdev->device == 0x0009) { - u8 reg; - + break; + case 0x0008: + case 0x0009: /* Mac systems come up with some registers not set as we will need them */ @@ -338,6 +341,7 @@ static void atp8xx_fixup(struct pci_dev *pdev) /* Enable IRQ output and burst mode */ pci_read_config_byte(pdev, 0x4a, ®); pci_write_config_byte(pdev, 0x4a, (reg & ~0x01) | 0x80); + break; } } From 87a3f2a899a42d750d01266cf2e85012c4b1e049 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 9 Feb 2022 23:53:50 +0300 Subject: [PATCH 038/124] ata: pata_hpt3x2n: drop unused HPT_PCI_FAST The driver has never used HPT_PCI_FAST -- drop it. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt3x2n.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 8772cbb29ee1..22e80d12a49b 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -27,7 +27,6 @@ #define DRV_VERSION "0.3.17" enum { - HPT_PCI_FAST = (1 << 31), PCI66 = (1 << 1), USE_DPLL = (1 << 0) }; From 8d463523586127a1af01bcfc4fdb96ca43dc9138 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Wed, 9 Feb 2022 23:53:51 +0300 Subject: [PATCH 039/124] ata: pata_hpt3x2n: drop unused 'struct hpt_chip' The driver has never used 'struct hpt_chip' -- drop its declaration. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt3x2n.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index 22e80d12a49b..b36090808890 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -36,11 +36,6 @@ struct hpt_clock { u32 timing; }; -struct hpt_chip { - const char *name; - struct hpt_clock *clocks[3]; -}; - /* key for bus clock timings * bit * 0:3 data_high_time. Inactive time of DIOW_/DIOR_ for PIO and MW DMA. From 1336aa88d8553292604878c53538297fbc65bf0a Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 00:46:28 +0300 Subject: [PATCH 040/124] ata: libata-sff: make ata_devchk() return 'bool' ata_devchk() returns 1 if a device is present, 0 if not -- the 'bool' type clearly fits better here than 'unsigned int'... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-sff.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index c9dbfb3641fc..546b1f73ede5 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1751,10 +1751,13 @@ EXPORT_SYMBOL_GPL(ata_sff_prereset); * correctly storing and echoing back the * ATA shadow register contents. * + * RETURN: + * true if device is present, false if not. + * * LOCKING: * caller. */ -static unsigned int ata_devchk(struct ata_port *ap, unsigned int device) +static bool ata_devchk(struct ata_port *ap, unsigned int device) { struct ata_ioports *ioaddr = &ap->ioaddr; u8 nsect, lbal; @@ -1774,9 +1777,9 @@ static unsigned int ata_devchk(struct ata_port *ap, unsigned int device) lbal = ioread8(ioaddr->lbal_addr); if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ + return true; /* we found a device */ - return 0; /* nothing found */ + return false; /* nothing found */ } /** From bba077d801b1eed07b2ae9ee62a5b134cb1a6830 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 00:46:29 +0300 Subject: [PATCH 041/124] ata: pata_samsung_cf: make pata_s3c_devchk() return 'bool' pata_s3c_devchk() returns 1 if a device is present, 0 if not -- the 'bool' type clearly fits better here than 'unsigned int'... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_samsung_cf.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 377cd6bd87ac..bdd2178c4a61 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -308,8 +308,7 @@ static void pata_s3c_dev_select(struct ata_port *ap, unsigned int device) /* * pata_s3c_devchk - PATA device presence detection */ -static unsigned int pata_s3c_devchk(struct ata_port *ap, - unsigned int device) +static bool pata_s3c_devchk(struct ata_port *ap, unsigned int device) { struct ata_ioports *ioaddr = &ap->ioaddr; u8 nsect, lbal; @@ -329,9 +328,9 @@ static unsigned int pata_s3c_devchk(struct ata_port *ap, lbal = ata_inb(ap->host, ioaddr->lbal_addr); if ((nsect == 0x55) && (lbal == 0xaa)) - return 1; /* we found a device */ + return true; /* we found a device */ - return 0; /* nothing found */ + return false; /* nothing found */ } /* From 88e6b81878fb3fce93a26879164a2b7f5cbc848a Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 00:46:30 +0300 Subject: [PATCH 042/124] ata: sata_rcar: make sata_rcar_ata_devchk() return 'bool' sata_rcar_ata_devchk() returns 1 if a device is present, 0 if not -- the 'bool' type clearly fits better here than 'unsigned int'... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/sata_rcar.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index be8bfefed663..20263c1113df 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -283,8 +283,7 @@ static void sata_rcar_dev_select(struct ata_port *ap, unsigned int device) ata_sff_pause(ap); /* needed; also flushes, for mmio */ } -static unsigned int sata_rcar_ata_devchk(struct ata_port *ap, - unsigned int device) +static bool sata_rcar_ata_devchk(struct ata_port *ap, unsigned int device) { struct ata_ioports *ioaddr = &ap->ioaddr; u8 nsect, lbal; @@ -304,9 +303,9 @@ static unsigned int sata_rcar_ata_devchk(struct ata_port *ap, lbal = ioread32(ioaddr->lbal_addr); if (nsect == 0x55 && lbal == 0xaa) - return 1; /* found a device */ + return true; /* found a device */ - return 0; /* nothing found */ + return false; /* nothing found */ } static int sata_rcar_wait_after_reset(struct ata_link *link, From f79ca4550c3cb985313f69fcd4e82770d18fc8fe Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 12:56:31 +0300 Subject: [PATCH 043/124] ata: pata_hpt366: check channel enable bits HighPoint HPT36x chips did turn out to have the channel enable bits -- however, badly implemented. Make use of them, despite that is probably only going to burden the driver's code -- assuming both channels are always enabled by the HighPoint BIOS anyway... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt366.c | 42 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 778c893f276b..96caa79dc8d7 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -23,7 +23,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.11" +#define DRV_VERSION "0.6.12" struct hpt_clock { u8 xfer_mode; @@ -278,6 +278,35 @@ static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev) hpt366_set_mode(ap, adev, adev->dma_mode); } +/** + * hpt366_prereset - reset the hpt36x bus + * @link: ATA link to reset + * @deadline: deadline jiffies for the operation + * + * Perform the initial reset handling for the 36x series controllers. + * Reset the hardware and state machine, + */ + +static int hpt366_prereset(struct ata_link *link, unsigned long deadline) +{ + struct ata_port *ap = link->ap; + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + /* + * HPT36x chips have one channel per function and have + * both channel enable bits located differently and visible + * to both functions -- really stupid design decision... :-( + * Bit 4 is for the primary channel, bit 5 for the secondary. + */ + static const struct pci_bits hpt366_enable_bits = { + 0x50, 1, 0x30, 0x30 + }; + + if (!pci_test_config_bits(pdev, &hpt366_enable_bits)) + return -ENOENT; + + return ata_sff_prereset(link, deadline); +} + static struct scsi_host_template hpt36x_sht = { ATA_BMDMA_SHT(DRV_NAME), }; @@ -288,6 +317,7 @@ static struct scsi_host_template hpt36x_sht = { static struct ata_port_operations hpt366_port_ops = { .inherits = &ata_bmdma_port_ops, + .prereset = hpt366_prereset, .cable_detect = hpt36x_cable_detect, .mode_filter = hpt366_filter, .set_piomode = hpt366_set_piomode, @@ -304,7 +334,7 @@ static struct ata_port_operations hpt366_port_ops = { static void hpt36x_init_chipset(struct pci_dev *dev) { - u8 drive_fast; + u8 drive_fast, mcr1; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); @@ -314,6 +344,14 @@ static void hpt36x_init_chipset(struct pci_dev *dev) pci_read_config_byte(dev, 0x51, &drive_fast); if (drive_fast & 0x80) pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); + + /* + * Now we'll have to force both channels enabled if at least one + * of them has been enabled by BIOS... + */ + pci_read_config_byte(dev, 0x50, &mcr1); + if (mcr1 & 0x30) + pci_write_config_byte(dev, 0x50, mcr1 | 0x30); } /** From 334bfa1f06649774b3df5b343688f6070b8d6485 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 13:32:42 +0300 Subject: [PATCH 044/124] ata: sata_rcar: drop unused #define's This driver has never used the SH-Navi2G/ATAPI-ATA compatible taskfile registers (the driver uses the taskfile registers in another location anyway), so drop their #define's... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/sata_rcar.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 20263c1113df..bde76a87beeb 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -18,10 +18,6 @@ #define DRV_NAME "sata_rcar" -/* SH-Navi2G/ATAPI-ATA compatible task registers */ -#define DATA_REG 0x100 -#define SDEVCON_REG 0x138 - /* SH-Navi2G/ATAPI module compatible control registers */ #define ATAPI_CONTROL1_REG 0x180 #define ATAPI_STATUS_REG 0x184 From cf369e4e5245c583d611729e563c3b81e61d8496 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 10 Feb 2022 21:42:19 +0100 Subject: [PATCH 045/124] ata: pata_mpc52xx: use GFP_KERNEL Platform_driver probe functions aren't called with locks held and thus don't need GFP_ATOMIC. Use GFP_KERNEL instead. Problem found with Coccinelle. Signed-off-by: Julia Lawall Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_mpc52xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index c1b138d24b05..a2a3a95c71ed 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -736,7 +736,7 @@ static int mpc52xx_ata_probe(struct platform_device *op) } /* Prepare our private structure */ - priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_ATOMIC); + priv = devm_kzalloc(&op->dev, sizeof(*priv), GFP_KERNEL); if (!priv) { rv = -ENOMEM; goto err1; From a58ff050b428e38461d201b24d388899111ffedf Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 22:22:12 +0300 Subject: [PATCH 046/124] ata: pata_hpt366: disable fast interrupts in prereset() method The PIO/DMA mode setting function is hardly a good place for disabling the fast interrupts on a channel -- let's move that code to the driver's prereset() method instead. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt366.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c index 96caa79dc8d7..c99e8f0708b3 100644 --- a/drivers/ata/pata_hpt366.c +++ b/drivers/ata/pata_hpt366.c @@ -23,7 +23,7 @@ #include #define DRV_NAME "pata_hpt366" -#define DRV_VERSION "0.6.12" +#define DRV_VERSION "0.6.13" struct hpt_clock { u8 xfer_mode; @@ -300,10 +300,15 @@ static int hpt366_prereset(struct ata_link *link, unsigned long deadline) static const struct pci_bits hpt366_enable_bits = { 0x50, 1, 0x30, 0x30 }; + u8 mcr2; if (!pci_test_config_bits(pdev, &hpt366_enable_bits)) return -ENOENT; + pci_read_config_byte(pdev, 0x51, &mcr2); + if (mcr2 & 0x80) + pci_write_config_byte(pdev, 0x51, mcr2 & ~0x80); + return ata_sff_prereset(link, deadline); } @@ -334,17 +339,13 @@ static struct ata_port_operations hpt366_port_ops = { static void hpt36x_init_chipset(struct pci_dev *dev) { - u8 drive_fast, mcr1; + u8 mcr1; pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78); pci_write_config_byte(dev, PCI_MIN_GNT, 0x08); pci_write_config_byte(dev, PCI_MAX_LAT, 0x08); - pci_read_config_byte(dev, 0x51, &drive_fast); - if (drive_fast & 0x80) - pci_write_config_byte(dev, 0x51, drive_fast & ~0x80); - /* * Now we'll have to force both channels enabled if at least one * of them has been enabled by BIOS... From 6110530b580074a47ac732c451c65e900fe6ca19 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 22:22:13 +0300 Subject: [PATCH 047/124] ata: pata_hpt37x: disable fast interrupts in prereset() method The PIO/DMA mode setting functions are hardly a good place for disabling the fast interrupts on a channel -- let's move that code to the driver's prereset() method instead. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt37x.c | 48 ++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 7abc7e04f656..cb0fcee02de3 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -23,7 +23,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.23" +#define DRV_VERSION "0.6.24" struct hpt_clock { u8 xfer_speed; @@ -394,6 +394,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) { 0x50, 1, 0x04, 0x04 }, { 0x54, 1, 0x04, 0x04 } }; + u8 mcr2; if (!pci_test_config_bits(pdev, &hpt37x_enable_bits[ap->port_no])) return -ENOENT; @@ -402,6 +403,20 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); + /* + * Disable the "fast interrupt" prediction. Don't hold off + * on interrupts. (== 0x01 despite what the docs say) + */ + pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2); + /* Is it HPT370/A? */ + if (pdev->device == PCI_DEVICE_ID_TTI_HPT366 && pdev->revision < 5) { + mcr2 &= ~0x02; + mcr2 |= 0x01; + } else { + mcr2 &= ~0x07; + } + pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2); + return ata_sff_prereset(link, deadline); } @@ -409,18 +424,8 @@ static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; + int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no); u32 reg, timing, mask; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x02; - fast |= 0x01; - pci_write_config_byte(pdev, addr2, fast); /* Determine timing mask and find matching mode entry */ if (mode < XFER_MW_DMA_0) @@ -432,9 +437,9 @@ static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev, timing = hpt37x_find_mode(ap, mode); - pci_read_config_dword(pdev, addr1, ®); + pci_read_config_dword(pdev, addr, ®); reg = (reg & ~mask) | (timing & mask); - pci_write_config_dword(pdev, addr1, reg); + pci_write_config_dword(pdev, addr, reg); } /** * hpt370_set_piomode - PIO setup @@ -503,17 +508,8 @@ static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; + int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no); u32 reg, timing, mask; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x07; - pci_write_config_byte(pdev, addr2, fast); /* Determine timing mask and find matching mode entry */ if (mode < XFER_MW_DMA_0) @@ -525,9 +521,9 @@ static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev, timing = hpt37x_find_mode(ap, mode); - pci_read_config_dword(pdev, addr1, ®); + pci_read_config_dword(pdev, addr, ®); reg = (reg & ~mask) | (timing & mask); - pci_write_config_dword(pdev, addr1, reg); + pci_write_config_dword(pdev, addr, reg); } /** From 25d83f9d23d8ff61ba7e2815a2ffc7c974003bdd Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 10 Feb 2022 22:22:14 +0300 Subject: [PATCH 048/124] ata: pata_hpt3x2n: disable fast interrupts in prereset() method The PIO/DMA mode setting function is hardly a good place for disabling the fast interrupts on a channel -- let's move that code to the driver's prereset() method instead. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt3x2n.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index b36090808890..1f6afd8ee29b 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.17" +#define DRV_VERSION "0.3.18" enum { PCI66 = (1 << 1), @@ -166,6 +166,7 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) { 0x50, 1, 0x04, 0x04 }, { 0x54, 1, 0x04, 0x04 } }; + u8 mcr2; if (!pci_test_config_bits(pdev, &hpt3x2n_enable_bits[ap->port_no])) return -ENOENT; @@ -174,6 +175,11 @@ static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline) pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37); udelay(100); + /* Fast interrupt prediction disable, hold off interrupt disable */ + pci_read_config_byte(pdev, 0x51 + 4 * ap->port_no, &mcr2); + mcr2 &= ~0x07; + pci_write_config_byte(pdev, 0x51 + 4 * ap->port_no, mcr2); + return ata_sff_prereset(link, deadline); } @@ -181,17 +187,8 @@ static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); - u32 addr1, addr2; + int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no); u32 reg, timing, mask; - u8 fast; - - addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - addr2 = 0x51 + 4 * ap->port_no; - - /* Fast interrupt prediction disable, hold off interrupt disable */ - pci_read_config_byte(pdev, addr2, &fast); - fast &= ~0x07; - pci_write_config_byte(pdev, addr2, fast); /* Determine timing mask and find matching mode entry */ if (mode < XFER_MW_DMA_0) @@ -203,9 +200,9 @@ static void hpt3x2n_set_mode(struct ata_port *ap, struct ata_device *adev, timing = hpt3x2n_find_mode(ap, mode); - pci_read_config_dword(pdev, addr1, ®); + pci_read_config_dword(pdev, addr, ®); reg = (reg & ~mask) | (timing & mask); - pci_write_config_dword(pdev, addr1, reg); + pci_write_config_dword(pdev, addr, reg); } /** From b51aa532e105722d0dfb21718f0b32780c9e8e8d Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sun, 13 Feb 2022 14:50:00 +0300 Subject: [PATCH 049/124] ata: libata-sff: make ata_resources_present() return 'bool' ata_resources_present() returns 1 if the primary/secondary channel's PCI resources are present, 0 if not -- the 'bool' type fits somewhat better here than 'int'... Use the *= operator, while at it... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-sff.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 546b1f73ede5..f5e4cd046055 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -2174,18 +2174,18 @@ EXPORT_SYMBOL_GPL(ata_sff_std_ports); #ifdef CONFIG_PCI -static int ata_resources_present(struct pci_dev *pdev, int port) +static bool ata_resources_present(struct pci_dev *pdev, int port) { int i; /* Check the PCI resources for this channel are enabled */ - port = port * 2; + port *= 2; for (i = 0; i < 2; i++) { if (pci_resource_start(pdev, port + i) == 0 || pci_resource_len(pdev, port + i) == 0) - return 0; + return false; } - return 1; + return true; } /** From 4fc5f0aa9712418dcb12c446a904a359e5568659 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sun, 13 Feb 2022 18:10:31 +0300 Subject: [PATCH 050/124] ata: libata-sff: refactor ata_sff_set_devctl() Commit 41dec29bcb05 ("libata: introduce sff_set_devctl() method") left some clumsy checks surrounding calls to ata_sff_set_devctl() which Jeff Garzik suggested to factor out... and I never followed up. :-( At last, refactor ata_sff_set_devctl() to include the repetitive checks and return a 'bool' result indicating if the device control register exists or not. While at it, further update the 'kernel-doc' comment -- the device control register has never been a part of the taskfile, despite what Jeff and co. think! :-) Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-sff.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index f5e4cd046055..aefe8af5cdac 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -265,20 +265,26 @@ EXPORT_SYMBOL_GPL(ata_sff_wait_ready); * @ap: port where the device is * @ctl: value to write * - * Writes ATA taskfile device control register. + * Writes ATA device control register. * - * Note: may NOT be used as the sff_set_devctl() entry in - * ata_port_operations. + * RETURN: + * true if the register exists, false if not. * * LOCKING: * Inherited from caller. */ -static void ata_sff_set_devctl(struct ata_port *ap, u8 ctl) +static bool ata_sff_set_devctl(struct ata_port *ap, u8 ctl) { - if (ap->ops->sff_set_devctl) + if (ap->ops->sff_set_devctl) { ap->ops->sff_set_devctl(ap, ctl); - else + return true; + } + if (ap->ioaddr.ctl_addr) { iowrite8(ctl, ap->ioaddr.ctl_addr); + return true; + } + + return false; } /** @@ -357,8 +363,6 @@ static void ata_dev_select(struct ata_port *ap, unsigned int device, */ void ata_sff_irq_on(struct ata_port *ap) { - struct ata_ioports *ioaddr = &ap->ioaddr; - if (ap->ops->sff_irq_on) { ap->ops->sff_irq_on(ap); return; @@ -367,8 +371,7 @@ void ata_sff_irq_on(struct ata_port *ap) ap->ctl &= ~ATA_NIEN; ap->last_ctl = ap->ctl; - if (ap->ops->sff_set_devctl || ioaddr->ctl_addr) - ata_sff_set_devctl(ap, ap->ctl); + ata_sff_set_devctl(ap, ap->ctl); ata_wait_idle(ap); if (ap->ops->sff_irq_clear) @@ -1662,8 +1665,7 @@ void ata_sff_freeze(struct ata_port *ap) ap->ctl |= ATA_NIEN; ap->last_ctl = ap->ctl; - if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) - ata_sff_set_devctl(ap, ap->ctl); + ata_sff_set_devctl(ap, ap->ctl); /* Under certain circumstances, some controllers raise IRQ on * ATA_NIEN manipulation. Also, many controllers fail to mask @@ -2061,10 +2063,8 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes) return; /* set up device control */ - if (ap->ops->sff_set_devctl || ap->ioaddr.ctl_addr) { - ata_sff_set_devctl(ap, ap->ctl); + if (ata_sff_set_devctl(ap, ap->ctl)) ap->last_ctl = ap->ctl; - } } EXPORT_SYMBOL_GPL(ata_sff_postreset); From 03c0e84f9c1e166d57d06b04497e11205f48e9a8 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Sun, 13 Feb 2022 18:10:32 +0300 Subject: [PATCH 051/124] ata: libata-sff: refactor ata_sff_altstatus() The driver's calls to ata_sff_altstatus() are mostly surrounded by some clumsy checks. Refactor ata_sff_altstatus() to include the repetitive checks and return a 'bool' result indicating if the alternate status register exists or not. While at it, further update the 'kernel-doc' comment -- the alternate status register has never been a part of the taskfile, despite what Jeff and co. think! :-) In ata_sff_lost_interrupt(), wrap the ata_sff_altstatus() call in a WARN_ON_ONCE() check to issue a warning if the device control register does not exist. And while at it, fix the strange argument indentation in the ata_port_warn() call following the call to ata_sff_altstatus(). Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-sff.c | 59 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index aefe8af5cdac..2fb3956f66f6 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -70,22 +70,35 @@ EXPORT_SYMBOL_GPL(ata_sff_check_status); /** * ata_sff_altstatus - Read device alternate status reg * @ap: port where the device is + * @status: pointer to a status value * - * Reads ATA taskfile alternate status register for - * currently-selected device and return its value. + * Reads ATA alternate status register for currently-selected device + * and return its value. * - * Note: may NOT be used as the check_altstatus() entry in - * ata_port_operations. + * RETURN: + * true if the register exists, false if not. * * LOCKING: * Inherited from caller. */ -static u8 ata_sff_altstatus(struct ata_port *ap) +static bool ata_sff_altstatus(struct ata_port *ap, u8 *status) { - if (ap->ops->sff_check_altstatus) - return ap->ops->sff_check_altstatus(ap); + u8 tmp; - return ioread8(ap->ioaddr.altstatus_addr); + if (ap->ops->sff_check_altstatus) { + tmp = ap->ops->sff_check_altstatus(ap); + goto read; + } + if (ap->ioaddr.altstatus_addr) { + tmp = ioread8(ap->ioaddr.altstatus_addr); + goto read; + } + return false; + +read: + if (status) + *status = tmp; + return true; } /** @@ -104,12 +117,9 @@ static u8 ata_sff_irq_status(struct ata_port *ap) { u8 status; - if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { - status = ata_sff_altstatus(ap); - /* Not us: We are busy */ - if (status & ATA_BUSY) - return status; - } + /* Not us: We are busy */ + if (ata_sff_altstatus(ap, &status) && (status & ATA_BUSY)) + return status; /* Clear INTRQ latch */ status = ap->ops->sff_check_status(ap); return status; @@ -129,10 +139,7 @@ static u8 ata_sff_irq_status(struct ata_port *ap) static void ata_sff_sync(struct ata_port *ap) { - if (ap->ops->sff_check_altstatus) - ap->ops->sff_check_altstatus(ap); - else if (ap->ioaddr.altstatus_addr) - ioread8(ap->ioaddr.altstatus_addr); + ata_sff_altstatus(ap, NULL); } /** @@ -164,12 +171,12 @@ EXPORT_SYMBOL_GPL(ata_sff_pause); void ata_sff_dma_pause(struct ata_port *ap) { - if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { - /* An altstatus read will cause the needed delay without - messing up the IRQ status */ - ata_sff_altstatus(ap); + /* + * An altstatus read will cause the needed delay without + * messing up the IRQ status + */ + if (ata_sff_altstatus(ap, NULL)) return; - } /* There are no DMA controllers without ctl. BUG here to ensure we never violate the HDMA1:0 transition timing and risk corruption. */ @@ -1637,14 +1644,14 @@ void ata_sff_lost_interrupt(struct ata_port *ap) return; /* See if the controller thinks it is still busy - if so the command isn't a lost IRQ but is still in progress */ - status = ata_sff_altstatus(ap); + if (WARN_ON_ONCE(!ata_sff_altstatus(ap, &status))) + return; if (status & ATA_BUSY) return; /* There was a command running, we are no longer busy and we have no interrupt. */ - ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", - status); + ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status); /* Run the host interrupt logic as if the interrupt had not been lost */ ata_sff_port_intr(ap, qc); From 59b0040475ee5d562f061eef718b808fbec8a13a Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Mon, 14 Feb 2022 23:14:54 +0300 Subject: [PATCH 052/124] ata: libata-scsi: use *switch* statements to check SCSI command codes Replace strings of the *if* statements checking the SCSI command code with the *switch* statements that fit better here... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-scsi.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index eb40c3796a3f..1b6f1a0ecebf 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1362,19 +1362,22 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf->protocol = ATA_PROT_NODATA; - if (cdb[0] == VERIFY) { + switch (cdb[0]) { + case VERIFY: if (scmd->cmd_len < 10) { fp = 9; goto invalid_fld; } scsi_10_lba_len(cdb, &block, &n_block); - } else if (cdb[0] == VERIFY_16) { + break; + case VERIFY_16: if (scmd->cmd_len < 16) { fp = 15; goto invalid_fld; } scsi_16_lba_len(cdb, &block, &n_block); - } else { + break; + default: fp = 0; goto invalid_fld; } @@ -1506,8 +1509,13 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) int rc; u16 fp = 0; - if (cdb[0] == WRITE_10 || cdb[0] == WRITE_6 || cdb[0] == WRITE_16) + switch (cdb[0]) { + case WRITE_6: + case WRITE_10: + case WRITE_16: tf_flags |= ATA_TFLAG_WRITE; + break; + } /* Calculate the SCSI LBA, transfer length and FUA. */ switch (cdb[0]) { @@ -2817,7 +2825,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) * 12 and 16 byte CDBs use different offsets to * provide the various register values. */ - if (cdb[0] == ATA_16) { + switch (cdb[0]) { + case ATA_16: /* * 16-byte CDB - may contain extended commands. * @@ -2843,7 +2852,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->lbah = cdb[12]; tf->device = cdb[13]; tf->command = cdb[14]; - } else if (cdb[0] == ATA_12) { + break; + case ATA_12: /* * 12-byte CDB - incapable of extended commands. */ @@ -2856,7 +2866,8 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->lbah = cdb[7]; tf->device = cdb[8]; tf->command = cdb[9]; - } else { + break; + default: /* * 32-byte CDB - may contain extended command fields. * @@ -2880,6 +2891,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) tf->device = cdb[24]; tf->command = cdb[25]; tf->auxiliary = get_unaligned_be32(&cdb[28]); + break; } /* For NCQ commands copy the tag value */ From f7220eac752f2c96a1b6e0830cbf427ca908e511 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Wed, 16 Feb 2022 16:14:35 +0900 Subject: [PATCH 053/124] ata: Kconfig: fix sata gemini compile test condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When compile testing the sata gemini driver, CONFIG_OF is required to avoid the warning: drivers/ata/sata_gemini.c:421:34: error: ‘gemini_sata_of_match’ defined but not used [-Werror=unused-const-variable=] Signed-off-by: Damien Le Moal --- drivers/ata/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index cb54631fd950..f2d436df9da3 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -283,7 +283,7 @@ config SATA_FSL config SATA_GEMINI tristate "Gemini SATA bridge support" - depends on ARCH_GEMINI || COMPILE_TEST + depends on ARCH_GEMINI || (OF && COMPILE_TEST) select SATA_HOST default ARCH_GEMINI help From efcef265fd83d9a68a68926abecb3e1dd3e260a8 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Tue, 15 Feb 2022 21:49:26 +0300 Subject: [PATCH 054/124] ata: add/use ata_taskfile::{error|status} fields Add the explicit error and status register fields to 'struct ata_taskfile' using the anonymous *union*s ('struct ide_taskfile' had that for ages!) and update the libata taskfile code accordingly. There should be no object code changes resulting from that... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/acard-ahci.c | 2 +- drivers/ata/ahci.c | 4 ++-- drivers/ata/ahci_qoriq.c | 2 +- drivers/ata/ahci_xgene.c | 2 +- drivers/ata/libahci.c | 4 ++-- drivers/ata/libata-acpi.c | 8 +++---- drivers/ata/libata-core.c | 12 +++++----- drivers/ata/libata-eh.c | 42 +++++++++++++++++------------------ drivers/ata/libata-sata.c | 10 ++++----- drivers/ata/libata-scsi.c | 22 +++++++++--------- drivers/ata/libata-sff.c | 6 ++--- drivers/ata/pata_ep93xx.c | 4 ++-- drivers/ata/pata_ns87415.c | 4 ++-- drivers/ata/pata_octeon_cf.c | 4 ++-- drivers/ata/pata_samsung_cf.c | 2 +- drivers/ata/sata_highbank.c | 2 +- drivers/ata/sata_inic162x.c | 10 ++++----- drivers/ata/sata_rcar.c | 4 ++-- drivers/ata/sata_svw.c | 10 ++++----- drivers/ata/sata_vsc.c | 10 ++++----- include/linux/libata.h | 10 +++++++-- 21 files changed, 90 insertions(+), 84 deletions(-) diff --git a/drivers/ata/acard-ahci.c b/drivers/ata/acard-ahci.c index 536d4cb8f08b..7654a40c12b4 100644 --- a/drivers/ata/acard-ahci.c +++ b/drivers/ata/acard-ahci.c @@ -265,7 +265,7 @@ static bool acard_ahci_qc_fill_rtf(struct ata_queued_cmd *qc) if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE && !(qc->flags & ATA_QCFLAG_FAILED)) { ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); - qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15]; + qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15]; } else ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf); diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 51045fd05243..bb14683a8d4b 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -739,7 +739,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; + tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context), @@ -808,7 +808,7 @@ static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; + tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, timing, deadline, &online, diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index bf5b388bd4e0..cca78e25b173 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -123,7 +123,7 @@ static int ahci_qoriq_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; + tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, timing, deadline, &online, diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index 8e206379d699..c5b392e07e65 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -365,7 +365,7 @@ static int xgene_ahci_do_hardreset(struct ata_link *link, do { /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; + tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, timing, deadline, online, ahci_check_ready); diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 0ed484e04fd6..cf8c7fd59ada 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1561,7 +1561,7 @@ int ahci_do_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; + tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); rc = sata_link_hardreset(link, timing, deadline, online, @@ -2033,7 +2033,7 @@ static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc) if (qc->tf.protocol == ATA_PROT_PIO && qc->dma_dir == DMA_FROM_DEVICE && !(qc->flags & ATA_QCFLAG_FAILED)) { ata_tf_from_fis(rx_fis + RX_FIS_PIO_SETUP, &qc->result_tf); - qc->result_tf.command = (rx_fis + RX_FIS_PIO_SETUP)[15]; + qc->result_tf.status = (rx_fis + RX_FIS_PIO_SETUP)[15]; } else ata_tf_from_fis(rx_fis + RX_FIS_D2H_REG, &qc->result_tf); diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index b788f5a4565c..3d345d173556 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -546,13 +546,13 @@ static void ata_acpi_gtf_to_tf(struct ata_device *dev, tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; tf->protocol = ATA_PROT_NODATA; - tf->feature = gtf->tf[0]; /* 0x1f1 */ + tf->error = gtf->tf[0]; /* 0x1f1 */ tf->nsect = gtf->tf[1]; /* 0x1f2 */ tf->lbal = gtf->tf[2]; /* 0x1f3 */ tf->lbam = gtf->tf[3]; /* 0x1f4 */ tf->lbah = gtf->tf[4]; /* 0x1f5 */ tf->device = gtf->tf[5]; /* 0x1f6 */ - tf->command = gtf->tf[6]; /* 0x1f7 */ + tf->status = gtf->tf[6]; /* 0x1f7 */ } static int ata_acpi_filter_tf(struct ata_device *dev, @@ -679,7 +679,7 @@ static int ata_acpi_run_tf(struct ata_device *dev, "(%s) rejected by device (Stat=0x%02x Err=0x%02x)", tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, tf.lbah, tf.device, descr, - rtf.command, rtf.feature); + rtf.status, rtf.error); rc = 0; break; @@ -689,7 +689,7 @@ static int ata_acpi_run_tf(struct ata_device *dev, "(%s) failed (Emask=0x%x Stat=0x%02x Err=0x%02x)", tf.command, tf.feature, tf.nsect, tf.lbal, tf.lbam, tf.lbah, tf.device, descr, - err_mask, rtf.command, rtf.feature); + err_mask, rtf.status, rtf.error); rc = -EIO; break; } diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 0ddb49f2ece1..15172415b87e 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1171,7 +1171,7 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors) ata_dev_warn(dev, "failed to read native max address (err_mask=0x%x)\n", err_mask); - if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED)) + if (err_mask == AC_ERR_DEV && (tf.error & ATA_ABORTED)) return -EACCES; return -EIO; } @@ -1235,7 +1235,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors) "failed to set max address (err_mask=0x%x)\n", err_mask); if (err_mask == AC_ERR_DEV && - (tf.feature & (ATA_ABORTED | ATA_IDNF))) + (tf.error & (ATA_ABORTED | ATA_IDNF))) return -EACCES; return -EIO; } @@ -1584,7 +1584,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, /* perform minimal error analysis */ if (qc->flags & ATA_QCFLAG_FAILED) { - if (qc->result_tf.command & (ATA_ERR | ATA_DF)) + if (qc->result_tf.status & (ATA_ERR | ATA_DF)) qc->err_mask |= AC_ERR_DEV; if (!qc->err_mask) @@ -1593,7 +1593,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, if (qc->err_mask & ~AC_ERR_OTHER) qc->err_mask &= ~AC_ERR_OTHER; } else if (qc->tf.command == ATA_CMD_REQ_SENSE_DATA) { - qc->result_tf.command |= ATA_SENSE; + qc->result_tf.status |= ATA_SENSE; } /* finish up */ @@ -1813,7 +1813,7 @@ retry: return 0; } - if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) { + if ((err_mask == AC_ERR_DEV) && (tf.error & ATA_ABORTED)) { /* Device or controller might have reported * the wrong device class. Give a shot at the * other IDENTIFY if the current one is @@ -4375,7 +4375,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev, /* A clean abort indicates an original or just out of spec drive and we should continue as we issue the setup based on the drive reported working geometry */ - if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED)) + if (err_mask == AC_ERR_DEV && (tf.error & ATA_ABORTED)) err_mask = 0; return err_mask; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index e31341c9ac61..3307ed45fe4d 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -1386,7 +1386,7 @@ unsigned int atapi_eh_tur(struct ata_device *dev, u8 *r_sense_key) err_mask = ata_exec_internal(dev, &tf, cdb, DMA_NONE, NULL, 0, 0); if (err_mask == AC_ERR_DEV) - *r_sense_key = tf.feature >> 4; + *r_sense_key = tf.error >> 4; return err_mask; } @@ -1429,12 +1429,12 @@ static void ata_eh_request_sense(struct ata_queued_cmd *qc, err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); /* Ignore err_mask; ATA_ERR might be set */ - if (tf.command & ATA_SENSE) { + if (tf.status & ATA_SENSE) { ata_scsi_set_sense(dev, cmd, tf.lbah, tf.lbam, tf.lbal); qc->flags |= ATA_QCFLAG_SENSE_VALID; } else { ata_dev_warn(dev, "request sense failed stat %02x emask %x\n", - tf.command, err_mask); + tf.status, err_mask); } } @@ -1557,7 +1557,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, const struct ata_taskfile *tf) { unsigned int tmp, action = 0; - u8 stat = tf->command, err = tf->feature; + u8 stat = tf->status, err = tf->error; if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) { qc->err_mask |= AC_ERR_HSM; @@ -1594,7 +1594,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc, if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) { tmp = atapi_eh_request_sense(qc->dev, qc->scsicmd->sense_buffer, - qc->result_tf.feature >> 4); + qc->result_tf.error >> 4); if (!tmp) qc->flags |= ATA_QCFLAG_SENSE_VALID; else @@ -2360,7 +2360,7 @@ static void ata_eh_link_report(struct ata_link *link) cmd->hob_feature, cmd->hob_nsect, cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah, cmd->device, qc->tag, data_buf, cdb_buf, - res->command, res->feature, res->nsect, + res->status, res->error, res->nsect, res->lbal, res->lbam, res->lbah, res->hob_feature, res->hob_nsect, res->hob_lbal, res->hob_lbam, res->hob_lbah, @@ -2368,28 +2368,28 @@ static void ata_eh_link_report(struct ata_link *link) qc->err_mask & AC_ERR_NCQ ? " " : ""); #ifdef CONFIG_ATA_VERBOSE_ERROR - if (res->command & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | - ATA_SENSE | ATA_ERR)) { - if (res->command & ATA_BUSY) + if (res->status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | + ATA_SENSE | ATA_ERR)) { + if (res->status & ATA_BUSY) ata_dev_err(qc->dev, "status: { Busy }\n"); else ata_dev_err(qc->dev, "status: { %s%s%s%s%s}\n", - res->command & ATA_DRDY ? "DRDY " : "", - res->command & ATA_DF ? "DF " : "", - res->command & ATA_DRQ ? "DRQ " : "", - res->command & ATA_SENSE ? "SENSE " : "", - res->command & ATA_ERR ? "ERR " : ""); + res->status & ATA_DRDY ? "DRDY " : "", + res->status & ATA_DF ? "DF " : "", + res->status & ATA_DRQ ? "DRQ " : "", + res->status & ATA_SENSE ? "SENSE " : "", + res->status & ATA_ERR ? "ERR " : ""); } if (cmd->command != ATA_CMD_PACKET && - (res->feature & (ATA_ICRC | ATA_UNC | ATA_AMNF | - ATA_IDNF | ATA_ABORTED))) + (res->error & (ATA_ICRC | ATA_UNC | ATA_AMNF | ATA_IDNF | + ATA_ABORTED))) ata_dev_err(qc->dev, "error: { %s%s%s%s%s}\n", - res->feature & ATA_ICRC ? "ICRC " : "", - res->feature & ATA_UNC ? "UNC " : "", - res->feature & ATA_AMNF ? "AMNF " : "", - res->feature & ATA_IDNF ? "IDNF " : "", - res->feature & ATA_ABORTED ? "ABRT " : ""); + res->error & ATA_ICRC ? "ICRC " : "", + res->error & ATA_UNC ? "UNC " : "", + res->error & ATA_AMNF ? "AMNF " : "", + res->error & ATA_IDNF ? "IDNF " : "", + res->error & ATA_ABORTED ? "ABRT " : ""); #endif } } diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 071158c0c44c..044a16daa2d4 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -191,8 +191,8 @@ EXPORT_SYMBOL_GPL(ata_tf_to_fis); void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf) { - tf->command = fis[2]; /* status */ - tf->feature = fis[3]; /* error */ + tf->status = fis[2]; + tf->error = fis[3]; tf->lbal = fis[4]; tf->lbam = fis[5]; @@ -1406,8 +1406,8 @@ static int ata_eh_read_log_10h(struct ata_device *dev, *tag = buf[0] & 0x1f; - tf->command = buf[2]; - tf->feature = buf[3]; + tf->status = buf[2]; + tf->error = buf[3]; tf->lbal = buf[4]; tf->lbam = buf[5]; tf->lbah = buf[6]; @@ -1482,7 +1482,7 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) qc->result_tf.flags = ATA_TFLAG_ISADDR | ATA_TFLAG_LBA | ATA_TFLAG_LBA48; qc->err_mask |= AC_ERR_DEV | AC_ERR_NCQ; if (dev->class == ATA_DEV_ZAC && - ((qc->result_tf.command & ATA_SENSE) || qc->result_tf.auxiliary)) { + ((qc->result_tf.status & ATA_SENSE) || qc->result_tf.auxiliary)) { char sense_key, asc, ascq; sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 1b6f1a0ecebf..9df1a20b77dd 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -680,7 +680,7 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) */ static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf) { - u8 stat = tf->command, err = tf->feature; + u8 stat = tf->status, err = tf->error; if (stat & ATA_BUSY) { ata_port_warn(ap, "status=0x%02x {Busy} ", stat); @@ -871,8 +871,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) * onto sense key, asc & ascq. */ if (qc->err_mask || - tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, + tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, &sense_key, &asc, &ascq, verbose); ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); } else { @@ -901,13 +901,13 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) * Copy registers into sense buffer. */ desc[2] = 0x00; - desc[3] = tf->feature; /* == error reg */ + desc[3] = tf->error; desc[5] = tf->nsect; desc[7] = tf->lbal; desc[9] = tf->lbam; desc[11] = tf->lbah; desc[12] = tf->device; - desc[13] = tf->command; /* == status reg */ + desc[13] = tf->status; /* * Fill in Extend bit, and the high order bytes @@ -922,8 +922,8 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) } } else { /* Fixed sense format */ - desc[0] = tf->feature; - desc[1] = tf->command; /* status */ + desc[0] = tf->error; + desc[1] = tf->status; desc[2] = tf->device; desc[3] = tf->nsect; desc[7] = 0; @@ -972,14 +972,14 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) * onto sense key, asc & ascq. */ if (qc->err_mask || - tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { - ata_to_sense_error(qc->ap->print_id, tf->command, tf->feature, + tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, &sense_key, &asc, &ascq, verbose); ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); } else { /* Could not decode error */ ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n", - tf->command, qc->err_mask); + tf->status, qc->err_mask); ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); return; } @@ -2473,7 +2473,7 @@ static void atapi_request_sense(struct ata_queued_cmd *qc) /* fill these in, for the case where they are -not- overwritten */ cmd->sense_buffer[0] = 0x70; - cmd->sense_buffer[2] = qc->tf.feature >> 4; + cmd->sense_buffer[2] = qc->tf.error >> 4; ata_qc_reinit(qc); diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 2fb3956f66f6..1d28b1cd8baa 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -449,8 +449,8 @@ void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = ata_sff_check_status(ap); - tf->feature = ioread8(ioaddr->error_addr); + tf->status = ata_sff_check_status(ap); + tf->error = ioread8(ioaddr->error_addr); tf->nsect = ioread8(ioaddr->nsect_addr); tf->lbal = ioread8(ioaddr->lbal_addr); tf->lbam = ioread8(ioaddr->lbam_addr); @@ -1825,7 +1825,7 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, memset(&tf, 0, sizeof(tf)); ap->ops->sff_tf_read(ap, &tf); - err = tf.feature; + err = tf.error; if (r_err) *r_err = err; diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index b78f71c70f27..6c75a22db12b 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c @@ -416,8 +416,8 @@ static void ep93xx_pata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ep93xx_pata_data *drv_data = ap->host->private_data; - tf->command = ep93xx_pata_check_status(ap); - tf->feature = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE); + tf->status = ep93xx_pata_check_status(ap); + tf->error = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_FEATURE); tf->nsect = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_NSECT); tf->lbal = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAL); tf->lbam = ep93xx_pata_read_reg(drv_data, IDECTRL_ADDR_LBAM); diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index f4949e704356..9dd6bffefb48 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -264,8 +264,8 @@ void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = ns87560_check_status(ap); - tf->feature = ioread8(ioaddr->error_addr); + tf->status = ns87560_check_status(ap); + tf->error = ioread8(ioaddr->error_addr); tf->nsect = ioread8(ioaddr->nsect_addr); tf->lbal = ioread8(ioaddr->lbal_addr); tf->lbam = ioread8(ioaddr->lbam_addr); diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index 05c2ab375756..aaa9f95d814c 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -382,7 +382,7 @@ static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf) void __iomem *base = ap->ioaddr.data_addr; blob = __raw_readw(base + 0xc); - tf->feature = blob >> 8; + tf->error = blob >> 8; blob = __raw_readw(base + 2); tf->nsect = blob & 0xff; @@ -394,7 +394,7 @@ static void octeon_cf_tf_read16(struct ata_port *ap, struct ata_taskfile *tf) blob = __raw_readw(base + 6); tf->device = blob & 0xff; - tf->command = blob >> 8; + tf->status = blob >> 8; if (tf->flags & ATA_TFLAG_LBA48) { if (likely(ap->ioaddr.ctl_addr)) { diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index bdd2178c4a61..aba1536ddd44 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -213,7 +213,7 @@ static void pata_s3c_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->feature = ata_inb(ap->host, ioaddr->error_addr); + tf->error = ata_inb(ap->host, ioaddr->error_addr); tf->nsect = ata_inb(ap->host, ioaddr->nsect_addr); tf->lbal = ata_inb(ap->host, ioaddr->lbal_addr); tf->lbam = ata_inb(ap->host, ioaddr->lbam_addr); diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 077bce76c445..40bb27f83ecf 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -400,7 +400,7 @@ static int ahci_highbank_hardreset(struct ata_link *link, unsigned int *class, /* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init(link->device, &tf); - tf.command = ATA_BUSY; + tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); do { diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 781901151d82..11e518f0111c 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -557,13 +557,13 @@ static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { void __iomem *port_base = inic_port_base(ap); - tf->feature = readb(port_base + PORT_TF_FEATURE); + tf->error = readb(port_base + PORT_TF_FEATURE); tf->nsect = readb(port_base + PORT_TF_NSECT); tf->lbal = readb(port_base + PORT_TF_LBAL); tf->lbam = readb(port_base + PORT_TF_LBAM); tf->lbah = readb(port_base + PORT_TF_LBAH); tf->device = readb(port_base + PORT_TF_DEVICE); - tf->command = readb(port_base + PORT_TF_COMMAND); + tf->status = readb(port_base + PORT_TF_COMMAND); } static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc) @@ -580,11 +580,11 @@ static bool inic_qc_fill_rtf(struct ata_queued_cmd *qc) */ inic_tf_read(qc->ap, &tf); - if (!(tf.command & ATA_ERR)) + if (!(tf.status & ATA_ERR)) return false; - rtf->command = tf.command; - rtf->feature = tf.feature; + rtf->status = tf.status; + rtf->error = tf.error; return true; } diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index bde76a87beeb..8e4516acb3f6 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -394,8 +394,8 @@ static void sata_rcar_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = sata_rcar_check_status(ap); - tf->feature = ioread32(ioaddr->error_addr); + tf->status = sata_rcar_check_status(ap); + tf->error = ioread32(ioaddr->error_addr); tf->nsect = ioread32(ioaddr->nsect_addr); tf->lbal = ioread32(ioaddr->lbal_addr); tf->lbam = ioread32(ioaddr->lbam_addr); diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index f8552559db7f..2e3418a82b44 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -194,24 +194,24 @@ static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - u16 nsect, lbal, lbam, lbah, feature; + u16 nsect, lbal, lbam, lbah, error; - tf->command = k2_stat_check_status(ap); + tf->status = k2_stat_check_status(ap); tf->device = readw(ioaddr->device_addr); - feature = readw(ioaddr->error_addr); + error = readw(ioaddr->error_addr); nsect = readw(ioaddr->nsect_addr); lbal = readw(ioaddr->lbal_addr); lbam = readw(ioaddr->lbam_addr); lbah = readw(ioaddr->lbah_addr); - tf->feature = feature; + tf->error = error; tf->nsect = nsect; tf->lbal = lbal; tf->lbam = lbam; tf->lbah = lbah; if (tf->flags & ATA_TFLAG_LBA48) { - tf->hob_feature = feature >> 8; + tf->hob_feature = error >> 8; tf->hob_nsect = nsect >> 8; tf->hob_lbal = lbal >> 8; tf->hob_lbam = lbam >> 8; diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index 8fa952cb9f7f..87e4ed66b306 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -183,24 +183,24 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - u16 nsect, lbal, lbam, lbah, feature; + u16 nsect, lbal, lbam, lbah, error; - tf->command = ata_sff_check_status(ap); + tf->status = ata_sff_check_status(ap); tf->device = readw(ioaddr->device_addr); - feature = readw(ioaddr->error_addr); + error = readw(ioaddr->error_addr); nsect = readw(ioaddr->nsect_addr); lbal = readw(ioaddr->lbal_addr); lbam = readw(ioaddr->lbam_addr); lbah = readw(ioaddr->lbah_addr); - tf->feature = feature; + tf->error = error; tf->nsect = nsect; tf->lbal = lbal; tf->lbam = lbam; tf->lbah = lbah; if (tf->flags & ATA_TFLAG_LBA48) { - tf->hob_feature = feature >> 8; + tf->hob_feature = error >> 8; tf->hob_nsect = nsect >> 8; tf->hob_lbal = lbal >> 8; tf->hob_lbam = lbam >> 8; diff --git a/include/linux/libata.h b/include/linux/libata.h index a49e75c4206d..0619ae462ecd 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -518,7 +518,10 @@ struct ata_taskfile { u8 hob_lbam; u8 hob_lbah; - u8 feature; + union { + u8 error; + u8 feature; + }; u8 nsect; u8 lbal; u8 lbam; @@ -526,7 +529,10 @@ struct ata_taskfile { u8 device; - u8 command; /* IO operation */ + union { + u8 status; + u8 command; + }; u32 auxiliary; /* auxiliary field */ /* from SATA 3.1 and */ From ffa92a7457555df6871cfb15c2fb3afcb02c4d2b Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Thu, 17 Feb 2022 18:38:29 +0300 Subject: [PATCH 055/124] ata: libata-sff: use *switch* statement in ata_sff_dev_classify() In ata_sff_dev_classify(), replace a string of the *if* statements checking the device's class with the *switch* statement that fits better here... While at it, fix the multi-line comment style in the vicinity... Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/libata-sff.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 1d28b1cd8baa..b3be7a8f5bea 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c @@ -1842,9 +1842,10 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, /* determine if device is ATA or ATAPI */ class = ata_port_classify(ap, &tf); - - if (class == ATA_DEV_UNKNOWN) { - /* If the device failed diagnostic, it's likely to + switch (class) { + case ATA_DEV_UNKNOWN: + /* + * If the device failed diagnostic, it's likely to * have reported incorrect device signature too. * Assume ATA device if the device seems present but * device signature is invalid with diagnostic @@ -1854,10 +1855,12 @@ unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, class = ATA_DEV_ATA; else class = ATA_DEV_NONE; - } else if ((class == ATA_DEV_ATA) && - (ap->ops->sff_check_status(ap) == 0)) - class = ATA_DEV_NONE; - + break; + case ATA_DEV_ATA: + if (ap->ops->sff_check_status(ap) == 0) + class = ATA_DEV_NONE; + break; + } return class; } EXPORT_SYMBOL_GPL(ata_sff_dev_classify); From 9256766fe2df9510cbeee8b458dab5df7df8506e Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Fri, 18 Feb 2022 13:06:14 +0300 Subject: [PATCH 056/124] ata: pata_hpt37x: merge transfer mode setting methods After commit e0afcf140e6e ("ata: pata_hpt37x: disable fast interrupts in prereset() method") HPT370's and HPT372+'s PIO/DMA mode setting functions have become identical -- merge them. Signed-off-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_hpt37x.c | 75 +++++++-------------------------------- 1 file changed, 13 insertions(+), 62 deletions(-) diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index cb0fcee02de3..015da39e3c24 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -23,7 +23,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.24" +#define DRV_VERSION "0.6.25" struct hpt_clock { u8 xfer_speed; @@ -420,7 +420,7 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline) return ata_sff_prereset(link, deadline); } -static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev, +static void hpt37x_set_mode(struct ata_port *ap, struct ata_device *adev, u8 mode) { struct pci_dev *pdev = to_pci_dev(ap->host->dev); @@ -442,29 +442,29 @@ static void hpt370_set_mode(struct ata_port *ap, struct ata_device *adev, pci_write_config_dword(pdev, addr, reg); } /** - * hpt370_set_piomode - PIO setup + * hpt37x_set_piomode - PIO setup * @ap: ATA interface * @adev: device on the interface * * Perform PIO mode setup. */ -static void hpt370_set_piomode(struct ata_port *ap, struct ata_device *adev) +static void hpt37x_set_piomode(struct ata_port *ap, struct ata_device *adev) { - hpt370_set_mode(ap, adev, adev->pio_mode); + hpt37x_set_mode(ap, adev, adev->pio_mode); } /** - * hpt370_set_dmamode - DMA timing setup + * hpt37x_set_dmamode - DMA timing setup * @ap: ATA interface * @adev: Device being configured * * Set up the channel for MWDMA or UDMA modes. */ -static void hpt370_set_dmamode(struct ata_port *ap, struct ata_device *adev) +static void hpt37x_set_dmamode(struct ata_port *ap, struct ata_device *adev) { - hpt370_set_mode(ap, adev, adev->dma_mode); + hpt37x_set_mode(ap, adev, adev->dma_mode); } /** @@ -504,54 +504,6 @@ static void hpt370_bmdma_stop(struct ata_queued_cmd *qc) ata_bmdma_stop(qc); } -static void hpt372_set_mode(struct ata_port *ap, struct ata_device *adev, - u8 mode) -{ - struct pci_dev *pdev = to_pci_dev(ap->host->dev); - int addr = 0x40 + 4 * (adev->devno + 2 * ap->port_no); - u32 reg, timing, mask; - - /* Determine timing mask and find matching mode entry */ - if (mode < XFER_MW_DMA_0) - mask = 0xcfc3ffff; - else if (mode < XFER_UDMA_0) - mask = 0x31c001ff; - else - mask = 0x303c0000; - - timing = hpt37x_find_mode(ap, mode); - - pci_read_config_dword(pdev, addr, ®); - reg = (reg & ~mask) | (timing & mask); - pci_write_config_dword(pdev, addr, reg); -} - -/** - * hpt372_set_piomode - PIO setup - * @ap: ATA interface - * @adev: device on the interface - * - * Perform PIO mode setup. - */ - -static void hpt372_set_piomode(struct ata_port *ap, struct ata_device *adev) -{ - hpt372_set_mode(ap, adev, adev->pio_mode); -} - -/** - * hpt372_set_dmamode - DMA timing setup - * @ap: ATA interface - * @adev: Device being configured - * - * Set up the channel for MWDMA or UDMA modes. - */ - -static void hpt372_set_dmamode(struct ata_port *ap, struct ata_device *adev) -{ - hpt372_set_mode(ap, adev, adev->dma_mode); -} - /** * hpt37x_bmdma_stop - DMA engine stop * @qc: ATA command @@ -589,8 +541,8 @@ static struct ata_port_operations hpt370_port_ops = { .mode_filter = hpt370_filter, .cable_detect = hpt37x_cable_detect, - .set_piomode = hpt370_set_piomode, - .set_dmamode = hpt370_set_dmamode, + .set_piomode = hpt37x_set_piomode, + .set_dmamode = hpt37x_set_dmamode, .prereset = hpt37x_pre_reset, }; @@ -604,8 +556,7 @@ static struct ata_port_operations hpt370a_port_ops = { }; /* - * Configuration for HPT371 and HPT302. Slightly different PIO and DMA - * mode setting functionality. + * Configuration for HPT371 and HPT302. */ static struct ata_port_operations hpt302_port_ops = { @@ -614,8 +565,8 @@ static struct ata_port_operations hpt302_port_ops = { .bmdma_stop = hpt37x_bmdma_stop, .cable_detect = hpt37x_cable_detect, - .set_piomode = hpt372_set_piomode, - .set_dmamode = hpt372_set_dmamode, + .set_piomode = hpt37x_set_piomode, + .set_dmamode = hpt37x_set_dmamode, .prereset = hpt37x_pre_reset, }; From e005ff01bfdb653ac2f03614625cb9aefa86fa9c Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Wed, 26 Jan 2022 10:32:30 +0000 Subject: [PATCH 057/124] selftests/kselftest/runner.sh: Pass optional command parameters in environment Some testcases allow for optional commandline parameters but as of now there is now way to provide such arguments to the runner script. Add support to retrieve such optional command parameters fron environment variables named so as to include the all-uppercase test executable name, sanitized substituting any non-acceptable varname characters with "_", following the pattern: KSELFTEST__ARGS="options" Optional command parameters support is not available if 'tr' is not installed on the test system. Cc: Kees Cook Signed-off-by: Cristian Marussi Signed-off-by: Shuah Khan --- tools/testing/selftests/kselftest/runner.sh | 30 ++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/kselftest/runner.sh b/tools/testing/selftests/kselftest/runner.sh index a9ba782d8ca0..294619ade49f 100644 --- a/tools/testing/selftests/kselftest/runner.sh +++ b/tools/testing/selftests/kselftest/runner.sh @@ -18,6 +18,8 @@ if [ -z "$BASE_DIR" ]; then exit 1 fi +TR_CMD=$(command -v tr) + # If Perl is unavailable, we must fall back to line-at-a-time prefixing # with sed instead of unbuffered output. tap_prefix() @@ -49,6 +51,31 @@ run_one() # Reset any "settings"-file variables. export kselftest_timeout="$kselftest_default_timeout" + + # Safe default if tr not available + kselftest_cmd_args_ref="KSELFTEST_ARGS" + + # Optional arguments for this command, possibly defined as an + # environment variable built using the test executable in all + # uppercase and sanitized substituting non acceptable shell + # variable name characters with "_" as in: + # + # KSELFTEST__ARGS="" + # + # e.g. + # + # rtctest --> KSELFTEST_RTCTEST_ARGS="/dev/rtc1" + # + # cpu-on-off-test.sh --> KSELFTEST_CPU_ON_OFF_TEST_SH_ARGS="-a -p 10" + # + if [ -n "$TR_CMD" ]; then + BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \ + $TR_CMD -d "[:blank:][:cntrl:]" | \ + $TR_CMD -c "[:alnum:]_" "_" | \ + $TR_CMD [:lower:] [:upper:]) + kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS" + fi + # Load per-test-directory kselftest "settings" file. settings="$BASE_DIR/$DIR/settings" if [ -r "$settings" ] ; then @@ -69,7 +96,8 @@ run_one() echo "# Warning: file $TEST is missing!" echo "not ok $test_num $TEST_HDR_MSG" else - cmd="./$BASENAME_TEST" + eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}" + cmd="./$BASENAME_TEST $kselftest_cmd_args" if [ ! -x "$TEST" ]; then echo "# Warning: file $TEST is not executable" From cef757808666de8400d09ac11521418d8122edd5 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:33:32 +0500 Subject: [PATCH 058/124] selftests: futex: set DEFAULT_INSTALL_HDR_PATH If only futex selftest is compiled, uapi header files are copied to the selftests/futex/functional directory. This copy isn't needed. Set the DEFAULT_INSTALL_HDR_PATH variable to 1 to use the default header install path only. This removes extra copy of header file. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/futex/functional/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile index 5cc38de9d8ea..9a8c3700d773 100644 --- a/tools/testing/selftests/futex/functional/Makefile +++ b/tools/testing/selftests/futex/functional/Makefile @@ -24,6 +24,7 @@ TEST_PROGS := run.sh top_srcdir = ../../../../.. KSFT_KHDR_INSTALL := 1 +DEFAULT_INSTALL_HDR_PATH := 1 include ../../lib.mk $(TEST_GEN_FILES): $(HEADERS) From 5ad51ab618de5d05f4e692ebabeb6fe6289aaa57 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:22 +0500 Subject: [PATCH 059/124] selftests: set the BUILD variable to absolute path The build of kselftests fails if relative path is specified through KBUILD_OUTPUT or O= method. BUILD variable is used to determine the path of the output objects. When make is run from other directories with relative paths, the exact path of the build objects is ambiguous and build fails. make[1]: Entering directory '/home/usama/repos/kernel/linux_mainline2/tools/testing/selftests/alsa' gcc mixer-test.c -L/usr/lib/x86_64-linux-gnu -lasound -o build/kselftest/alsa/mixer-test /usr/bin/ld: cannot open output file build/kselftest/alsa/mixer-test Set the BUILD variable to the absolute path of the output directory. Make the logic readable and easy to follow. Use spaces instead of tabs for indentation as if with tab indentation is considered recipe in make. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index d08fe4cfe811..a7b63860b7bc 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -114,19 +114,27 @@ ifdef building_out_of_srctree override LDFLAGS = endif -ifneq ($(O),) - BUILD := $(O)/kselftest +top_srcdir ?= ../../.. + +ifeq ("$(origin O)", "command line") + KBUILD_OUTPUT := $(O) +endif + +ifneq ($(KBUILD_OUTPUT),) + # Make's built-in functions such as $(abspath ...), $(realpath ...) cannot + # expand a shell special character '~'. We use a somewhat tedious way here. + abs_objtree := $(shell cd $(top_srcdir) && mkdir -p $(KBUILD_OUTPUT) && cd $(KBUILD_OUTPUT) && pwd) + $(if $(abs_objtree),, \ + $(error failed to create output directory "$(KBUILD_OUTPUT)")) + # $(realpath ...) resolves symlinks + abs_objtree := $(realpath $(abs_objtree)) + BUILD := $(abs_objtree)/kselftest else - ifneq ($(KBUILD_OUTPUT),) - BUILD := $(KBUILD_OUTPUT)/kselftest - else - BUILD := $(shell pwd) - DEFAULT_INSTALL_HDR_PATH := 1 - endif + BUILD := $(CURDIR) + DEFAULT_INSTALL_HDR_PATH := 1 endif # Prepare for headers install -top_srcdir ?= ../../.. include $(top_srcdir)/scripts/subarch.include ARCH ?= $(SUBARCH) export KSFT_KHDR_INSTALL_DONE := 1 From 250f8c1137578e6210becaed63ec6e9a8eea430e Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:23 +0500 Subject: [PATCH 060/124] selftests: Add and export a kernel uapi headers path Kernel uapi headers can be present at different paths depending upon how the build was invoked. It becomes impossible for the tests to include the correct headers directory. Set and export KHDR_INCLUDES variable to make it possible for sub make files to include the header files. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index a7b63860b7bc..21f983dfd047 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -129,8 +129,11 @@ ifneq ($(KBUILD_OUTPUT),) # $(realpath ...) resolves symlinks abs_objtree := $(realpath $(abs_objtree)) BUILD := $(abs_objtree)/kselftest + KHDR_INCLUDES := -I${abs_objtree}/usr/include else BUILD := $(CURDIR) + abs_srctree := $(shell cd $(top_srcdir) && pwd) + KHDR_INCLUDES := -I${abs_srctree}/usr/include DEFAULT_INSTALL_HDR_PATH := 1 endif @@ -139,6 +142,7 @@ include $(top_srcdir)/scripts/subarch.include ARCH ?= $(SUBARCH) export KSFT_KHDR_INSTALL_DONE := 1 export BUILD +export KHDR_INCLUDES # set default goal to all, so make without a target runs all, even when # all isn't the first target in the file. From afe5fba8d10b40fdc517b46a2b59d2172686221e Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:24 +0500 Subject: [PATCH 061/124] selftests: Correct the headers install path uapi headers should be installed at the top of the object tree, "/usr/include". There is no need for kernel headers to be present at kselftest build directory, "/kselftest/usr/ include" as well. This duplication can be avoided by correctly specifying the INSTALL_HDR_PATH. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 21f983dfd047..80e5498eab92 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -167,7 +167,7 @@ khdr: ifeq (1,$(DEFAULT_INSTALL_HDR_PATH)) $(MAKE) --no-builtin-rules ARCH=$(ARCH) -C $(top_srcdir) headers_install else - $(MAKE) --no-builtin-rules INSTALL_HDR_PATH=$$BUILD/usr \ + $(MAKE) --no-builtin-rules INSTALL_HDR_PATH=$(abs_objtree)/usr \ ARCH=$(ARCH) -C $(top_srcdir) headers_install endif From bd7d481c37716b21b251e6f8248ed6d8f2183445 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:25 +0500 Subject: [PATCH 062/124] selftests: futex: Add the uapi headers include variable Out of tree build of this test fails if relative path of the output directory is specified. KBUILD_OUTPUT also doesn't point to the correct directory when relative path is used. Thus out of tree builds fail. Remove the un-needed include paths and use KHDR_INCLUDES to correctly reach the headers. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/futex/functional/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile index 9a8c3700d773..b8152c573e8a 100644 --- a/tools/testing/selftests/futex/functional/Makefile +++ b/tools/testing/selftests/futex/functional/Makefile @@ -1,7 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -INCLUDES := -I../include -I../../ -I../../../../../usr/include/ \ - -I$(KBUILD_OUTPUT)/kselftest/usr/include -CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) +INCLUDES := -I../include -I../../ -I../../../../../usr/include/ +CFLAGS := $(CFLAGS) -g -O2 -Wall -D_GNU_SOURCE -pthread $(INCLUDES) $(KHDR_INCLUDES) LDLIBS := -lpthread -lrt HEADERS := \ From 0cc5963b4cc348fc37586ae8cbd91db1398037d1 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:26 +0500 Subject: [PATCH 063/124] selftests: kvm: Add the uapi headers include variable Out of tree build of this test fails if relative path of the output directory is specified. Add KHDR_INCLUDES to correctly reach the headers. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/kvm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile index 17c3f0749f05..b970397f725c 100644 --- a/tools/testing/selftests/kvm/Makefile +++ b/tools/testing/selftests/kvm/Makefile @@ -149,7 +149,7 @@ endif CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \ -fno-stack-protector -fno-PIE -I$(LINUX_TOOL_INCLUDE) \ -I$(LINUX_TOOL_ARCH_INCLUDE) -I$(LINUX_HDR_PATH) -Iinclude \ - -I$( Date: Wed, 19 Jan 2022 15:15:27 +0500 Subject: [PATCH 064/124] selftests: landlock: Add the uapi headers include variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out of tree build of this test fails if relative path of the output directory is specified. Add the KHDR_INCLUDES to correctly reach the headers. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Mickaël Salaün Signed-off-by: Shuah Khan --- tools/testing/selftests/landlock/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/landlock/Makefile b/tools/testing/selftests/landlock/Makefile index a99596ca9882..0b0049e133bb 100644 --- a/tools/testing/selftests/landlock/Makefile +++ b/tools/testing/selftests/landlock/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -CFLAGS += -Wall -O2 +CFLAGS += -Wall -O2 $(KHDR_INCLUDES) src_test := $(wildcard *_test.c) From 50f4143df0a63220f2108dc62164c432e07e410b Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:28 +0500 Subject: [PATCH 065/124] selftests: net: Add the uapi headers include variable Out of tree build of this test fails if relative path of the output directory is specified. Add the KHDR_INCLUDES to correctly reach the headers. Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/net/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index 9897fa9ab953..0b1488616c55 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -2,7 +2,7 @@ # Makefile for net selftests CFLAGS = -Wall -Wl,--no-as-needed -O2 -g -CFLAGS += -I../../../../usr/include/ +CFLAGS += -I../../../../usr/include/ $(KHDR_INCLUDES) TEST_PROGS := run_netsocktests run_afpackettests test_bpf.sh netdevice.sh \ rtnetlink.sh xfrm_policy.sh test_blackhole_dev.sh From 5faa35d0b8cc1403acb6760e9e95905cfd691872 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:29 +0500 Subject: [PATCH 066/124] selftests: mptcp: Add the uapi headers include variable Out of tree build of this test fails if relative path of the output directory is specified. Add the KHDR_INCLUDES to correctly reach the headers. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Matthieu Baerts Signed-off-by: Shuah Khan --- tools/testing/selftests/net/mptcp/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/mptcp/Makefile b/tools/testing/selftests/net/mptcp/Makefile index 0356c4501c99..f905d5358e68 100644 --- a/tools/testing/selftests/net/mptcp/Makefile +++ b/tools/testing/selftests/net/mptcp/Makefile @@ -3,7 +3,7 @@ top_srcdir = ../../../../.. KSFT_KHDR_INSTALL := 1 -CFLAGS = -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include +CFLAGS = -Wall -Wl,--no-as-needed -O2 -g -I$(top_srcdir)/usr/include $(KHDR_INCLUDES) TEST_PROGS := mptcp_connect.sh pm_netlink.sh mptcp_join.sh diag.sh \ simult_flows.sh mptcp_sockopt.sh From 4a8900207abdc629933f07329bd884c60b50f074 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:30 +0500 Subject: [PATCH 067/124] selftests: vm: Add the uapi headers include variable Out of tree build of this test fails if relative path of the output directory is specified. Add the KHDR_INCLUDES to correctly reach the headers. Acked-by: Paolo Bonzini Signed-off-by: Muhammad Usama Anjum Tested-by: Alistair Popple Signed-off-by: Shuah Khan --- tools/testing/selftests/vm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile index 1607322a112c..033e9e11e2da 100644 --- a/tools/testing/selftests/vm/Makefile +++ b/tools/testing/selftests/vm/Makefile @@ -23,7 +23,7 @@ MACHINE ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/p # LDLIBS. MAKEFLAGS += --no-builtin-rules -CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) +CFLAGS = -Wall -I ../../../../usr/include $(EXTRA_CFLAGS) $(KHDR_INCLUDES) LDLIBS = -lrt -lpthread TEST_GEN_FILES = compaction_test TEST_GEN_FILES += gup_test From 681696862bc1823595c05960a83766d1aa965c17 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 19 Jan 2022 15:15:31 +0500 Subject: [PATCH 068/124] selftests: vm: remove dependecy from internal kernel macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The defination of swap() is used from kernel's internal header when this test is built in source tree. The build fails when this test is built out of source tree as defination of swap() isn't found. Selftests shouldn't depend on kernel's internal header files. They can only depend on uapi header files. Add the defination of swap() to fix the build error: gcc -Wall -I/linux_mainline2/build/usr/include -no-pie userfaultfd.c -lrt -lpthread -o /linux_mainline2/build/kselftest/vm/userfaultfd userfaultfd.c: In function ‘userfaultfd_stress’: userfaultfd.c:1530:3: warning: implicit declaration of function ‘swap’; did you mean ‘swab’? [-Wimplicit-function-declaration] 1530 | swap(area_src, area_dst); | ^~~~ | swab /usr/bin/ld: /tmp/cclUUH7V.o: in function `userfaultfd_stress': userfaultfd.c:(.text+0x4d64): undefined reference to `swap' /usr/bin/ld: userfaultfd.c:(.text+0x4d82): undefined reference to `swap' collect2: error: ld returned 1 exit status Fixes: 2c769ed7137a ("tools/testing/selftests/vm/userfaultfd.c: use swap() to make code cleaner") Signed-off-by: Muhammad Usama Anjum Reviewed-by: Alistair Popple Signed-off-by: Shuah Khan --- tools/testing/selftests/vm/userfaultfd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c index 2f49c9af1b58..50476ec6c070 100644 --- a/tools/testing/selftests/vm/userfaultfd.c +++ b/tools/testing/selftests/vm/userfaultfd.c @@ -119,6 +119,9 @@ struct uffd_stats { ~(unsigned long)(sizeof(unsigned long long) \ - 1))) +#define swap(a, b) \ + do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) + const char *examples = "# Run anonymous memory test on 100MiB region with 99999 bounces:\n" "./userfaultfd anon 100 99999\n\n" From 46e50459ea10cbf8a534fc1e6e752408dda191ef Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Mon, 14 Feb 2022 21:07:56 +0500 Subject: [PATCH 069/124] selftests: Use -isystem instead of -I to include headers Selftests need kernel headers and glibc for compilation. In compilation of selftests, uapi headers from kernel source are used instead of default ones while glibc has already been compiled with different header files installed in the operating system. So there can be redefination warnings from compiler. These warnings can be suppressed by using -isystem to include the uapi headers. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 80e5498eab92..5d9d4ddccccb 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -129,11 +129,11 @@ ifneq ($(KBUILD_OUTPUT),) # $(realpath ...) resolves symlinks abs_objtree := $(realpath $(abs_objtree)) BUILD := $(abs_objtree)/kselftest - KHDR_INCLUDES := -I${abs_objtree}/usr/include + KHDR_INCLUDES := -isystem ${abs_objtree}/usr/include else BUILD := $(CURDIR) abs_srctree := $(shell cd $(top_srcdir) && pwd) - KHDR_INCLUDES := -I${abs_srctree}/usr/include + KHDR_INCLUDES := -isystem ${abs_srctree}/usr/include DEFAULT_INSTALL_HDR_PATH := 1 endif From 4893992b6de1be5e0c9f6df747912761e96b4271 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Fri, 11 Feb 2022 03:23:19 +0500 Subject: [PATCH 070/124] selftests/exec: Rename file binfmt_script to binfmt_script.py Rename file for readability purpose. Update its usage and references. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/exec/Makefile | 2 +- .../testing/selftests/exec/{binfmt_script => binfmt_script.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename tools/testing/selftests/exec/{binfmt_script => binfmt_script.py} (100%) diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile index 2d7fca446c7f..7f0412a26ba9 100644 --- a/tools/testing/selftests/exec/Makefile +++ b/tools/testing/selftests/exec/Makefile @@ -3,7 +3,7 @@ CFLAGS = -Wall CFLAGS += -Wno-nonnull CFLAGS += -D_GNU_SOURCE -TEST_PROGS := binfmt_script +TEST_PROGS := binfmt_script.py TEST_GEN_PROGS := execveat load_address_4096 load_address_2097152 load_address_16777216 non-regular TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir # Makefile is a run-time dependency, since it's accessed by the execveat test diff --git a/tools/testing/selftests/exec/binfmt_script b/tools/testing/selftests/exec/binfmt_script.py similarity index 100% rename from tools/testing/selftests/exec/binfmt_script rename to tools/testing/selftests/exec/binfmt_script.py From b22dfec72c377e350c4cafce4078977d3e5bee03 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Fri, 21 Jan 2022 19:51:52 +0500 Subject: [PATCH 071/124] selftests/lkdtm: Remove dead config option CONFIG_HARDENED_USERCOPY_FALLBACK config option has been removed in commit 53944f171a89 ("mm: remove HARDENED_USERCOPY_FALLBACK"). Remove it from the lkdtm selftest config. Signed-off-by: Muhammad Usama Anjum Acked-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/lkdtm/config | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/testing/selftests/lkdtm/config b/tools/testing/selftests/lkdtm/config index a26a3fa9e925..a7a58f885f52 100644 --- a/tools/testing/selftests/lkdtm/config +++ b/tools/testing/selftests/lkdtm/config @@ -3,7 +3,6 @@ CONFIG_DEBUG_LIST=y CONFIG_SLAB_FREELIST_HARDENED=y CONFIG_FORTIFY_SOURCE=y CONFIG_HARDENED_USERCOPY=y -# CONFIG_HARDENED_USERCOPY_FALLBACK is not set CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y CONFIG_UBSAN_BOUNDS=y From 1900be289b598b2c553b3add13e491c0bb8a8550 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Fri, 21 Jan 2022 19:51:53 +0500 Subject: [PATCH 072/124] selftests/lkdtm: Add UBSAN config UBSAN_BOUNDS and UBSAN_TRAP depend on UBSAN config option. merge_config.sh script generates following warnings if parent config doesn't have UBSAN config already enabled and UBSAN_BOUNDS/UBSAN_TRAP config options don't get added to the parent config. Value requested for CONFIG_UBSAN_BOUNDS not in final .config Requested value: CONFIG_UBSAN_BOUNDS=y Actual value: Value requested for CONFIG_UBSAN_TRAP not in final .config Requested value: CONFIG_UBSAN_TRAP=y Actual value: Fix this by including UBSAN config. Fixes: c75be56e35b2 ("lkdtm/bugs: Add ARRAY_BOUNDS to selftests") Signed-off-by: Muhammad Usama Anjum Acked-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/lkdtm/config | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/lkdtm/config b/tools/testing/selftests/lkdtm/config index a7a58f885f52..46f39ee76208 100644 --- a/tools/testing/selftests/lkdtm/config +++ b/tools/testing/selftests/lkdtm/config @@ -5,6 +5,7 @@ CONFIG_FORTIFY_SOURCE=y CONFIG_HARDENED_USERCOPY=y CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y +CONFIG_UBSAN=y CONFIG_UBSAN_BOUNDS=y CONFIG_UBSAN_TRAP=y CONFIG_STACKPROTECTOR_STRONG=y From d7fd696c12605b1666e9a2051e2ac896af103bfe Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 25 Feb 2022 10:52:46 +0800 Subject: [PATCH 073/124] list: test: Add test for list_del_init_careful() The list_del_init_careful() function was added[1] after the list KUnit test. Add a very basic test to cover it. Note that this test only covers the single-threaded behaviour (which matches list_del_init()), as is already the case with the test for list_empty_careful(). [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c6fe44d96fc1536af5b11cd859686453d1b7bfd1 Signed-off-by: David Gow Reviewed-by: Andy Shevchenko Signed-off-by: Shuah Khan --- lib/list-test.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/list-test.c b/lib/list-test.c index ee09505df16f..302b7382bff4 100644 --- a/lib/list-test.c +++ b/lib/list-test.c @@ -161,6 +161,26 @@ static void list_test_list_del_init(struct kunit *test) KUNIT_EXPECT_TRUE(test, list_empty_careful(&a)); } +static void list_test_list_del_init_careful(struct kunit *test) +{ + /* NOTE: This test only checks the behaviour of this function in + * isolation. It does not verify memory model guarantees. + */ + struct list_head a, b; + LIST_HEAD(list); + + list_add_tail(&a, &list); + list_add_tail(&b, &list); + + /* before: [list] -> a -> b */ + list_del_init_careful(&a); + /* after: [list] -> b, a initialised */ + + KUNIT_EXPECT_PTR_EQ(test, list.next, &b); + KUNIT_EXPECT_PTR_EQ(test, b.prev, &list); + KUNIT_EXPECT_TRUE(test, list_empty_careful(&a)); +} + static void list_test_list_move(struct kunit *test) { struct list_head a, b; @@ -707,6 +727,7 @@ static struct kunit_case list_test_cases[] = { KUNIT_CASE(list_test_list_replace_init), KUNIT_CASE(list_test_list_swap), KUNIT_CASE(list_test_list_del_init), + KUNIT_CASE(list_test_list_del_init_careful), KUNIT_CASE(list_test_list_move), KUNIT_CASE(list_test_list_move_tail), KUNIT_CASE(list_test_list_bulk_move_tail), From 37dc573c0a547e1aed0c9abb480fab797bd3833f Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 25 Feb 2022 10:52:48 +0800 Subject: [PATCH 074/124] list: test: Add a test for list_is_head() list_is_head() was added recently[1], and didn't have a KUnit test. The implementation is trivial, so it's not a particularly exciting test, but it'd be nice to get back to full coverage of the list functions. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/linux/list.h?id=0425473037db40d9e322631f2d4dc6ef51f97e88 Signed-off-by: David Gow Acked-by: Daniel Latypov Acked-by: Brendan Higgins Reviewed-by: Andy Shevchenko Signed-off-by: Shuah Khan --- lib/list-test.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/list-test.c b/lib/list-test.c index 302b7382bff4..3870ebfd84aa 100644 --- a/lib/list-test.c +++ b/lib/list-test.c @@ -254,6 +254,24 @@ static void list_test_list_bulk_move_tail(struct kunit *test) KUNIT_EXPECT_EQ(test, i, 2); } +static void list_test_list_is_head(struct kunit *test) +{ + struct list_head a, b, c; + + /* Two lists: [a] -> b, [c] */ + INIT_LIST_HEAD(&a); + INIT_LIST_HEAD(&c); + list_add_tail(&b, &a); + + KUNIT_EXPECT_TRUE_MSG(test, list_is_head(&a, &a), + "Head element of same list"); + KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &b), + "Non-head element of same list"); + KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &c), + "Head element of different list"); +} + + static void list_test_list_is_first(struct kunit *test) { struct list_head a, b; @@ -731,6 +749,7 @@ static struct kunit_case list_test_cases[] = { KUNIT_CASE(list_test_list_move), KUNIT_CASE(list_test_list_move_tail), KUNIT_CASE(list_test_list_bulk_move_tail), + KUNIT_CASE(list_test_list_is_head), KUNIT_CASE(list_test_list_is_first), KUNIT_CASE(list_test_list_is_last), KUNIT_CASE(list_test_list_empty), From 5debe5bfa02c4c8922bd2d0f82c9c3a70bec8944 Mon Sep 17 00:00:00 2001 From: David Gow Date: Fri, 25 Feb 2022 10:52:49 +0800 Subject: [PATCH 075/124] list: test: Add a test for list_entry_is_head() The list_entry_is_head() macro was added[1] after the list KUnit tests, so wasn't tested. Add a new KUnit test to complete the set. [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e130816164e244b692921de49771eeb28205152d Signed-off-by: David Gow Acked-by: Daniel Latypov Acked-by: Brendan Higgins Reviewed-by: Andy Shevchenko Signed-off-by: Shuah Khan --- lib/list-test.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/list-test.c b/lib/list-test.c index 3870ebfd84aa..035ef6597640 100644 --- a/lib/list-test.c +++ b/lib/list-test.c @@ -549,6 +549,26 @@ static void list_test_list_entry(struct kunit *test) struct list_test_struct, list)); } +static void list_test_list_entry_is_head(struct kunit *test) +{ + struct list_test_struct test_struct1, test_struct2, test_struct3; + + INIT_LIST_HEAD(&test_struct1.list); + INIT_LIST_HEAD(&test_struct3.list); + + list_add_tail(&test_struct2.list, &test_struct1.list); + + KUNIT_EXPECT_TRUE_MSG(test, + list_entry_is_head((&test_struct1), &test_struct1.list, list), + "Head element of same list"); + KUNIT_EXPECT_FALSE_MSG(test, + list_entry_is_head((&test_struct2), &test_struct1.list, list), + "Non-head element of same list"); + KUNIT_EXPECT_FALSE_MSG(test, + list_entry_is_head((&test_struct3), &test_struct1.list, list), + "Head element of different list"); +} + static void list_test_list_first_entry(struct kunit *test) { struct list_test_struct test_struct1, test_struct2; @@ -764,6 +784,7 @@ static struct kunit_case list_test_cases[] = { KUNIT_CASE(list_test_list_splice_init), KUNIT_CASE(list_test_list_splice_tail_init), KUNIT_CASE(list_test_list_entry), + KUNIT_CASE(list_test_list_entry_is_head), KUNIT_CASE(list_test_list_first_entry), KUNIT_CASE(list_test_list_last_entry), KUNIT_CASE(list_test_list_first_entry_or_null), From 2aaa36e95ea586ad23edfcc1d474e8b735a4d1c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Jo=C5=84czyk?= Date: Sat, 19 Feb 2022 08:27:13 +0100 Subject: [PATCH 076/124] selftests/rtc: continuously read RTC in a loop for 30s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some problems with reading the RTC time may happen rarely, for example while the RTC is updating. So read the RTC many times to catch these problems. For example, a previous attempt for my commit ea6fa4961aab ("rtc: mc146818-lib: fix RTC presence check") was incorrect and would have triggered this selftest. To avoid the risk of damaging the hardware, wait 11ms before consecutive reads. In rtc_time_to_timestamp I copied values manually instead of casting - just to be on the safe side. The 11ms wait period was chosen so that it is not a divisor of 1000ms. Signed-off-by: Mateusz JoÅ„czyk Cc: Alessandro Zummo Cc: Alexandre Belloni Cc: Shuah Khan Signed-off-by: Shuah Khan --- tools/testing/selftests/rtc/rtctest.c | 66 +++++++++++++++++++++++++++ tools/testing/selftests/rtc/settings | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c index 66af608fb4c6..2b9d929a24ed 100644 --- a/tools/testing/selftests/rtc/rtctest.c +++ b/tools/testing/selftests/rtc/rtctest.c @@ -20,6 +20,8 @@ #define NUM_UIE 3 #define ALARM_DELTA 3 +#define READ_LOOP_DURATION_SEC 30 +#define READ_LOOP_SLEEP_MS 11 static char *rtc_file = "/dev/rtc0"; @@ -49,6 +51,70 @@ TEST_F(rtc, date_read) { rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec); } +static time_t rtc_time_to_timestamp(struct rtc_time *rtc_time) +{ + struct tm tm_time = { + .tm_sec = rtc_time->tm_sec, + .tm_min = rtc_time->tm_min, + .tm_hour = rtc_time->tm_hour, + .tm_mday = rtc_time->tm_mday, + .tm_mon = rtc_time->tm_mon, + .tm_year = rtc_time->tm_year, + }; + + return mktime(&tm_time); +} + +static void nanosleep_with_retries(long ns) +{ + struct timespec req = { + .tv_sec = 0, + .tv_nsec = ns, + }; + struct timespec rem; + + while (nanosleep(&req, &rem) != 0) { + req.tv_sec = rem.tv_sec; + req.tv_nsec = rem.tv_nsec; + } +} + +TEST_F_TIMEOUT(rtc, date_read_loop, READ_LOOP_DURATION_SEC + 2) { + int rc; + long iter_count = 0; + struct rtc_time rtc_tm; + time_t start_rtc_read, prev_rtc_read; + + TH_LOG("Continuously reading RTC time for %ds (with %dms breaks after every read).", + READ_LOOP_DURATION_SEC, READ_LOOP_SLEEP_MS); + + rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm); + ASSERT_NE(-1, rc); + start_rtc_read = rtc_time_to_timestamp(&rtc_tm); + prev_rtc_read = start_rtc_read; + + do { + time_t rtc_read; + + rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm); + ASSERT_NE(-1, rc); + + rtc_read = rtc_time_to_timestamp(&rtc_tm); + /* Time should not go backwards */ + ASSERT_LE(prev_rtc_read, rtc_read); + /* Time should not increase more then 1s at a time */ + ASSERT_GE(prev_rtc_read + 1, rtc_read); + + /* Sleep 11ms to avoid killing / overheating the RTC */ + nanosleep_with_retries(READ_LOOP_SLEEP_MS * 1000000); + + prev_rtc_read = rtc_read; + iter_count++; + } while (prev_rtc_read <= start_rtc_read + READ_LOOP_DURATION_SEC); + + TH_LOG("Performed %ld RTC time reads.", iter_count); +} + TEST_F_TIMEOUT(rtc, uie_read, NUM_UIE + 2) { int i, rc, irq = 0; unsigned long data; diff --git a/tools/testing/selftests/rtc/settings b/tools/testing/selftests/rtc/settings index a953c96aa16e..0c1a2075d5f3 100644 --- a/tools/testing/selftests/rtc/settings +++ b/tools/testing/selftests/rtc/settings @@ -1 +1 @@ -timeout=180 +timeout=210 From 4a835afd808a3dbbac44bb399a902b822dc7445c Mon Sep 17 00:00:00 2001 From: Wen Zhiwei Date: Wed, 29 Dec 2021 10:38:14 +0800 Subject: [PATCH 077/124] mmc: dw_mmc: Fix potential null pointer risk we previously assumed 'host->slot' could be null, null pointer judgment should be added Signed-off-by: Wen Zhiwei Reviewed-by: Jaehoon Chung Link: https://lore.kernel.org/r/20211229023814.53372-1-wenzhiwei@kylinos.cn Signed-off-by: Ulf Hansson --- drivers/mmc/host/dw_mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 42bf8a2287ba..99b201921954 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3568,7 +3568,7 @@ int dw_mci_runtime_resume(struct device *dev) mci_writel(host, CTRL, SDMMC_CTRL_INT_ENABLE); - if (host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER) + if (host->slot && host->slot->mmc->pm_flags & MMC_PM_KEEP_POWER) dw_mci_set_ios(host->slot->mmc, &host->slot->mmc->ios); /* Force setup bus to guarantee available clock output */ From b59294d65ae5740e79d70c6712d91f76a667ee2e Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Wed, 12 Jan 2022 20:40:54 +0100 Subject: [PATCH 078/124] dt-bindings: mmc: sdhci-msm: Add msm8953 compatible Add msm8953 SoC specific compatible strings for qcom-sdhci controller. Signed-off-by: Luca Weiss Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20220112194118.178026-6-luca@z3ntu.xyz Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-msm.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt index 6a8cc261bf61..6216ed777343 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-msm.txt +++ b/Documentation/devicetree/bindings/mmc/sdhci-msm.txt @@ -14,6 +14,7 @@ Required properties: full compatible strings with SoC and version: "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4" "qcom,msm8226-sdhci", "qcom,sdhci-msm-v4" + "qcom,msm8953-sdhci", "qcom,sdhci-msm-v4" "qcom,msm8974-sdhci", "qcom,sdhci-msm-v4" "qcom,msm8916-sdhci", "qcom,sdhci-msm-v4" "qcom,msm8992-sdhci", "qcom,sdhci-msm-v4" From 48f6daf188ef51ee60b3dd0a38aff8cc14f14ffb Mon Sep 17 00:00:00 2001 From: Aniruddha Rao Date: Thu, 13 Jan 2022 10:46:09 +0530 Subject: [PATCH 079/124] mmc: sdhci-tegra: Enable wake on SD card event Enable GPIO wake source on SD card detect line. Physical card insertion/removal event should wake the system from suspend. Signed-off-by: Aniruddha Rao Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/1642050969-21152-1-git-send-email-anrao@nvidia.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-tegra.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 35ebba067e87..5c84bd5764ee 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -1673,6 +1673,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev) /* HW busy detection is supported, but R1B responses are required. */ host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | MMC_CAP_NEED_RSP_BUSY; + /* GPIO CD can be set as a wakeup source */ + host->mmc->caps |= MMC_CAP_CD_WAKE; + tegra_sdhci_parse_dt(host); tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power", @@ -1840,7 +1843,7 @@ static int sdhci_tegra_suspend(struct device *dev) return ret; } - return 0; + return mmc_gpio_set_cd_wake(host->mmc, true); } static int sdhci_tegra_resume(struct device *dev) @@ -1848,6 +1851,10 @@ static int sdhci_tegra_resume(struct device *dev) struct sdhci_host *host = dev_get_drvdata(dev); int ret; + ret = mmc_gpio_set_cd_wake(host->mmc, false); + if (ret) + return ret; + ret = pm_runtime_force_resume(dev); if (ret) return ret; From fc25f83a7b7164352094683c6f24a2328d3ad177 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Thu, 13 Jan 2022 12:02:58 -0500 Subject: [PATCH 080/124] MAINTAINERS: co-maintain LiteX platform Add the litex_mmc (LiteSDCard) and LiteETH drivers to the list of files maintained under LiteX. Add Gabriel Somlo and Joel Stanley as maintainers; Joel authored the LiteETH driver, and Gabriel is currently curating the LiteX out-of-tree device drivers as they are tested and prepared for upstream submission, having also co-authored a number of them. Signed-off-by: Gabriel Somlo Acked-by: Joel Stanley Acked-by: Mateusz Holenko Link: https://lore.kernel.org/r/20220113170300.3555651-2-gsomlo@gmail.com Signed-off-by: Ulf Hansson --- MAINTAINERS | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1ba1e4af2cbc..6d148c5768b6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11130,12 +11130,17 @@ F: lib/list-test.c LITEX PLATFORM M: Karol Gugala M: Mateusz Holenko +M: Gabriel Somlo +M: Joel Stanley S: Maintained F: Documentation/devicetree/bindings/*/litex,*.yaml F: arch/openrisc/boot/dts/or1klitex.dts -F: drivers/soc/litex/litex_soc_ctrl.c -F: drivers/tty/serial/liteuart.c F: include/linux/litex.h +F: drivers/tty/serial/liteuart.c +F: drivers/soc/litex/* +F: drivers/net/ethernet/litex/* +F: drivers/mmc/host/litex_mmc.c +N: litex LIVE PATCHING M: Josh Poimboeuf From 50d5d1626dac1dfda0d7e8029d0a783d9ef24f83 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Thu, 13 Jan 2022 12:02:59 -0500 Subject: [PATCH 081/124] dt-bindings: mmc: Add bindings for LiteSDCard LiteSDCard is a small footprint, configurable SDCard core for FPGA based SoCs. Signed-off-by: Gabriel Somlo Reviewed-by: Geert Uytterhoeven Reviewed-by: Rob Herring Reviewed-by: Joel Stanley Link: https://lore.kernel.org/r/20220113170300.3555651-3-gsomlo@gmail.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/litex,mmc.yaml | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Documentation/devicetree/bindings/mmc/litex,mmc.yaml diff --git a/Documentation/devicetree/bindings/mmc/litex,mmc.yaml b/Documentation/devicetree/bindings/mmc/litex,mmc.yaml new file mode 100644 index 000000000000..ef9e0da44bf8 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/litex,mmc.yaml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: GPL-2.0-or-later OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/litex,mmc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LiteX LiteSDCard device + +maintainers: + - Gabriel Somlo + +description: | + LiteSDCard is a small footprint, configurable SDCard core for FPGA based + system on chips. + + The hardware source is Open Source and can be found on at + https://github.com/enjoy-digital/litesdcard/. + +allOf: + - $ref: mmc-controller.yaml# + +properties: + compatible: + const: litex,mmc + + reg: + items: + - description: PHY registers + - description: CORE registers + - description: DMA Reader buffer + - description: DMA Writer buffer + - description: IRQ registers + minItems: 4 + + reg-names: + items: + - const: phy + - const: core + - const: reader + - const: writer + - const: irq + minItems: 4 + + clocks: + maxItems: 1 + description: + Handle to reference clock. + + vmmc-supply: + description: + Handle to fixed-voltage supply for the card power. + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - clocks + - vmmc-supply + +additionalProperties: false + +examples: + - | + mmc: mmc@12005000 { + compatible = "litex,mmc"; + reg = <0x12005000 0x100>, + <0x12003800 0x100>, + <0x12003000 0x100>, + <0x12004800 0x100>, + <0x12004000 0x100>; + reg-names = "phy", "core", "reader", "writer", "irq"; + clocks = <&reference_clk>; + vmmc-supply = <&vreg_mmc>; + interrupts = <4>; + }; From 92e099104729d7284d37bc0f49f8a9d30f3e0521 Mon Sep 17 00:00:00 2001 From: Gabriel Somlo Date: Thu, 13 Jan 2022 12:03:00 -0500 Subject: [PATCH 082/124] mmc: Add driver for LiteX's LiteSDCard interface LiteX (https://github.com/enjoy-digital/litex) is a SoC framework that targets FPGAs. LiteSDCard is a small footprint, configurable SDCard core commonly used in LiteX designs. The driver was first written in May 2020 and has been maintained cooperatively by the LiteX community. Thanks to all contributors! Co-developed-by: Kamil Rakoczy Signed-off-by: Kamil Rakoczy Co-developed-by: Maciej Dudek Signed-off-by: Maciej Dudek Co-developed-by: Paul Mackerras Signed-off-by: Paul Mackerras Signed-off-by: Gabriel Somlo Reviewed-by: Joel Stanley Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220113170300.3555651-4-gsomlo@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/Kconfig | 13 + drivers/mmc/host/Makefile | 1 + drivers/mmc/host/litex_mmc.c | 661 +++++++++++++++++++++++++++++++++++ 3 files changed, 675 insertions(+) create mode 100644 drivers/mmc/host/litex_mmc.c diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 52b0b27a6839..af6c3c329076 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -1094,3 +1094,16 @@ config MMC_OWL config MMC_SDHCI_EXTERNAL_DMA bool + +config MMC_LITEX + tristate "LiteX MMC Host Controller support" + depends on ((PPC_MICROWATT || LITEX) && OF && HAVE_CLK) || COMPILE_TEST + select REGULATOR + select REGULATOR_FIXED_VOLTAGE + help + This selects support for the MMC Host Controller found in LiteX SoCs. + + To compile this driver as a module, choose M here: the + module will be called litex_mmc. + + If unsure, say N. diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index ea36d379bd3c..4e4ceb32c4b4 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile @@ -101,6 +101,7 @@ obj-$(CONFIG_MMC_CQHCI) += cqhci.o cqhci-y += cqhci-core.o cqhci-$(CONFIG_MMC_CRYPTO) += cqhci-crypto.o obj-$(CONFIG_MMC_HSQ) += mmc_hsq.o +obj-$(CONFIG_MMC_LITEX) += litex_mmc.o ifeq ($(CONFIG_CB710_DEBUG),y) CFLAGS-cb710-mmc += -DDEBUG diff --git a/drivers/mmc/host/litex_mmc.c b/drivers/mmc/host/litex_mmc.c new file mode 100644 index 000000000000..6ba0d63b8c07 --- /dev/null +++ b/drivers/mmc/host/litex_mmc.c @@ -0,0 +1,661 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * LiteX LiteSDCard driver + * + * Copyright (C) 2019-2020 Antmicro + * Copyright (C) 2019-2020 Kamil Rakoczy + * Copyright (C) 2019-2020 Maciej Dudek + * Copyright (C) 2020 Paul Mackerras + * Copyright (C) 2020-2022 Gabriel Somlo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define LITEX_PHY_CARDDETECT 0x00 +#define LITEX_PHY_CLOCKERDIV 0x04 +#define LITEX_PHY_INITIALIZE 0x08 +#define LITEX_PHY_WRITESTATUS 0x0C +#define LITEX_CORE_CMDARG 0x00 +#define LITEX_CORE_CMDCMD 0x04 +#define LITEX_CORE_CMDSND 0x08 +#define LITEX_CORE_CMDRSP 0x0C +#define LITEX_CORE_CMDEVT 0x1C +#define LITEX_CORE_DATEVT 0x20 +#define LITEX_CORE_BLKLEN 0x24 +#define LITEX_CORE_BLKCNT 0x28 +#define LITEX_BLK2MEM_BASE 0x00 +#define LITEX_BLK2MEM_LEN 0x08 +#define LITEX_BLK2MEM_ENA 0x0C +#define LITEX_BLK2MEM_DONE 0x10 +#define LITEX_BLK2MEM_LOOP 0x14 +#define LITEX_MEM2BLK_BASE 0x00 +#define LITEX_MEM2BLK_LEN 0x08 +#define LITEX_MEM2BLK_ENA 0x0C +#define LITEX_MEM2BLK_DONE 0x10 +#define LITEX_MEM2BLK_LOOP 0x14 +#define LITEX_MEM2BLK 0x18 +#define LITEX_IRQ_STATUS 0x00 +#define LITEX_IRQ_PENDING 0x04 +#define LITEX_IRQ_ENABLE 0x08 + +#define SD_CTL_DATA_XFER_NONE 0 +#define SD_CTL_DATA_XFER_READ 1 +#define SD_CTL_DATA_XFER_WRITE 2 + +#define SD_CTL_RESP_NONE 0 +#define SD_CTL_RESP_SHORT 1 +#define SD_CTL_RESP_LONG 2 +#define SD_CTL_RESP_SHORT_BUSY 3 + +#define SD_BIT_DONE BIT(0) +#define SD_BIT_WR_ERR BIT(1) +#define SD_BIT_TIMEOUT BIT(2) +#define SD_BIT_CRC_ERR BIT(3) + +#define SD_SLEEP_US 5 +#define SD_TIMEOUT_US 20000 + +#define SDIRQ_CARD_DETECT 1 +#define SDIRQ_SD_TO_MEM_DONE 2 +#define SDIRQ_MEM_TO_SD_DONE 4 +#define SDIRQ_CMD_DONE 8 + +struct litex_mmc_host { + struct mmc_host *mmc; + + void __iomem *sdphy; + void __iomem *sdcore; + void __iomem *sdreader; + void __iomem *sdwriter; + void __iomem *sdirq; + + void *buffer; + size_t buf_size; + dma_addr_t dma; + + struct completion cmd_done; + int irq; + + unsigned int ref_clk; + unsigned int sd_clk; + + u32 resp[4]; + u16 rca; + + bool is_bus_width_set; + bool app_cmd; +}; + +static int litex_mmc_sdcard_wait_done(void __iomem *reg, struct device *dev) +{ + u8 evt; + int ret; + + ret = readx_poll_timeout(litex_read8, reg, evt, evt & SD_BIT_DONE, + SD_SLEEP_US, SD_TIMEOUT_US); + if (ret) + return ret; + if (evt == SD_BIT_DONE) + return 0; + if (evt & SD_BIT_WR_ERR) + return -EIO; + if (evt & SD_BIT_TIMEOUT) + return -ETIMEDOUT; + if (evt & SD_BIT_CRC_ERR) + return -EILSEQ; + dev_err(dev, "%s: unknown error (evt=%x)\n", __func__, evt); + return -EINVAL; +} + +static int litex_mmc_send_cmd(struct litex_mmc_host *host, + u8 cmd, u32 arg, u8 response_len, u8 transfer) +{ + struct device *dev = mmc_dev(host->mmc); + void __iomem *reg; + int ret; + u8 evt; + + litex_write32(host->sdcore + LITEX_CORE_CMDARG, arg); + litex_write32(host->sdcore + LITEX_CORE_CMDCMD, + cmd << 8 | transfer << 5 | response_len); + litex_write8(host->sdcore + LITEX_CORE_CMDSND, 1); + + /* + * Wait for an interrupt if we have an interrupt and either there is + * data to be transferred, or if the card can report busy via DAT0. + */ + if (host->irq > 0 && + (transfer != SD_CTL_DATA_XFER_NONE || + response_len == SD_CTL_RESP_SHORT_BUSY)) { + reinit_completion(&host->cmd_done); + litex_write32(host->sdirq + LITEX_IRQ_ENABLE, + SDIRQ_CMD_DONE | SDIRQ_CARD_DETECT); + wait_for_completion(&host->cmd_done); + } + + ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_CMDEVT, dev); + if (ret) { + dev_err(dev, "Command (cmd %d) error, status %d\n", cmd, ret); + return ret; + } + + if (response_len != SD_CTL_RESP_NONE) { + /* + * NOTE: this matches the semantics of litex_read32() + * regardless of underlying arch endianness! + */ + memcpy_fromio(host->resp, + host->sdcore + LITEX_CORE_CMDRSP, 0x10); + } + + if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR) + host->rca = (host->resp[3] >> 16); + + host->app_cmd = (cmd == MMC_APP_CMD); + + if (transfer == SD_CTL_DATA_XFER_NONE) + return ret; /* OK from prior litex_mmc_sdcard_wait_done() */ + + ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_DATEVT, dev); + if (ret) { + dev_err(dev, "Data xfer (cmd %d) error, status %d\n", cmd, ret); + return ret; + } + + /* Wait for completion of (read or write) DMA transfer */ + reg = (transfer == SD_CTL_DATA_XFER_READ) ? + host->sdreader + LITEX_BLK2MEM_DONE : + host->sdwriter + LITEX_MEM2BLK_DONE; + ret = readx_poll_timeout(litex_read8, reg, evt, evt & SD_BIT_DONE, + SD_SLEEP_US, SD_TIMEOUT_US); + if (ret) + dev_err(dev, "DMA timeout (cmd %d)\n", cmd); + + return ret; +} + +static int litex_mmc_send_app_cmd(struct litex_mmc_host *host) +{ + return litex_mmc_send_cmd(host, MMC_APP_CMD, host->rca << 16, + SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE); +} + +static int litex_mmc_send_set_bus_w_cmd(struct litex_mmc_host *host, u32 width) +{ + return litex_mmc_send_cmd(host, SD_APP_SET_BUS_WIDTH, width, + SD_CTL_RESP_SHORT, SD_CTL_DATA_XFER_NONE); +} + +static int litex_mmc_set_bus_width(struct litex_mmc_host *host) +{ + bool app_cmd_sent; + int ret; + + if (host->is_bus_width_set) + return 0; + + /* Ensure 'app_cmd' precedes 'app_set_bus_width_cmd' */ + app_cmd_sent = host->app_cmd; /* was preceding command app_cmd? */ + if (!app_cmd_sent) { + ret = litex_mmc_send_app_cmd(host); + if (ret) + return ret; + } + + /* LiteSDCard only supports 4-bit bus width */ + ret = litex_mmc_send_set_bus_w_cmd(host, MMC_BUS_WIDTH_4); + if (ret) + return ret; + + /* Re-send 'app_cmd' if necessary */ + if (app_cmd_sent) { + ret = litex_mmc_send_app_cmd(host); + if (ret) + return ret; + } + + host->is_bus_width_set = true; + + return 0; +} + +static int litex_mmc_get_cd(struct mmc_host *mmc) +{ + struct litex_mmc_host *host = mmc_priv(mmc); + int ret; + + if (!mmc_card_is_removable(mmc)) + return 1; + + ret = !litex_read8(host->sdphy + LITEX_PHY_CARDDETECT); + if (ret) + return ret; + + /* Ensure bus width will be set (again) upon card (re)insertion */ + host->is_bus_width_set = false; + + return 0; +} + +static irqreturn_t litex_mmc_interrupt(int irq, void *arg) +{ + struct mmc_host *mmc = arg; + struct litex_mmc_host *host = mmc_priv(mmc); + u32 pending = litex_read32(host->sdirq + LITEX_IRQ_PENDING); + irqreturn_t ret = IRQ_NONE; + + /* Check for card change interrupt */ + if (pending & SDIRQ_CARD_DETECT) { + litex_write32(host->sdirq + LITEX_IRQ_PENDING, + SDIRQ_CARD_DETECT); + mmc_detect_change(mmc, msecs_to_jiffies(10)); + ret = IRQ_HANDLED; + } + + /* Check for command completed */ + if (pending & SDIRQ_CMD_DONE) { + /* Disable it so it doesn't keep interrupting */ + litex_write32(host->sdirq + LITEX_IRQ_ENABLE, + SDIRQ_CARD_DETECT); + complete(&host->cmd_done); + ret = IRQ_HANDLED; + } + + return ret; +} + +static u32 litex_mmc_response_len(struct mmc_command *cmd) +{ + if (cmd->flags & MMC_RSP_136) + return SD_CTL_RESP_LONG; + if (!(cmd->flags & MMC_RSP_PRESENT)) + return SD_CTL_RESP_NONE; + if (cmd->flags & MMC_RSP_BUSY) + return SD_CTL_RESP_SHORT_BUSY; + return SD_CTL_RESP_SHORT; +} + +static void litex_mmc_do_dma(struct litex_mmc_host *host, struct mmc_data *data, + unsigned int *len, bool *direct, u8 *transfer) +{ + struct device *dev = mmc_dev(host->mmc); + dma_addr_t dma; + int sg_count; + + /* + * Try to DMA directly to/from the data buffer. + * We can do that if the buffer can be mapped for DMA + * in one contiguous chunk. + */ + dma = host->dma; + *len = data->blksz * data->blocks; + sg_count = dma_map_sg(dev, data->sg, data->sg_len, + mmc_get_dma_dir(data)); + if (sg_count == 1) { + dma = sg_dma_address(data->sg); + *len = sg_dma_len(data->sg); + *direct = true; + } else if (*len > host->buf_size) + *len = host->buf_size; + + if (data->flags & MMC_DATA_READ) { + litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0); + litex_write64(host->sdreader + LITEX_BLK2MEM_BASE, dma); + litex_write32(host->sdreader + LITEX_BLK2MEM_LEN, *len); + litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 1); + *transfer = SD_CTL_DATA_XFER_READ; + } else if (data->flags & MMC_DATA_WRITE) { + if (!*direct) + sg_copy_to_buffer(data->sg, data->sg_len, + host->buffer, *len); + litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0); + litex_write64(host->sdwriter + LITEX_MEM2BLK_BASE, dma); + litex_write32(host->sdwriter + LITEX_MEM2BLK_LEN, *len); + litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 1); + *transfer = SD_CTL_DATA_XFER_WRITE; + } else { + dev_warn(dev, "Data present w/o read or write flag.\n"); + /* Continue: set cmd status, mark req done */ + } + + litex_write16(host->sdcore + LITEX_CORE_BLKLEN, data->blksz); + litex_write32(host->sdcore + LITEX_CORE_BLKCNT, data->blocks); +} + +static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) +{ + struct litex_mmc_host *host = mmc_priv(mmc); + struct device *dev = mmc_dev(mmc); + struct mmc_command *cmd = mrq->cmd; + struct mmc_command *sbc = mrq->sbc; + struct mmc_data *data = mrq->data; + struct mmc_command *stop = mrq->stop; + unsigned int retries = cmd->retries; + unsigned int len = 0; + bool direct = false; + u32 response_len = litex_mmc_response_len(cmd); + u8 transfer = SD_CTL_DATA_XFER_NONE; + + /* First check that the card is still there */ + if (!litex_mmc_get_cd(mmc)) { + cmd->error = -ENOMEDIUM; + mmc_request_done(mmc, mrq); + return; + } + + /* Send set-block-count command if needed */ + if (sbc) { + sbc->error = litex_mmc_send_cmd(host, sbc->opcode, sbc->arg, + litex_mmc_response_len(sbc), + SD_CTL_DATA_XFER_NONE); + if (sbc->error) { + host->is_bus_width_set = false; + mmc_request_done(mmc, mrq); + return; + } + } + + if (data) { + /* + * LiteSDCard only supports 4-bit bus width; therefore, we MUST + * inject a SET_BUS_WIDTH (acmd6) before the very first data + * transfer, earlier than when the mmc subsystem would normally + * get around to it! + */ + cmd->error = litex_mmc_set_bus_width(host); + if (cmd->error) { + dev_err(dev, "Can't set bus width!\n"); + mmc_request_done(mmc, mrq); + return; + } + + litex_mmc_do_dma(host, data, &len, &direct, &transfer); + } + + do { + cmd->error = litex_mmc_send_cmd(host, cmd->opcode, cmd->arg, + response_len, transfer); + } while (cmd->error && retries-- > 0); + + if (cmd->error) { + /* Card may be gone; don't assume bus width is still set */ + host->is_bus_width_set = false; + } + + if (response_len == SD_CTL_RESP_SHORT) { + /* Pull short response fields from appropriate host registers */ + cmd->resp[0] = host->resp[3]; + cmd->resp[1] = host->resp[2] & 0xFF; + } else if (response_len == SD_CTL_RESP_LONG) { + cmd->resp[0] = host->resp[0]; + cmd->resp[1] = host->resp[1]; + cmd->resp[2] = host->resp[2]; + cmd->resp[3] = host->resp[3]; + } + + /* Send stop-transmission command if required */ + if (stop && (cmd->error || !sbc)) { + stop->error = litex_mmc_send_cmd(host, stop->opcode, stop->arg, + litex_mmc_response_len(stop), + SD_CTL_DATA_XFER_NONE); + if (stop->error) + host->is_bus_width_set = false; + } + + if (data) { + dma_unmap_sg(dev, data->sg, data->sg_len, + mmc_get_dma_dir(data)); + } + + if (!cmd->error && transfer != SD_CTL_DATA_XFER_NONE) { + data->bytes_xfered = min(len, mmc->max_req_size); + if (transfer == SD_CTL_DATA_XFER_READ && !direct) { + sg_copy_from_buffer(data->sg, sg_nents(data->sg), + host->buffer, data->bytes_xfered); + } + } + + mmc_request_done(mmc, mrq); +} + +static void litex_mmc_setclk(struct litex_mmc_host *host, unsigned int freq) +{ + struct device *dev = mmc_dev(host->mmc); + u32 div; + + div = freq ? host->ref_clk / freq : 256U; + div = roundup_pow_of_two(div); + div = clamp(div, 2U, 256U); + dev_dbg(dev, "sd_clk_freq=%d: set to %d via div=%d\n", + freq, host->ref_clk / div, div); + litex_write16(host->sdphy + LITEX_PHY_CLOCKERDIV, div); + host->sd_clk = freq; +} + +static void litex_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) +{ + struct litex_mmc_host *host = mmc_priv(mmc); + + /* + * NOTE: Ignore any ios->bus_width updates; they occur right after + * the mmc core sends its own acmd6 bus-width change notification, + * which is redundant since we snoop on the command flow and inject + * an early acmd6 before the first data transfer command is sent! + */ + + /* Update sd_clk */ + if (ios->clock != host->sd_clk) + litex_mmc_setclk(host, ios->clock); +} + +static const struct mmc_host_ops litex_mmc_ops = { + .get_cd = litex_mmc_get_cd, + .request = litex_mmc_request, + .set_ios = litex_mmc_set_ios, +}; + +static int litex_mmc_irq_init(struct platform_device *pdev, + struct litex_mmc_host *host) +{ + struct device *dev = mmc_dev(host->mmc); + int ret; + + ret = platform_get_irq_optional(pdev, 0); + if (ret < 0 && ret != -ENXIO) + return ret; + if (ret > 0) + host->irq = ret; + else { + dev_warn(dev, "Failed to get IRQ, using polling\n"); + goto use_polling; + } + + host->sdirq = devm_platform_ioremap_resource_byname(pdev, "irq"); + if (IS_ERR(host->sdirq)) + return PTR_ERR(host->sdirq); + + ret = devm_request_irq(dev, host->irq, litex_mmc_interrupt, 0, + "litex-mmc", host->mmc); + if (ret < 0) { + dev_warn(dev, "IRQ request error %d, using polling\n", ret); + goto use_polling; + } + + /* Clear & enable card-change interrupts */ + litex_write32(host->sdirq + LITEX_IRQ_PENDING, SDIRQ_CARD_DETECT); + litex_write32(host->sdirq + LITEX_IRQ_ENABLE, SDIRQ_CARD_DETECT); + + return 0; + +use_polling: + host->mmc->caps |= MMC_CAP_NEEDS_POLL; + return 0; +} + +static void litex_mmc_free_host_wrapper(void *mmc) +{ + mmc_free_host(mmc); +} + +static int litex_mmc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct litex_mmc_host *host; + struct mmc_host *mmc; + struct clk *clk; + int ret; + + /* + * NOTE: defaults to max_[req,seg]_size=PAGE_SIZE, max_blk_size=512, + * and max_blk_count accordingly set to 8; + * If for some reason we need to modify max_blk_count, we must also + * re-calculate `max_[req,seg]_size = max_blk_size * max_blk_count;` + */ + mmc = mmc_alloc_host(sizeof(struct litex_mmc_host), dev); + if (!mmc) + return -ENOMEM; + + ret = devm_add_action_or_reset(dev, litex_mmc_free_host_wrapper, mmc); + if (ret) + return dev_err_probe(dev, ret, + "Can't register mmc_free_host action\n"); + + host = mmc_priv(mmc); + host->mmc = mmc; + + /* Initialize clock source */ + clk = devm_clk_get(dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "can't get clock\n"); + host->ref_clk = clk_get_rate(clk); + host->sd_clk = 0; + + /* + * LiteSDCard only supports 4-bit bus width; therefore, we MUST inject + * a SET_BUS_WIDTH (acmd6) before the very first data transfer, earlier + * than when the mmc subsystem would normally get around to it! + */ + host->is_bus_width_set = false; + host->app_cmd = false; + + /* LiteSDCard can support 64-bit DMA addressing */ + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); + if (ret) + return ret; + + host->buf_size = mmc->max_req_size * 2; + host->buffer = dmam_alloc_coherent(dev, host->buf_size, + &host->dma, GFP_KERNEL); + if (host->buffer == NULL) + return -ENOMEM; + + host->sdphy = devm_platform_ioremap_resource_byname(pdev, "phy"); + if (IS_ERR(host->sdphy)) + return PTR_ERR(host->sdphy); + + host->sdcore = devm_platform_ioremap_resource_byname(pdev, "core"); + if (IS_ERR(host->sdcore)) + return PTR_ERR(host->sdcore); + + host->sdreader = devm_platform_ioremap_resource_byname(pdev, "reader"); + if (IS_ERR(host->sdreader)) + return PTR_ERR(host->sdreader); + + host->sdwriter = devm_platform_ioremap_resource_byname(pdev, "writer"); + if (IS_ERR(host->sdwriter)) + return PTR_ERR(host->sdwriter); + + /* Ensure DMA bus masters are disabled */ + litex_write8(host->sdreader + LITEX_BLK2MEM_ENA, 0); + litex_write8(host->sdwriter + LITEX_MEM2BLK_ENA, 0); + + init_completion(&host->cmd_done); + ret = litex_mmc_irq_init(pdev, host); + if (ret) + return ret; + + mmc->ops = &litex_mmc_ops; + + ret = mmc_regulator_get_supply(mmc); + if (ret || mmc->ocr_avail == 0) { + dev_warn(dev, "can't get voltage, defaulting to 3.3V\n"); + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; + } + + /* + * Set default sd_clk frequency range based on empirical observations + * of LiteSDCard gateware behavior on typical SDCard media + */ + mmc->f_min = 12.5e6; + mmc->f_max = 50e6; + + ret = mmc_of_parse(mmc); + if (ret) + return ret; + + /* Force 4-bit bus_width (only width supported by hardware) */ + mmc->caps &= ~MMC_CAP_8_BIT_DATA; + mmc->caps |= MMC_CAP_4_BIT_DATA; + + /* Set default capabilities */ + mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY | + MMC_CAP_DRIVER_TYPE_D | + MMC_CAP_CMD23; + mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT | + MMC_CAP2_NO_SDIO | + MMC_CAP2_NO_MMC; + + platform_set_drvdata(pdev, host); + + ret = mmc_add_host(mmc); + if (ret) + return ret; + + dev_info(dev, "LiteX MMC controller initialized.\n"); + return 0; +} + +static int litex_mmc_remove(struct platform_device *pdev) +{ + struct litex_mmc_host *host = platform_get_drvdata(pdev); + + mmc_remove_host(host->mmc); + return 0; +} + +static const struct of_device_id litex_match[] = { + { .compatible = "litex,mmc" }, + { } +}; +MODULE_DEVICE_TABLE(of, litex_match); + +static struct platform_driver litex_mmc_driver = { + .probe = litex_mmc_probe, + .remove = litex_mmc_remove, + .driver = { + .name = "litex-mmc", + .of_match_table = litex_match, + }, +}; +module_platform_driver(litex_mmc_driver); + +MODULE_DESCRIPTION("LiteX SDCard driver"); +MODULE_AUTHOR("Antmicro "); +MODULE_AUTHOR("Kamil Rakoczy "); +MODULE_AUTHOR("Maciej Dudek "); +MODULE_AUTHOR("Paul Mackerras "); +MODULE_AUTHOR("Gabriel Somlo "); +MODULE_LICENSE("GPL v2"); From d0ba932a9aca90e87181ddda3fabec03778a28a2 Mon Sep 17 00:00:00 2001 From: Ben Chuang Date: Wed, 19 Jan 2022 15:53:06 +0800 Subject: [PATCH 083/124] mmc: sdhci-pci-gli: Reduce the SSC value at 205MHz for GL9750 and GL9755 The SSC value is 0xFFE7 at 205MHz and may be saturated. Reduce the SSC value to 0x5A1D at 205MHz to reduce this situation for GL9750 and GL9755. Signed-off-by: Ben Chuang Link: https://lore.kernel.org/r/20220119075306.36262-1-benchuanggli@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pci-gli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index 97035d77c18c..dcd304385529 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -393,7 +393,7 @@ static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm) static void gl9750_set_ssc_pll_205mhz(struct sdhci_host *host) { /* set pll to 205MHz and enable ssc */ - gl9750_set_ssc(host, 0x1, 0x1F, 0xFFE7); + gl9750_set_ssc(host, 0x1, 0xF, 0x5A1D); gl9750_set_pll(host, 0x1, 0x246, 0x0); } @@ -536,7 +536,7 @@ static void gl9755_set_ssc(struct pci_dev *pdev, u8 enable, u8 step, u16 ppm) static void gl9755_set_ssc_pll_205mhz(struct pci_dev *pdev) { /* set pll to 205MHz and enable ssc */ - gl9755_set_ssc(pdev, 0x1, 0x1F, 0xFFE7); + gl9755_set_ssc(pdev, 0x1, 0xF, 0x5A1D); gl9755_set_pll(pdev, 0x1, 0x246, 0x0); } From d3c6bdb656d452096c9fb3ad4c91ad627a032cd1 Mon Sep 17 00:00:00 2001 From: Ben Chuang Date: Wed, 19 Jan 2022 15:53:39 +0800 Subject: [PATCH 084/124] mmc: sdhci-pci-gli: Enable SSC at 50MHz and 100MHz for GL9750 and GL9755 Enable SSC function at 50MHz and 100MHz for GL9750 and GL9755. Signed-off-by: Ben Chuang Link: https://lore.kernel.org/r/20220119075339.36281-1-benchuanggli@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pci-gli.c | 36 ++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index dcd304385529..fd7a6afc1d8b 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -397,6 +397,20 @@ static void gl9750_set_ssc_pll_205mhz(struct sdhci_host *host) gl9750_set_pll(host, 0x1, 0x246, 0x0); } +static void gl9750_set_ssc_pll_100mhz(struct sdhci_host *host) +{ + /* set pll to 100MHz and enable ssc */ + gl9750_set_ssc(host, 0x1, 0xE, 0x51EC); + gl9750_set_pll(host, 0x1, 0x244, 0x1); +} + +static void gl9750_set_ssc_pll_50mhz(struct sdhci_host *host) +{ + /* set pll to 50MHz and enable ssc */ + gl9750_set_ssc(host, 0x1, 0xE, 0x51EC); + gl9750_set_pll(host, 0x1, 0x244, 0x3); +} + static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock) { struct mmc_ios *ios = &host->mmc->ios; @@ -414,6 +428,10 @@ static void sdhci_gl9750_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) { host->mmc->actual_clock = 205000000; gl9750_set_ssc_pll_205mhz(host); + } else if (clock == 100000000) { + gl9750_set_ssc_pll_100mhz(host); + } else if (clock == 50000000) { + gl9750_set_ssc_pll_50mhz(host); } sdhci_enable_clk(host, clk); @@ -540,6 +558,20 @@ static void gl9755_set_ssc_pll_205mhz(struct pci_dev *pdev) gl9755_set_pll(pdev, 0x1, 0x246, 0x0); } +static void gl9755_set_ssc_pll_100mhz(struct pci_dev *pdev) +{ + /* set pll to 100MHz and enable ssc */ + gl9755_set_ssc(pdev, 0x1, 0xE, 0x51EC); + gl9755_set_pll(pdev, 0x1, 0x244, 0x1); +} + +static void gl9755_set_ssc_pll_50mhz(struct pci_dev *pdev) +{ + /* set pll to 50MHz and enable ssc */ + gl9755_set_ssc(pdev, 0x1, 0xE, 0x51EC); + gl9755_set_pll(pdev, 0x1, 0x244, 0x3); +} + static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock) { struct sdhci_pci_slot *slot = sdhci_priv(host); @@ -560,6 +592,10 @@ static void sdhci_gl9755_set_clock(struct sdhci_host *host, unsigned int clock) if (clock == 200000000 && ios->timing == MMC_TIMING_UHS_SDR104) { host->mmc->actual_clock = 205000000; gl9755_set_ssc_pll_205mhz(pdev); + } else if (clock == 100000000) { + gl9755_set_ssc_pll_100mhz(pdev); + } else if (clock == 50000000) { + gl9755_set_ssc_pll_50mhz(pdev); } sdhci_enable_clk(host, clk); From 08df1a5021d05f82aca24f6a00beee3a8f68f264 Mon Sep 17 00:00:00 2001 From: Ben Chuang Date: Wed, 19 Jan 2022 15:54:06 +0800 Subject: [PATCH 085/124] mmc: sdhci-pci-gli: Add a switch to enable/disable SSC for GL9750 and GL9755 Add a vendor-specific bit at the bit26 of GL9750's register 878h and GL9755's register 78h to decide whether to disable SSC function. If this bit is set, the SSC function will be disabled. Signed-off-by: Ben Chuang Link: https://lore.kernel.org/r/20220119075406.36321-1-benchuanggli@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pci-gli.c | 66 ++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index fd7a6afc1d8b..ab099cdb081c 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -63,6 +63,7 @@ #define GLI_9750_MISC_RX_INV_OFF 0x0 #define GLI_9750_MISC_RX_INV_VALUE GLI_9750_MISC_RX_INV_OFF #define GLI_9750_MISC_TX1_DLY_VALUE 0x5 +#define SDHCI_GLI_9750_MISC_SSC_OFF BIT(26) #define SDHCI_GLI_9750_TUNING_CONTROL 0x540 #define SDHCI_GLI_9750_TUNING_CONTROL_EN BIT(4) @@ -137,6 +138,9 @@ #define PCI_GLI_9755_SerDes 0x70 #define PCI_GLI_9755_SCP_DIS BIT(19) +#define PCI_GLI_9755_MISC 0x78 +#define PCI_GLI_9755_MISC_SSC_OFF BIT(26) + #define GLI_MAX_TUNING_LOOP 40 /* Genesys Logic chipset */ @@ -371,6 +375,19 @@ static void gl9750_set_pll(struct sdhci_host *host, u8 dir, u16 ldiv, u8 pdiv) mdelay(1); } +static bool gl9750_ssc_enable(struct sdhci_host *host) +{ + u32 misc; + u8 off; + + gl9750_wt_on(host); + misc = sdhci_readl(host, SDHCI_GLI_9750_MISC); + off = FIELD_GET(SDHCI_GLI_9750_MISC_SSC_OFF, misc); + gl9750_wt_off(host); + + return !off; +} + static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm) { u32 pll; @@ -392,22 +409,28 @@ static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm) static void gl9750_set_ssc_pll_205mhz(struct sdhci_host *host) { - /* set pll to 205MHz and enable ssc */ - gl9750_set_ssc(host, 0x1, 0xF, 0x5A1D); + bool enable = gl9750_ssc_enable(host); + + /* set pll to 205MHz and ssc */ + gl9750_set_ssc(host, enable, 0xF, 0x5A1D); gl9750_set_pll(host, 0x1, 0x246, 0x0); } static void gl9750_set_ssc_pll_100mhz(struct sdhci_host *host) { - /* set pll to 100MHz and enable ssc */ - gl9750_set_ssc(host, 0x1, 0xE, 0x51EC); + bool enable = gl9750_ssc_enable(host); + + /* set pll to 100MHz and ssc */ + gl9750_set_ssc(host, enable, 0xE, 0x51EC); gl9750_set_pll(host, 0x1, 0x244, 0x1); } static void gl9750_set_ssc_pll_50mhz(struct sdhci_host *host) { - /* set pll to 50MHz and enable ssc */ - gl9750_set_ssc(host, 0x1, 0xE, 0x51EC); + bool enable = gl9750_ssc_enable(host); + + /* set pll to 50MHz and ssc */ + gl9750_set_ssc(host, enable, 0xE, 0x51EC); gl9750_set_pll(host, 0x1, 0x244, 0x3); } @@ -532,6 +555,19 @@ static void gl9755_set_pll(struct pci_dev *pdev, u8 dir, u16 ldiv, u8 pdiv) mdelay(1); } +static bool gl9755_ssc_enable(struct pci_dev *pdev) +{ + u32 misc; + u8 off; + + gl9755_wt_on(pdev); + pci_read_config_dword(pdev, PCI_GLI_9755_MISC, &misc); + off = FIELD_GET(PCI_GLI_9755_MISC_SSC_OFF, misc); + gl9755_wt_off(pdev); + + return !off; +} + static void gl9755_set_ssc(struct pci_dev *pdev, u8 enable, u8 step, u16 ppm) { u32 pll; @@ -553,22 +589,28 @@ static void gl9755_set_ssc(struct pci_dev *pdev, u8 enable, u8 step, u16 ppm) static void gl9755_set_ssc_pll_205mhz(struct pci_dev *pdev) { - /* set pll to 205MHz and enable ssc */ - gl9755_set_ssc(pdev, 0x1, 0xF, 0x5A1D); + bool enable = gl9755_ssc_enable(pdev); + + /* set pll to 205MHz and ssc */ + gl9755_set_ssc(pdev, enable, 0xF, 0x5A1D); gl9755_set_pll(pdev, 0x1, 0x246, 0x0); } static void gl9755_set_ssc_pll_100mhz(struct pci_dev *pdev) { - /* set pll to 100MHz and enable ssc */ - gl9755_set_ssc(pdev, 0x1, 0xE, 0x51EC); + bool enable = gl9755_ssc_enable(pdev); + + /* set pll to 100MHz and ssc */ + gl9755_set_ssc(pdev, enable, 0xE, 0x51EC); gl9755_set_pll(pdev, 0x1, 0x244, 0x1); } static void gl9755_set_ssc_pll_50mhz(struct pci_dev *pdev) { - /* set pll to 50MHz and enable ssc */ - gl9755_set_ssc(pdev, 0x1, 0xE, 0x51EC); + bool enable = gl9755_ssc_enable(pdev); + + /* set pll to 50MHz and ssc */ + gl9755_set_ssc(pdev, enable, 0xE, 0x51EC); gl9755_set_pll(pdev, 0x1, 0x244, 0x3); } From 43a6a11aaf875bc2567c2d0d930d59d022ee8e68 Mon Sep 17 00:00:00 2001 From: Allen-KH Cheng Date: Fri, 28 Jan 2022 14:20:47 +0800 Subject: [PATCH 086/124] dt-bindings: mmc: Add compatible for Mediatek MT8186 This commit adds dt-binding documentation of mmc for Mediatek MT8186 SoC Platform. Signed-off-by: Allen-KH Cheng Link: https://lore.kernel.org/r/20220128062050.23978-5-allen-kh.cheng@mediatek.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/mtk-sd.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml index faf89b0c918f..297ada03e3de 100644 --- a/Documentation/devicetree/bindings/mmc/mtk-sd.yaml +++ b/Documentation/devicetree/bindings/mmc/mtk-sd.yaml @@ -29,6 +29,9 @@ properties: - items: - const: mediatek,mt7623-mmc - const: mediatek,mt2701-mmc + - items: + - const: mediatek,mt8186-mmc + - const: mediatek,mt8183-mmc - items: - const: mediatek,mt8192-mmc - const: mediatek,mt8183-mmc From 1b3eebf17c028d2f083ded6ca84ff8576f199ec4 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 2 Feb 2022 19:06:44 +0100 Subject: [PATCH 087/124] mmc: wmt-sdmmc: Use of_device_get_match_data() helper Only the device data is needed, not the whole struct of_device_id. Use of_device_get_match_data() instead of open coding of of_match_device(). Signed-off-by: Bean Huo Link: https://lore.kernel.org/r/20220202180648.1252154-2-huobean@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/wmt-sdmmc.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/mmc/host/wmt-sdmmc.c b/drivers/mmc/host/wmt-sdmmc.c index cf10949fb0ac..163ac9df8cca 100644 --- a/drivers/mmc/host/wmt-sdmmc.c +++ b/drivers/mmc/host/wmt-sdmmc.c @@ -751,19 +751,16 @@ static int wmt_mci_probe(struct platform_device *pdev) struct mmc_host *mmc; struct wmt_mci_priv *priv; struct device_node *np = pdev->dev.of_node; - const struct of_device_id *of_id = - of_match_device(wmt_mci_dt_ids, &pdev->dev); const struct wmt_mci_caps *wmt_caps; int ret; int regular_irq, dma_irq; - if (!of_id || !of_id->data) { + wmt_caps = of_device_get_match_data(&pdev->dev); + if (!wmt_caps) { dev_err(&pdev->dev, "Controller capabilities data missing\n"); return -EFAULT; } - wmt_caps = of_id->data; - if (!np) { dev_err(&pdev->dev, "Missing SDMMC description in devicetree\n"); return -EFAULT; From dfbaaec99351fd840ea2572a1adb0294a098f0bb Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 2 Feb 2022 19:06:45 +0100 Subject: [PATCH 088/124] mmc: sdhci-tegra: Use of_device_get_match_data() helper Only the device data is needed,not the whole struct of_device_id. Use of_device_get_match_data() instead of open coding of of_match_device(). Signed-off-by: Bean Huo Link: https://lore.kernel.org/r/20220202180648.1252154-3-huobean@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-tegra.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 5c84bd5764ee..2d2d8260c681 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -1618,7 +1618,6 @@ cleanup: static int sdhci_tegra_probe(struct platform_device *pdev) { - const struct of_device_id *match; const struct sdhci_tegra_soc_data *soc_data; struct sdhci_host *host; struct sdhci_pltfm_host *pltfm_host; @@ -1626,10 +1625,9 @@ static int sdhci_tegra_probe(struct platform_device *pdev) struct clk *clk; int rc; - match = of_match_device(sdhci_tegra_dt_match, &pdev->dev); - if (!match) + soc_data = of_device_get_match_data(&pdev->dev); + if (!soc_data) return -EINVAL; - soc_data = match->data; host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host)); if (IS_ERR(host)) From 685e013bef794561cc9c4bed6fefd4d6f2f67d39 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 2 Feb 2022 19:06:47 +0100 Subject: [PATCH 089/124] mmc: sdhci-of-at91: Use of_device_get_match_data() helper Only the device data is needed, not the entire struct of_device_id. Use of_device_get_match_data() instead of open coding of_match_device(). Signed-off-by: Bean Huo Link: https://lore.kernel.org/r/20220202180648.1252154-5-huobean@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-of-at91.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c index d1a1c548c515..10fb4cb2c731 100644 --- a/drivers/mmc/host/sdhci-of-at91.c +++ b/drivers/mmc/host/sdhci-of-at91.c @@ -308,17 +308,15 @@ static const struct dev_pm_ops sdhci_at91_dev_pm_ops = { static int sdhci_at91_probe(struct platform_device *pdev) { - const struct of_device_id *match; const struct sdhci_at91_soc_data *soc_data; struct sdhci_host *host; struct sdhci_pltfm_host *pltfm_host; struct sdhci_at91_priv *priv; int ret; - match = of_match_device(sdhci_at91_dt_match, &pdev->dev); - if (!match) + soc_data = of_device_get_match_data(&pdev->dev); + if (!soc_data) return -EINVAL; - soc_data = match->data; host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*priv)); if (IS_ERR(host)) From a25ebe4e59a333c881621b8caf653e56a757c9b6 Mon Sep 17 00:00:00 2001 From: Bean Huo Date: Wed, 2 Feb 2022 19:06:48 +0100 Subject: [PATCH 090/124] mmc: davinci: Use of_device_get_match_data() helper Only the device data is needed, not the entire struct of_device_id. Use of_device_get_match_data() instead of of_match_device(). Signed-off-by: Bean Huo Link: https://lore.kernel.org/r/20220202180648.1252154-6-huobean@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/davinci_mmc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 2a757c88f9d2..0cf646ec9a80 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1189,7 +1189,6 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc) static int davinci_mmcsd_probe(struct platform_device *pdev) { - const struct of_device_id *match; struct mmc_davinci_host *host = NULL; struct mmc_host *mmc = NULL; struct resource *r, *mem = NULL; @@ -1235,9 +1234,8 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) host->mmc_input_clk = clk_get_rate(host->clk); - match = of_match_device(davinci_mmc_dt_ids, &pdev->dev); - if (match) { - pdev->id_entry = match->data; + pdev->id_entry = of_device_get_match_data(&pdev->dev); + if (pdev->id_entry) { ret = mmc_of_parse(mmc); if (ret) { dev_err_probe(&pdev->dev, ret, From 43fa33aaf050f36867b018f2fd50aea26a6a1729 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 2 Feb 2022 20:24:50 +0200 Subject: [PATCH 091/124] mmc: dw_mmc: Use device_property_string_array_count() Use device_property_string_array_count() to get number of strings in a string array property. Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20220202182450.54925-1-andriy.shevchenko@linux.intel.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/dw_mmc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 99b201921954..3420a7ad6098 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -3057,8 +3057,7 @@ static void dw_mci_init_dma(struct dw_mci *host) dev_info(host->dev, "Using internal DMA controller.\n"); } else { /* TRANS_MODE_EDMAC: check dma bindings again */ - if ((device_property_read_string_array(dev, "dma-names", - NULL, 0) < 0) || + if ((device_property_string_array_count(dev, "dma-names") < 0) || !device_property_present(dev, "dmas")) { goto no_dma; } From 02d9c3f436d6ad9ec086d11130be3d22927f457d Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 2 Feb 2022 19:51:10 -0600 Subject: [PATCH 092/124] dt-bindings: mmc: sunxi: Add D1 MMC and eMMC compatibles D1 contains variants of the usual sunxi MMC controller. The eMMC controller has the same parameters as the A100 eMMC controller. The other controllers have a DMA address shift like on A100, but they have a smaller 13-bit size field, making them a new incompatible variant. Signed-off-by: Samuel Holland Acked-by: Maxime Ripard Link: https://lore.kernel.org/r/20220203015112.12008-1-samuel@sholland.org Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml index 4f62ad6ce50c..94e2c6c4e4b7 100644 --- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml +++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml @@ -24,6 +24,7 @@ properties: - const: allwinner,sun7i-a20-mmc - const: allwinner,sun8i-a83t-emmc - const: allwinner,sun9i-a80-mmc + - const: allwinner,sun20i-d1-mmc - const: allwinner,sun50i-a64-emmc - const: allwinner,sun50i-a64-mmc - const: allwinner,sun50i-a100-emmc @@ -49,6 +50,9 @@ properties: - items: - const: allwinner,sun50i-h6-mmc - const: allwinner,sun50i-a64-mmc + - items: + - const: allwinner,sun20i-d1-emmc + - const: allwinner,sun50i-a100-emmc - items: - const: allwinner,sun50i-h616-emmc - const: allwinner,sun50i-a100-emmc From 75a2f412d0aed4a4a80ab2a2d96d040b17acb6d6 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 2 Feb 2022 19:51:11 -0600 Subject: [PATCH 093/124] mmc: sunxi-mmc: Add D1 MMC variant D1's MMC controllers are unique in that they have the DMA address shift (like A100) with a 13-bit descriptor size field (like sun4i). Add the compatible and parameters for this new variant. Signed-off-by: Samuel Holland Acked-by: Maxime Ripard Link: https://lore.kernel.org/r/20220203015112.12008-2-samuel@sholland.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sunxi-mmc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index 2702736a1c57..c62afd212692 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -1167,6 +1167,14 @@ static const struct sunxi_mmc_cfg sun9i_a80_cfg = { .can_calibrate = false, }; +static const struct sunxi_mmc_cfg sun20i_d1_cfg = { + .idma_des_size_bits = 13, + .idma_des_shift = 2, + .can_calibrate = true, + .mask_data0 = true, + .needs_new_timings = true, +}; + static const struct sunxi_mmc_cfg sun50i_a64_cfg = { .idma_des_size_bits = 16, .clk_delays = NULL, @@ -1205,6 +1213,7 @@ static const struct of_device_id sunxi_mmc_of_match[] = { { .compatible = "allwinner,sun7i-a20-mmc", .data = &sun7i_a20_cfg }, { .compatible = "allwinner,sun8i-a83t-emmc", .data = &sun8i_a83t_emmc_cfg }, { .compatible = "allwinner,sun9i-a80-mmc", .data = &sun9i_a80_cfg }, + { .compatible = "allwinner,sun20i-d1-mmc", .data = &sun20i_d1_cfg }, { .compatible = "allwinner,sun50i-a64-mmc", .data = &sun50i_a64_cfg }, { .compatible = "allwinner,sun50i-a64-emmc", .data = &sun50i_a64_emmc_cfg }, { .compatible = "allwinner,sun50i-a100-mmc", .data = &sun50i_a100_cfg }, From f5d8a5fe77ce933f53eb8f2e22bb7a1a2019ea11 Mon Sep 17 00:00:00 2001 From: Sergey Shtylyov Date: Tue, 8 Feb 2022 15:02:15 +0300 Subject: [PATCH 094/124] mmc: core: use sysfs_emit() instead of sprintf() sprintf() (still used in the MMC core for the sysfs output) is vulnerable to the buffer overflow. Use the new-fangled sysfs_emit() instead. Found by Linux Verification Center (linuxtesting.org) with the SVACE static analysis tool. Signed-off-by: Sergey Shtylyov Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/717729b2-d65b-c72e-9fac-471d28d00b5a@omp.ru Signed-off-by: Ulf Hansson --- drivers/mmc/core/bus.c | 9 +++++---- drivers/mmc/core/bus.h | 3 ++- drivers/mmc/core/mmc.c | 16 ++++++++-------- drivers/mmc/core/sd.c | 23 +++++++++++------------ drivers/mmc/core/sdio.c | 5 +++-- drivers/mmc/core/sdio_bus.c | 7 ++++--- 6 files changed, 33 insertions(+), 30 deletions(-) diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 096ae624be9a..58a60afa650b 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -34,13 +35,13 @@ static ssize_t type_show(struct device *dev, switch (card->type) { case MMC_TYPE_MMC: - return sprintf(buf, "MMC\n"); + return sysfs_emit(buf, "MMC\n"); case MMC_TYPE_SD: - return sprintf(buf, "SD\n"); + return sysfs_emit(buf, "SD\n"); case MMC_TYPE_SDIO: - return sprintf(buf, "SDIO\n"); + return sysfs_emit(buf, "SDIO\n"); case MMC_TYPE_SD_COMBO: - return sprintf(buf, "SDcombo\n"); + return sysfs_emit(buf, "SDcombo\n"); default: return -EFAULT; } diff --git a/drivers/mmc/core/bus.h b/drivers/mmc/core/bus.h index 8105852c4b62..3996b191b68d 100644 --- a/drivers/mmc/core/bus.h +++ b/drivers/mmc/core/bus.h @@ -9,6 +9,7 @@ #define _MMC_CORE_BUS_H #include +#include struct mmc_host; struct mmc_card; @@ -17,7 +18,7 @@ struct mmc_card; static ssize_t mmc_##name##_show (struct device *dev, struct device_attribute *attr, char *buf) \ { \ struct mmc_card *card = mmc_dev_to_card(dev); \ - return sprintf(buf, fmt, args); \ + return sysfs_emit(buf, fmt, args); \ } \ static DEVICE_ATTR(name, S_IRUGO, mmc_##name##_show, NULL) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index bbbbcaf70a59..13abfcd130a5 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -812,12 +813,11 @@ static ssize_t mmc_fwrev_show(struct device *dev, { struct mmc_card *card = mmc_dev_to_card(dev); - if (card->ext_csd.rev < 7) { - return sprintf(buf, "0x%x\n", card->cid.fwrev); - } else { - return sprintf(buf, "0x%*phN\n", MMC_FIRMWARE_LEN, - card->ext_csd.fwrev); - } + if (card->ext_csd.rev < 7) + return sysfs_emit(buf, "0x%x\n", card->cid.fwrev); + else + return sysfs_emit(buf, "0x%*phN\n", MMC_FIRMWARE_LEN, + card->ext_csd.fwrev); } static DEVICE_ATTR(fwrev, S_IRUGO, mmc_fwrev_show, NULL); @@ -830,10 +830,10 @@ static ssize_t mmc_dsr_show(struct device *dev, struct mmc_host *host = card->host; if (card->csd.dsr_imp && host->dsr_req) - return sprintf(buf, "0x%x\n", host->dsr); + return sysfs_emit(buf, "0x%x\n", host->dsr); else /* return default DSR value */ - return sprintf(buf, "0x%x\n", 0x404); + return sysfs_emit(buf, "0x%x\n", 0x404); } static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL); diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index bd87012c220c..24b0418a24bb 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -708,18 +709,16 @@ MMC_DEV_ATTR(ocr, "0x%08x\n", card->ocr); MMC_DEV_ATTR(rca, "0x%04x\n", card->rca); -static ssize_t mmc_dsr_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t mmc_dsr_show(struct device *dev, struct device_attribute *attr, + char *buf) { - struct mmc_card *card = mmc_dev_to_card(dev); - struct mmc_host *host = card->host; + struct mmc_card *card = mmc_dev_to_card(dev); + struct mmc_host *host = card->host; - if (card->csd.dsr_imp && host->dsr_req) - return sprintf(buf, "0x%x\n", host->dsr); - else - /* return default DSR value */ - return sprintf(buf, "0x%x\n", 0x404); + if (card->csd.dsr_imp && host->dsr_req) + return sysfs_emit(buf, "0x%x\n", host->dsr); + /* return default DSR value */ + return sysfs_emit(buf, "0x%x\n", 0x404); } static DEVICE_ATTR(dsr, S_IRUGO, mmc_dsr_show, NULL); @@ -735,9 +734,9 @@ static ssize_t info##num##_show(struct device *dev, struct device_attribute *att \ if (num > card->num_info) \ return -ENODATA; \ - if (!card->info[num-1][0]) \ + if (!card->info[num - 1][0]) \ return 0; \ - return sprintf(buf, "%s\n", card->info[num-1]); \ + return sysfs_emit(buf, "%s\n", card->info[num - 1]); \ } \ static DEVICE_ATTR_RO(info##num) diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 41164748723d..25799accf8a0 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -40,9 +41,9 @@ static ssize_t info##num##_show(struct device *dev, struct device_attribute *att \ if (num > card->num_info) \ return -ENODATA; \ - if (!card->info[num-1][0]) \ + if (!card->info[num - 1][0]) \ return 0; \ - return sprintf(buf, "%s\n", card->info[num-1]); \ + return sysfs_emit(buf, "%s\n", card->info[num - 1]); \ } \ static DEVICE_ATTR_RO(info##num) diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index fda03b35c14a..c6268c38c69e 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ field##_show(struct device *dev, struct device_attribute *attr, char *buf) \ struct sdio_func *func; \ \ func = dev_to_sdio_func (dev); \ - return sprintf(buf, format_string, args); \ + return sysfs_emit(buf, format_string, args); \ } \ static DEVICE_ATTR_RO(field) @@ -52,9 +53,9 @@ static ssize_t info##num##_show(struct device *dev, struct device_attribute *att \ if (num > func->num_info) \ return -ENODATA; \ - if (!func->info[num-1][0]) \ + if (!func->info[num - 1][0]) \ return 0; \ - return sprintf(buf, "%s\n", func->info[num-1]); \ + return sysfs_emit(buf, "%s\n", func->info[num - 1]); \ } \ static DEVICE_ATTR_RO(info##num) From 3b7340f1c89cc488e4df0b033bf7ae502ebbf5b2 Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Fri, 11 Feb 2022 13:20:55 +0530 Subject: [PATCH 095/124] mmc: sdhci_am654: Fix the driver data of AM64 SoC The MMCSD IPs used in AM64 are the same as the ones used in J721E. Therefore, fix this by using the driver data from J721E for AM64 too, for both 8 and 4 bit instances. Fixes: 754b7f2f7d2a ("mmc: sdhci_am654: Add Support for TI's AM64 SoC") Signed-off-by: Aswath Govindraju Link: https://lore.kernel.org/r/20220211075056.26179-1-a-govindraju@ti.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci_am654.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index f654afbe8e83..b4891bb26648 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -514,26 +514,6 @@ static const struct sdhci_am654_driver_data sdhci_j721e_4bit_drvdata = { .flags = IOMUX_PRESENT, }; -static const struct sdhci_pltfm_data sdhci_am64_8bit_pdata = { - .ops = &sdhci_j721e_8bit_ops, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, -}; - -static const struct sdhci_am654_driver_data sdhci_am64_8bit_drvdata = { - .pdata = &sdhci_am64_8bit_pdata, - .flags = DLL_PRESENT | DLL_CALIB, -}; - -static const struct sdhci_pltfm_data sdhci_am64_4bit_pdata = { - .ops = &sdhci_j721e_4bit_ops, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, -}; - -static const struct sdhci_am654_driver_data sdhci_am64_4bit_drvdata = { - .pdata = &sdhci_am64_4bit_pdata, - .flags = IOMUX_PRESENT, -}; - static const struct soc_device_attribute sdhci_am654_devices[] = { { .family = "AM65X", .revision = "SR1.0", @@ -759,11 +739,11 @@ static const struct of_device_id sdhci_am654_of_match[] = { }, { .compatible = "ti,am64-sdhci-8bit", - .data = &sdhci_am64_8bit_drvdata, + .data = &sdhci_j721e_8bit_drvdata, }, { .compatible = "ti,am64-sdhci-4bit", - .data = &sdhci_am64_4bit_drvdata, + .data = &sdhci_j721e_4bit_drvdata, }, { /* sentinel */ } }; From 3569a139a8739949d187fbe0e04949d1d2cb1330 Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Wed, 16 Feb 2022 19:13:46 +0530 Subject: [PATCH 096/124] dt-bindings: mmc: sdhci-am654: Add compatible string for AM62 SoC Add compatible string for AM62 SoC in device tree binding of AM654 SDHCI module as the same IP is used. Signed-off-by: Aswath Govindraju Link: https://lore.kernel.org/r/20220216134346.11029-1-a-govindraju@ti.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/sdhci-am654.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml index 9fbf16b3bc8d..0566493c4def 100644 --- a/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml +++ b/Documentation/devicetree/bindings/mmc/sdhci-am654.yaml @@ -21,6 +21,7 @@ properties: - const: ti,j721e-sdhci-4bit - const: ti,am64-sdhci-8bit - const: ti,am64-sdhci-4bit + - const: ti,am62-sdhci - items: - const: ti,j7200-sdhci-8bit - const: ti,j721e-sdhci-8bit From b9df01a50d516d7a62d5fd3eff5b57981f283be1 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 15 Feb 2022 16:15:02 +0800 Subject: [PATCH 097/124] dt-bindings: mmc: imx-esdhc: Add imx93 compatible string Add i.MX93 compatible string, it uses two compatible strings. Signed-off-by: Peng Fan Link: https://lore.kernel.org/r/20220215081502.789067-1-peng.fan@oss.nxp.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml index 17acbc665f5a..7dbbcae9485c 100644 --- a/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml +++ b/Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.yaml @@ -47,6 +47,7 @@ properties: - const: fsl,imx7d-usdhc - items: - enum: + - fsl,imx93-usdhc - fsl,imx8ulp-usdhc - const: fsl,imx8mm-usdhc From 02538e45c666f207c55ae2984cf64de16abd3aea Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Fri, 18 Feb 2022 12:58:40 +0530 Subject: [PATCH 098/124] mmc: sdhci_am654: Add Support for TI's AM62 SoC Add support for the controller present on the AM62x SoC. There are instances: sdhci0: 8bit bus width, max 200 MBps sdhci1: 4bit bus width, max 100 MBps sdhci2: 4bit bus width, max 100 MBps The PHY used for 8 bit instance is same as the PHY for the 4 bit instance. Therefore, introduce a new bus width independent compatible for AM62 SoC that uses the driver data required for 4 bit instance. Signed-off-by: Aswath Govindraju Link: https://lore.kernel.org/r/20220218072840.5629-1-a-govindraju@ti.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci_am654.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/mmc/host/sdhci_am654.c b/drivers/mmc/host/sdhci_am654.c index b4891bb26648..e54fe24d47e7 100644 --- a/drivers/mmc/host/sdhci_am654.c +++ b/drivers/mmc/host/sdhci_am654.c @@ -745,6 +745,10 @@ static const struct of_device_id sdhci_am654_of_match[] = { .compatible = "ti,am64-sdhci-4bit", .data = &sdhci_j721e_4bit_drvdata, }, + { + .compatible = "ti,am62-sdhci", + .data = &sdhci_j721e_4bit_drvdata, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_am654_of_match); From bee1549199d4025b801d99b6b9157c2a6f938ed2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 21 Feb 2022 17:27:20 +0100 Subject: [PATCH 099/124] mmc: sh_mmcif: Simplify division/shift logic "a / (1 << b)" == "a >> b". No change in generated code. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/68d689c39c769d298b53ee8cb9de0e594a2999b2.1645460780.git.geert+renesas@glider.be Signed-off-by: Ulf Hansson --- drivers/mmc/host/sh_mmcif.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index 104dcd702870..5f9ebf045b1c 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -521,8 +521,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) } dev_dbg(dev, "clk %u/%u (%u, 0x%x)\n", - (best_freq / (1 << (clkdiv + 1))), clk, - best_freq, clkdiv); + (best_freq >> (clkdiv + 1)), clk, best_freq, clkdiv); clk_set_rate(host->clk, best_freq); clkdiv = clkdiv << 16; @@ -1012,8 +1011,8 @@ static void sh_mmcif_clk_setup(struct sh_mmcif_host *host) */ host->clkdiv_map = 0x3ff; - host->mmc->f_max = f_max / (1 << ffs(host->clkdiv_map)); - host->mmc->f_min = f_min / (1 << fls(host->clkdiv_map)); + host->mmc->f_max = f_max >> ffs(host->clkdiv_map); + host->mmc->f_min = f_min >> fls(host->clkdiv_map); } else { unsigned int clk = clk_get_rate(host->clk); From a4ee79063f44c60992c89eb4f66853329908ecca Mon Sep 17 00:00:00 2001 From: Lad Prabhakar Date: Sun, 27 Feb 2022 21:23:30 +0000 Subject: [PATCH 100/124] dt-bindings: mmc: renesas,sdhi: Document RZ/V2L SoC Document RZ/V2L SDHI bindings. RZ/V2L SDHI is almost identical to one found on the R-Car Gen3. No driver changes are required as generic compatible string "renesas,rcar-gen3-sdhi" will be used as a fallback. Signed-off-by: Lad Prabhakar Reviewed-by: Biju Das Reviewed-by: Krzysztof Kozlowski Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20220227212330.22262-1-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml index 9ce6e06c19db..3b191fb89cf1 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml +++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml @@ -58,6 +58,7 @@ properties: - renesas,sdhi-r8a77995 # R-Car D3 - renesas,sdhi-r8a779a0 # R-Car V3U - renesas,sdhi-r9a07g044 # RZ/G2{L,LC} + - renesas,sdhi-r9a07g054 # RZ/V2L - const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2 reg: @@ -107,7 +108,9 @@ allOf: properties: compatible: contains: - const: renesas,sdhi-r9a07g044 + enum: + - renesas,sdhi-r9a07g044 + - renesas,sdhi-r9a07g054 then: properties: clocks: From 099849af27f74981c7e660dd93ff6a987307c1f2 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 25 Feb 2022 11:23:17 -0600 Subject: [PATCH 101/124] ata: ahci: Rename board_ahci_mobile This board definition was originally created for mobile devices to designate default link power managmeent policy to influence runtime power consumption. As this is interesting for more than just mobile designs, rename the board to `board_ahci_low_power` to make it clear it is about default policy. Reviewed-by: Hans de Goede Reviewed-by: Paul Menzel Signed-off-by: Mario Limonciello Signed-off-by: Damien Le Moal --- drivers/ata/ahci.c | 96 +++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index bb14683a8d4b..c31fae2b384e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -50,7 +50,7 @@ enum board_ids { /* board IDs by feature in alphabetical order */ board_ahci, board_ahci_ign_iferr, - board_ahci_mobile, + board_ahci_low_power, board_ahci_no_debounce_delay, board_ahci_nomsi, board_ahci_noncq, @@ -135,7 +135,7 @@ static const struct ata_port_info ahci_port_info[] = { .udma_mask = ATA_UDMA6, .port_ops = &ahci_ops, }, - [board_ahci_mobile] = { + [board_ahci_low_power] = { AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE), .flags = AHCI_FLAG_COMMON, .pio_mask = ATA_PIO4, @@ -275,13 +275,13 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x2929), board_ahci_mobile }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292a), board_ahci_mobile }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292b), board_ahci_mobile }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292c), board_ahci_mobile }, /* ICH9M */ - { PCI_VDEVICE(INTEL, 0x292f), board_ahci_mobile }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x2929), board_ahci_low_power }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292a), board_ahci_low_power }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292b), board_ahci_low_power }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292c), board_ahci_low_power }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x292f), board_ahci_low_power }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ - { PCI_VDEVICE(INTEL, 0x294e), board_ahci_mobile }, /* ICH9M */ + { PCI_VDEVICE(INTEL, 0x294e), board_ahci_low_power }, /* ICH9M */ { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */ { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */ { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */ @@ -291,9 +291,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */ { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */ { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */ - { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_mobile }, /* PCH M AHCI */ + { PCI_VDEVICE(INTEL, 0x3b29), board_ahci_low_power }, /* PCH M AHCI */ { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */ - { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_mobile }, /* PCH M RAID */ + { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci_low_power }, /* PCH M RAID */ { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */ { PCI_VDEVICE(INTEL, 0x19b0), board_ahci_pcs7 }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x19b1), board_ahci_pcs7 }, /* DNV AHCI */ @@ -316,9 +316,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x19cE), board_ahci_pcs7 }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x19cF), board_ahci_pcs7 }, /* DNV AHCI */ { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */ - { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_mobile }, /* CPT M AHCI */ + { PCI_VDEVICE(INTEL, 0x1c03), board_ahci_low_power }, /* CPT M AHCI */ { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */ - { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_mobile }, /* CPT M RAID */ + { PCI_VDEVICE(INTEL, 0x1c05), board_ahci_low_power }, /* CPT M RAID */ { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */ { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */ { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */ @@ -327,29 +327,29 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG/Lewisburg RAID*/ { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ - { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_mobile }, /* Panther M AHCI */ + { PCI_VDEVICE(INTEL, 0x1e03), board_ahci_low_power }, /* Panther M AHCI */ { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ - { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_mobile }, /* Panther M RAID */ + { PCI_VDEVICE(INTEL, 0x1e07), board_ahci_low_power }, /* Panther M RAID */ { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */ { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */ - { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_mobile }, /* Lynx M AHCI */ + { PCI_VDEVICE(INTEL, 0x8c03), board_ahci_low_power }, /* Lynx M AHCI */ { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_mobile }, /* Lynx M RAID */ + { PCI_VDEVICE(INTEL, 0x8c05), board_ahci_low_power }, /* Lynx M RAID */ { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_mobile }, /* Lynx M RAID */ + { PCI_VDEVICE(INTEL, 0x8c07), board_ahci_low_power }, /* Lynx M RAID */ { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */ - { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_mobile }, /* Lynx M RAID */ - { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_mobile }, /* Lynx LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_mobile }, /* Lynx LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_mobile }, /* Lynx LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_mobile }, /* Lynx LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_mobile }, /* Lynx LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_mobile }, /* Lynx LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_mobile }, /* Lynx LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_mobile }, /* Lynx LP RAID */ - { PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_mobile }, /* Cannon Lake PCH-LP AHCI */ + { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci_low_power }, /* Lynx M RAID */ + { PCI_VDEVICE(INTEL, 0x9c02), board_ahci_low_power }, /* Lynx LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9c03), board_ahci_low_power }, /* Lynx LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9c04), board_ahci_low_power }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c05), board_ahci_low_power }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c06), board_ahci_low_power }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c07), board_ahci_low_power }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci_low_power }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci_low_power }, /* Lynx LP RAID */ + { PCI_VDEVICE(INTEL, 0x9dd3), board_ahci_low_power }, /* Cannon Lake PCH-LP AHCI */ { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */ { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */ { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */ @@ -381,26 +381,26 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */ - { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_mobile }, /* Wildcat LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_mobile }, /* Wildcat LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_mobile }, /* Wildcat LP RAID */ - { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_mobile }, /* Wildcat LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c83), board_ahci_low_power }, /* Wildcat LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9c85), board_ahci_low_power }, /* Wildcat LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c87), board_ahci_low_power }, /* Wildcat LP RAID */ + { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci_low_power }, /* Wildcat LP RAID */ { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */ - { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_mobile }, /* 9 Series M AHCI */ + { PCI_VDEVICE(INTEL, 0x8c83), board_ahci_low_power }, /* 9 Series M AHCI */ { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_mobile }, /* 9 Series M RAID */ + { PCI_VDEVICE(INTEL, 0x8c85), board_ahci_low_power }, /* 9 Series M RAID */ { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_mobile }, /* 9 Series M RAID */ + { PCI_VDEVICE(INTEL, 0x8c87), board_ahci_low_power }, /* 9 Series M RAID */ { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */ - { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_mobile }, /* 9 Series M RAID */ - { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_mobile }, /* Sunrise LP AHCI */ - { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_mobile }, /* Sunrise LP RAID */ - { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_mobile }, /* Sunrise LP RAID */ + { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci_low_power }, /* 9 Series M RAID */ + { PCI_VDEVICE(INTEL, 0x9d03), board_ahci_low_power }, /* Sunrise LP AHCI */ + { PCI_VDEVICE(INTEL, 0x9d05), board_ahci_low_power }, /* Sunrise LP RAID */ + { PCI_VDEVICE(INTEL, 0x9d07), board_ahci_low_power }, /* Sunrise LP RAID */ { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */ - { PCI_VDEVICE(INTEL, 0xa103), board_ahci_mobile }, /* Sunrise M AHCI */ + { PCI_VDEVICE(INTEL, 0xa103), board_ahci_low_power }, /* Sunrise M AHCI */ { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */ - { PCI_VDEVICE(INTEL, 0xa107), board_ahci_mobile }, /* Sunrise M RAID */ + { PCI_VDEVICE(INTEL, 0xa107), board_ahci_low_power }, /* Sunrise M RAID */ { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */ { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/ { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/ @@ -413,13 +413,13 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0xa356), board_ahci }, /* Cannon Lake PCH-H RAID */ { PCI_VDEVICE(INTEL, 0x06d7), board_ahci }, /* Comet Lake-H RAID */ { PCI_VDEVICE(INTEL, 0xa386), board_ahci }, /* Comet Lake PCH-V RAID */ - { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_mobile }, /* Bay Trail AHCI */ - { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_mobile }, /* Bay Trail AHCI */ - { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_mobile }, /* Cherry Tr. AHCI */ - { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_mobile }, /* ApolloLake AHCI */ - { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_mobile }, /* Ice Lake LP AHCI */ - { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_mobile }, /* Comet Lake PCH-U AHCI */ - { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_mobile }, /* Comet Lake PCH RAID */ + { PCI_VDEVICE(INTEL, 0x0f22), board_ahci_low_power }, /* Bay Trail AHCI */ + { PCI_VDEVICE(INTEL, 0x0f23), board_ahci_low_power }, /* Bay Trail AHCI */ + { PCI_VDEVICE(INTEL, 0x22a3), board_ahci_low_power }, /* Cherry Tr. AHCI */ + { PCI_VDEVICE(INTEL, 0x5ae3), board_ahci_low_power }, /* ApolloLake AHCI */ + { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */ + { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */ + { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -447,7 +447,7 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */ { PCI_VDEVICE(AMD, 0x7801), board_ahci_no_debounce_delay }, /* AMD Hudson-2 (AHCI mode) */ { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */ - { PCI_VDEVICE(AMD, 0x7901), board_ahci_mobile }, /* AMD Green Sardine */ + { PCI_VDEVICE(AMD, 0x7901), board_ahci_low_power }, /* AMD Green Sardine */ /* AMD is using RAID class only for ahci controllers */ { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci }, From e5c894791eabf13f3754ee0b28a3a8c1c5660d41 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 25 Feb 2022 11:23:18 -0600 Subject: [PATCH 102/124] ata: ahci: Rename `AHCI_HFLAG_IS_MOBILE` `AHCI_HFLAG_IS_MOBILE` designates that a chipset should be using the default link power management policy from a kernel configuration item. As desktop chipsets may also be interested in this default policy configuration, rename the flag to `AHCI_HFLAG_USE_LPM_POLICY` to more accurately reflect that a chipset doesn't have to be mobile to adopt it. Reviewed-by: Hans de Goede Reviewed-by: Paul Menzel Signed-off-by: Mario Limonciello Signed-off-by: Damien Le Moal --- drivers/ata/ahci.c | 6 +++--- drivers/ata/ahci.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c31fae2b384e..397dfd27c90d 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -136,7 +136,7 @@ static const struct ata_port_info ahci_port_info[] = { .port_ops = &ahci_ops, }, [board_ahci_low_power] = { - AHCI_HFLAGS (AHCI_HFLAG_IS_MOBILE), + AHCI_HFLAGS (AHCI_HFLAG_USE_LPM_POLICY), .flags = AHCI_FLAG_COMMON, .pio_mask = ATA_PIO4, .udma_mask = ATA_UDMA6, @@ -1598,8 +1598,8 @@ static void ahci_update_initial_lpm_policy(struct ata_port *ap, int policy = CONFIG_SATA_MOBILE_LPM_POLICY; - /* Ignore processing for non mobile platforms */ - if (!(hpriv->flags & AHCI_HFLAG_IS_MOBILE)) + /* Ignore processing for chipsets that don't use policy */ + if (!(hpriv->flags & AHCI_HFLAG_USE_LPM_POLICY)) return; /* user modified policy via module param */ diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index eeac5482f1d1..1ad48e2fe573 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -235,7 +235,7 @@ enum { AHCI_HFLAG_YES_ALPM = (1 << 23), /* force ALPM cap on */ AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read only registers */ - AHCI_HFLAG_IS_MOBILE = (1 << 25), /* mobile chipset, use + AHCI_HFLAG_USE_LPM_POLICY = (1 << 25), /* chipset that should use SATA_MOBILE_LPM_POLICY as default lpm_policy */ AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during From 4dd4d3deb5026ee7356e23ce2607637ff313bb80 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Fri, 25 Feb 2022 11:23:19 -0600 Subject: [PATCH 103/124] ata: ahci: Rename CONFIG_SATA_LPM_MOBILE_POLICY configuration item `CONFIG_SATA_LPM_MOBILE_POLICY` reflects a configuration to apply only to mobile chipsets. As some desktop boards may want to use this policy by default as well, rename the configuration item to `SATA_LPM_POLICY`. Reviewed-by: Hans de Goede Reviewed-by: Paul Menzel Signed-off-by: Mario Limonciello Signed-off-by: Damien Le Moal --- drivers/ata/Kconfig | 6 +++--- drivers/ata/ahci.c | 2 +- drivers/ata/ahci.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index f2d436df9da3..e5641e6c52ee 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -115,14 +115,14 @@ config SATA_AHCI If unsure, say N. -config SATA_MOBILE_LPM_POLICY - int "Default SATA Link Power Management policy for mobile chipsets" +config SATA_LPM_POLICY + int "Default SATA Link Power Management policy for low power chipsets" range 0 4 default 0 depends on SATA_AHCI help Select the Default SATA Link Power Management (LPM) policy to use - for mobile / laptop variants of chipsets / "South Bridges". + for chipsets / "South Bridges" designated as supporting low power. The value set has the following meanings: 0 => Keep firmware settings diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 397dfd27c90d..84456c05e845 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1595,7 +1595,7 @@ static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports, static void ahci_update_initial_lpm_policy(struct ata_port *ap, struct ahci_host_priv *hpriv) { - int policy = CONFIG_SATA_MOBILE_LPM_POLICY; + int policy = CONFIG_SATA_LPM_POLICY; /* Ignore processing for chipsets that don't use policy */ diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 1ad48e2fe573..5badbaca05a0 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -236,7 +236,7 @@ enum { AHCI_HFLAG_NO_WRITE_TO_RO = (1 << 24), /* don't write to read only registers */ AHCI_HFLAG_USE_LPM_POLICY = (1 << 25), /* chipset that should use - SATA_MOBILE_LPM_POLICY + SATA_LPM_POLICY as default lpm_policy */ AHCI_HFLAG_SUSPEND_PHYS = (1 << 26), /* handle PHYs during suspend/resume */ From 1f311c94aabdb419c28e3147bcc8ab89269f1a7e Mon Sep 17 00:00:00 2001 From: Ricky WU Date: Wed, 2 Mar 2022 09:43:01 +0000 Subject: [PATCH 104/124] mmc: rtsx: add 74 Clocks in power on flow SD spec definition: "Host provides at least 74 Clocks before issuing first command" After 1ms for the voltage stable then start issuing the Clock signals if POWER STATE is MMC_POWER_OFF to MMC_POWER_UP to issue Clock signal to card MMC_POWER_UP to MMC_POWER_ON to stop issuing signal to card Signed-off-by: Ricky Wu Link: https://lore.kernel.org/r/1badf10aba764191a1a752edcbf90389@realtek.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/rtsx_pci_sdmmc.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 58cfaffa3c2d..219029224727 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c @@ -38,10 +38,7 @@ struct realtek_pci_sdmmc { bool double_clk; bool eject; bool initial_mode; - int power_state; -#define SDMMC_POWER_ON 1 -#define SDMMC_POWER_OFF 0 - + int prev_power_state; int sg_count; s32 cookie; int cookie_sg_count; @@ -905,7 +902,7 @@ static int sd_set_bus_width(struct realtek_pci_sdmmc *host, return err; } -static int sd_power_on(struct realtek_pci_sdmmc *host) +static int sd_power_on(struct realtek_pci_sdmmc *host, unsigned char power_mode) { struct rtsx_pcr *pcr = host->pcr; struct mmc_host *mmc = host->mmc; @@ -913,9 +910,14 @@ static int sd_power_on(struct realtek_pci_sdmmc *host) u32 val; u8 test_mode; - if (host->power_state == SDMMC_POWER_ON) + if (host->prev_power_state == MMC_POWER_ON) return 0; + if (host->prev_power_state == MMC_POWER_UP) { + rtsx_pci_write_register(pcr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0); + goto finish; + } + msleep(100); rtsx_pci_init_cmd(pcr); @@ -936,10 +938,15 @@ static int sd_power_on(struct realtek_pci_sdmmc *host) if (err < 0) return err; + mdelay(1); + err = rtsx_pci_write_register(pcr, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); if (err < 0) return err; + /* send at least 74 clocks */ + rtsx_pci_write_register(pcr, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN); + if (PCI_PID(pcr) == PID_5261) { /* * If test mode is set switch to SD Express mandatorily, @@ -964,7 +971,8 @@ static int sd_power_on(struct realtek_pci_sdmmc *host) } } - host->power_state = SDMMC_POWER_ON; +finish: + host->prev_power_state = power_mode; return 0; } @@ -973,7 +981,7 @@ static int sd_power_off(struct realtek_pci_sdmmc *host) struct rtsx_pcr *pcr = host->pcr; int err; - host->power_state = SDMMC_POWER_OFF; + host->prev_power_state = MMC_POWER_OFF; rtsx_pci_init_cmd(pcr); @@ -999,7 +1007,7 @@ static int sd_set_power_mode(struct realtek_pci_sdmmc *host, if (power_mode == MMC_POWER_OFF) err = sd_power_off(host); else - err = sd_power_on(host); + err = sd_power_on(host, power_mode); return err; } @@ -1482,10 +1490,11 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) host = mmc_priv(mmc); host->pcr = pcr; + mmc->ios.power_delay_ms = 5; host->mmc = mmc; host->pdev = pdev; host->cookie = -1; - host->power_state = SDMMC_POWER_OFF; + host->prev_power_state = MMC_POWER_OFF; INIT_WORK(&host->work, sd_request); platform_set_drvdata(pdev, host); pcr->slots[RTSX_SD_CARD].p_dev = pdev; From edcb647b4bfb19674d58bff2e6ef96e0dbcccfdf Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 2 Mar 2022 23:01:18 +0500 Subject: [PATCH 105/124] selftests: add kselftest_install to .gitignore Add kselftest_install directory to the .gitignore which is created while creation of tar ball of objects: make -C tools/testing/selftests gen_tar Signed-off-by: Muhammad Usama Anjum Reviewed-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/.gitignore b/tools/testing/selftests/.gitignore index 055a5019b13c..cb24124ac5b9 100644 --- a/tools/testing/selftests/.gitignore +++ b/tools/testing/selftests/.gitignore @@ -3,6 +3,7 @@ gpiogpio-event-mon gpiogpio-hammer gpioinclude/ gpiolsgpio +kselftest_install/ tpm2/SpaceTest.log # Python bytecode and cache From c7b9c68fc01b468983c8f4745f400fa74c831005 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 2 Mar 2022 23:01:19 +0500 Subject: [PATCH 106/124] selftests/exec: add generated files to .gitignore Add generated files non-regular and null-argv to .gitignore file. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/exec/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/exec/.gitignore b/tools/testing/selftests/exec/.gitignore index 9e2f00343f15..90c238ba6a4b 100644 --- a/tools/testing/selftests/exec/.gitignore +++ b/tools/testing/selftests/exec/.gitignore @@ -7,6 +7,8 @@ execveat.moved execveat.path.ephemeral execveat.ephemeral execveat.denatured +non-regular +null-argv /load_address_* /recursion-depth xxxxxxxx* From 946ad0499d984be13ec02f8257ca0527ec287bf2 Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Wed, 2 Mar 2022 23:01:20 +0500 Subject: [PATCH 107/124] selftests: kvm: add generated file to the .gitignore Add hyperv_svm_test to the .gitignore file. Signed-off-by: Muhammad Usama Anjum Reviewed-by: Kees Cook Signed-off-by: Shuah Khan --- tools/testing/selftests/kvm/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore index dce7de7755e6..62f9b781545b 100644 --- a/tools/testing/selftests/kvm/.gitignore +++ b/tools/testing/selftests/kvm/.gitignore @@ -20,6 +20,7 @@ /x86_64/hyperv_clock /x86_64/hyperv_cpuid /x86_64/hyperv_features +/x86_64/hyperv_svm_test /x86_64/mmio_warning_test /x86_64/mmu_role_test /x86_64/platform_info_test From a50a88f026fb28ece512c50e8ef7cd4ef6d0a291 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Wed, 2 Mar 2022 13:29:13 +0800 Subject: [PATCH 108/124] selftests: netfilter: fix a build error on openSUSE This patch fixed the following build error on openSUSE Leap 15.3: ======================================================================= gcc nf-queue.c -lmnl -o tools/testing/selftests/netfilter/nf-queue nf-queue.c:13:10: fatal error: libmnl/libmnl.h: No such file or directory #include ^~~~~~~~~~~~~~~~~ compilation terminated. ======================================================================= It is because libmnl.h is put in the directory of "/usr/include/libmnl/libmnl/" on openSUSE, not "/usr/include/libmnl/": > rpm -ql libmnl-devel /usr/include/libmnl /usr/include/libmnl/libmnl /usr/include/libmnl/libmnl/libmnl.h /usr/lib64/libmnl.so /usr/lib64/pkgconfig/libmnl.pc Suggested-by: Kai Liu Signed-off-by: Geliang Tang Reviewed-by: Shuah Khan Signed-off-by: Shuah Khan --- tools/testing/selftests/netfilter/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/testing/selftests/netfilter/Makefile b/tools/testing/selftests/netfilter/Makefile index e4f845dd942b..8136c1fab7ab 100644 --- a/tools/testing/selftests/netfilter/Makefile +++ b/tools/testing/selftests/netfilter/Makefile @@ -8,6 +8,7 @@ TEST_PROGS := nft_trans_stress.sh nft_fib.sh nft_nat.sh bridge_brouter.sh \ ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ conntrack_vrf.sh nft_synproxy.sh +CFLAGS += $(shell pkg-config --cflags libmnl 2>/dev/null || echo "-I/usr/include/libmnl") LDLIBS = -lmnl TEST_GEN_FILES = nf-queue From f6d344cd5fa6a15e1ec2da350470b35a3f55f74c Mon Sep 17 00:00:00 2001 From: Muhammad Usama Anjum Date: Thu, 17 Feb 2022 03:38:17 +0500 Subject: [PATCH 109/124] selftests: Fix build when $(O) points to a relative path Build of bpf and tc-testing selftests fails when the relative path of the build directory is specified. make -C tools/testing/selftests O=build0 make[1]: Entering directory '/linux_mainline/tools/testing/selftests/bpf' ../../../scripts/Makefile.include:4: *** O=build0 does not exist. Stop. make[1]: Entering directory '/linux_mainline/tools/testing/selftests/tc-testing' ../../../scripts/Makefile.include:4: *** O=build0 does not exist. Stop. Makefiles of bpf and tc-testing include scripts/Makefile.include file. This file has sanity checking inside it which checks the output path. The output path is not relative to the bpf or tc-testing. The sanity check fails. Expand the output path to get rid of this error. The fix is the same as mentioned in commit 150a27328b68 ("bpf, preload: Fix build when $(O) points to a relative path"). Signed-off-by: Muhammad Usama Anjum Signed-off-by: Shuah Khan --- tools/testing/selftests/Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 5d9d4ddccccb..2319ec87f53d 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -177,6 +177,7 @@ all: khdr BUILD_TARGET=$$BUILD/$$TARGET; \ mkdir $$BUILD_TARGET -p; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET \ + O=$(abs_objtree) \ $(if $(FORCE_TARGETS),|| exit); \ ret=$$((ret * $$?)); \ done; exit $$ret; @@ -184,7 +185,8 @@ all: khdr run_tests: all @for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests \ + O=$(abs_objtree); \ done; hotplug: @@ -235,6 +237,7 @@ ifdef INSTALL_PATH for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET INSTALL_PATH=$(INSTALL_PATH)/$$TARGET install \ + O=$(abs_objtree) \ $(if $(FORCE_TARGETS),|| exit); \ ret=$$((ret * $$?)); \ done; exit $$ret; From 5e776d7b20f040f3219128cee17a1191d66a0f3f Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 3 Mar 2022 09:36:35 +0100 Subject: [PATCH 110/124] ata: Drop commas after OF match table sentinels It does not make sense to have a comma after a sentinel, as any new elements must be added before the sentinel. Add comments to clarify the purpose of the empty elements. Rewrap entries to a single line to have a consistent style. Signed-off-by: Geert Uytterhoeven Reviewed-by: Sergey Shtylyov Acked-by: Florian Fainelli [ahci_brcm] Reviewed-by: Kieran Bingham Reviewed-by: Linus Walleij Signed-off-by: Damien Le Moal --- drivers/ata/ahci_brcm.c | 2 +- drivers/ata/ahci_ceva.c | 2 +- drivers/ata/ahci_da850.c | 2 +- drivers/ata/ahci_dm816.c | 2 +- drivers/ata/ahci_imx.c | 2 +- drivers/ata/ahci_mtk.c | 2 +- drivers/ata/ahci_mvebu.c | 2 +- drivers/ata/ahci_octeon.c | 2 +- drivers/ata/ahci_platform.c | 2 +- drivers/ata/ahci_qoriq.c | 2 +- drivers/ata/ahci_st.c | 2 +- drivers/ata/ahci_sunxi.c | 2 +- drivers/ata/ahci_xgene.c | 2 +- drivers/ata/pata_ftide010.c | 6 ++---- drivers/ata/pata_ixp4xx_cf.c | 2 +- drivers/ata/pata_macio.c | 18 +++++------------- drivers/ata/pata_mpc52xx.c | 2 +- drivers/ata/pata_octeon_cf.c | 6 ++---- drivers/ata/pata_of_platform.c | 2 +- drivers/ata/sata_fsl.c | 10 +++------- drivers/ata/sata_gemini.c | 6 ++---- drivers/ata/sata_highbank.c | 2 +- drivers/ata/sata_mv.c | 2 +- drivers/ata/sata_rcar.c | 2 +- 24 files changed, 33 insertions(+), 51 deletions(-) diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c index 64dd8aa397d5..ab8552b1ff2a 100644 --- a/drivers/ata/ahci_brcm.c +++ b/drivers/ata/ahci_brcm.c @@ -427,7 +427,7 @@ static const struct of_device_id ahci_of_match[] = { {.compatible = "brcm,bcm63138-ahci", .data = (void *)BRCM_SATA_BCM7445}, {.compatible = "brcm,bcm-nsp-ahci", .data = (void *)BRCM_SATA_NSP}, {.compatible = "brcm,bcm7216-ahci", .data = (void *)BRCM_SATA_BCM7216}, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c index acf59f51b356..cb24ecf36faf 100644 --- a/drivers/ata/ahci_ceva.c +++ b/drivers/ata/ahci_ceva.c @@ -363,7 +363,7 @@ static SIMPLE_DEV_PM_OPS(ahci_ceva_pm_ops, ceva_ahci_suspend, ceva_ahci_resume); static const struct of_device_id ceva_ahci_of_match[] = { { .compatible = "ceva,ahci-1v84" }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ceva_ahci_of_match); diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c index 0e8276600712..052c28e250aa 100644 --- a/drivers/ata/ahci_da850.c +++ b/drivers/ata/ahci_da850.c @@ -241,7 +241,7 @@ static SIMPLE_DEV_PM_OPS(ahci_da850_pm_ops, ahci_platform_suspend, static const struct of_device_id ahci_da850_of_match[] = { { .compatible = "ti,da850-ahci", }, - { }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_da850_of_match); diff --git a/drivers/ata/ahci_dm816.c b/drivers/ata/ahci_dm816.c index 8bec41041671..8a92112dcd59 100644 --- a/drivers/ata/ahci_dm816.c +++ b/drivers/ata/ahci_dm816.c @@ -176,7 +176,7 @@ static SIMPLE_DEV_PM_OPS(ahci_dm816_pm_ops, static const struct of_device_id ahci_dm816_of_match[] = { { .compatible = "ti,dm816-ahci", }, - { }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_dm816_of_match); diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 388baf528fa8..79aa9f285312 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -811,7 +811,7 @@ static const struct of_device_id imx_ahci_of_match[] = { { .compatible = "fsl,imx6q-ahci", .data = (void *)AHCI_IMX6Q }, { .compatible = "fsl,imx6qp-ahci", .data = (void *)AHCI_IMX6QP }, { .compatible = "fsl,imx8qm-ahci", .data = (void *)AHCI_IMX8QM }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, imx_ahci_of_match); diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c index d9b08ae7c3b2..1f6c85fde983 100644 --- a/drivers/ata/ahci_mtk.c +++ b/drivers/ata/ahci_mtk.c @@ -169,7 +169,7 @@ static SIMPLE_DEV_PM_OPS(ahci_pm_ops, ahci_platform_suspend, static const struct of_device_id ahci_of_match[] = { { .compatible = "mediatek,mtk-ahci", }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c index 3ad46d26d9d5..991413a272e6 100644 --- a/drivers/ata/ahci_mvebu.c +++ b/drivers/ata/ahci_mvebu.c @@ -239,7 +239,7 @@ static const struct of_device_id ahci_mvebu_of_match[] = { .compatible = "marvell,armada-3700-ahci", .data = &ahci_mvebu_armada_3700_plat_data, }, - { }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_mvebu_of_match); diff --git a/drivers/ata/ahci_octeon.c b/drivers/ata/ahci_octeon.c index 5a44e089c6bb..b9460b91288f 100644 --- a/drivers/ata/ahci_octeon.c +++ b/drivers/ata/ahci_octeon.c @@ -80,7 +80,7 @@ static int ahci_octeon_remove(struct platform_device *pdev) static const struct of_device_id octeon_ahci_match[] = { { .compatible = "cavium,octeon-7130-sata-uctl", }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, octeon_ahci_match); diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index 3aab2e3d57f3..28a8de5b48b9 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -88,7 +88,7 @@ static const struct of_device_id ahci_of_match[] = { { .compatible = "snps,dwc-ahci", }, { .compatible = "hisilicon,hisi-ahci", }, { .compatible = "cavium,octeon-7130-ahci", }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c index cca78e25b173..6cd61842ad48 100644 --- a/drivers/ata/ahci_qoriq.c +++ b/drivers/ata/ahci_qoriq.c @@ -77,7 +77,7 @@ static const struct of_device_id ahci_qoriq_of_match[] = { { .compatible = "fsl,ls1088a-ahci", .data = (void *)AHCI_LS1088A}, { .compatible = "fsl,ls2088a-ahci", .data = (void *)AHCI_LS2088A}, { .compatible = "fsl,lx2160a-ahci", .data = (void *)AHCI_LX2160A}, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_qoriq_of_match); diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c index c268264c2129..7526653c843b 100644 --- a/drivers/ata/ahci_st.c +++ b/drivers/ata/ahci_st.c @@ -232,7 +232,7 @@ static SIMPLE_DEV_PM_OPS(st_ahci_pm_ops, st_ahci_suspend, st_ahci_resume); static const struct of_device_id st_ahci_match[] = { { .compatible = "st,ahci", }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, st_ahci_match); diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c index 56b695136977..c7273c1cb0c7 100644 --- a/drivers/ata/ahci_sunxi.c +++ b/drivers/ata/ahci_sunxi.c @@ -286,7 +286,7 @@ static SIMPLE_DEV_PM_OPS(ahci_sunxi_pm_ops, ahci_platform_suspend, static const struct of_device_id ahci_sunxi_of_match[] = { { .compatible = "allwinner,sun4i-a10-ahci", }, { .compatible = "allwinner,sun8i-r40-ahci", }, - { }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_sunxi_of_match); diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c index c5b392e07e65..7bb5db17f864 100644 --- a/drivers/ata/ahci_xgene.c +++ b/drivers/ata/ahci_xgene.c @@ -726,7 +726,7 @@ MODULE_DEVICE_TABLE(acpi, xgene_ahci_acpi_match); static const struct of_device_id xgene_ahci_of_match[] = { {.compatible = "apm,xgene-ahci", .data = (void *) XGENE_AHCI_V1}, {.compatible = "apm,xgene-ahci-v2", .data = (void *) XGENE_AHCI_V2}, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, xgene_ahci_of_match); diff --git a/drivers/ata/pata_ftide010.c b/drivers/ata/pata_ftide010.c index 34cb104f6b43..2e35505b683c 100644 --- a/drivers/ata/pata_ftide010.c +++ b/drivers/ata/pata_ftide010.c @@ -554,10 +554,8 @@ static int pata_ftide010_remove(struct platform_device *pdev) } static const struct of_device_id pata_ftide010_of_match[] = { - { - .compatible = "faraday,ftide010", - }, - {}, + { .compatible = "faraday,ftide010", }, + { /* sentinel */ } }; static struct platform_driver pata_ftide010_driver = { diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index 17b557c91e1c..e225913a619d 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -293,7 +293,7 @@ static int ixp4xx_pata_probe(struct platform_device *pdev) static const struct of_device_id ixp4xx_pata_of_match[] = { { .compatible = "intel,ixp4xx-compact-flash", }, - { }, + { /* sentinel */ } }; static struct platform_driver ixp4xx_pata_platform_driver = { diff --git a/drivers/ata/pata_macio.c b/drivers/ata/pata_macio.c index 3c3509f18cdd..42798402cf63 100644 --- a/drivers/ata/pata_macio.c +++ b/drivers/ata/pata_macio.c @@ -1329,19 +1329,11 @@ static int pata_macio_pci_resume(struct pci_dev *pdev) static const struct of_device_id pata_macio_match[] = { - { - .name = "IDE", - }, - { - .name = "ATA", - }, - { - .type = "ide", - }, - { - .type = "ata", - }, - {}, + { .name = "IDE", }, + { .name = "ATA", }, + { .type = "ide", }, + { .type = "ata", }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, pata_macio_match); diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index a2a3a95c71ed..3250ef317df6 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -850,7 +850,7 @@ mpc52xx_ata_resume(struct platform_device *op) static const struct of_device_id mpc52xx_ata_of_match[] = { { .compatible = "fsl,mpc5200-ata", }, { .compatible = "mpc5200-ata", }, - {}, + { /* sentinel */ } }; diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index aaa9f95d814c..6b5ed3046b44 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -1006,10 +1006,8 @@ static void octeon_cf_shutdown(struct device *dev) } static const struct of_device_id octeon_cf_match[] = { - { - .compatible = "cavium,ebt3000-compact-flash", - }, - {}, + { .compatible = "cavium,ebt3000-compact-flash", }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, octeon_cf_match); diff --git a/drivers/ata/pata_of_platform.c b/drivers/ata/pata_of_platform.c index c3a40b717dcd..ac5a633c00a5 100644 --- a/drivers/ata/pata_of_platform.c +++ b/drivers/ata/pata_of_platform.c @@ -79,7 +79,7 @@ static int pata_of_platform_probe(struct platform_device *ofdev) static const struct of_device_id pata_of_platform_match[] = { { .compatible = "ata-generic", }, - { }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, pata_of_platform_match); diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index cfe93c420488..dd27a34e3ce9 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1581,13 +1581,9 @@ static int sata_fsl_resume(struct platform_device *op) #endif static const struct of_device_id fsl_sata_match[] = { - { - .compatible = "fsl,pq-sata", - }, - { - .compatible = "fsl,pq-sata-v2", - }, - {}, + { .compatible = "fsl,pq-sata", }, + { .compatible = "fsl,pq-sata-v2", }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fsl_sata_match); diff --git a/drivers/ata/sata_gemini.c b/drivers/ata/sata_gemini.c index 440a63de20d0..00e1c7941d0e 100644 --- a/drivers/ata/sata_gemini.c +++ b/drivers/ata/sata_gemini.c @@ -419,10 +419,8 @@ static int gemini_sata_remove(struct platform_device *pdev) } static const struct of_device_id gemini_sata_of_match[] = { - { - .compatible = "cortina,gemini-sata-bridge", - }, - {}, + { .compatible = "cortina,gemini-sata-bridge", }, + { /* sentinel */ } }; static struct platform_driver gemini_sata_driver = { diff --git a/drivers/ata/sata_highbank.c b/drivers/ata/sata_highbank.c index 40bb27f83ecf..dfbf9493e451 100644 --- a/drivers/ata/sata_highbank.c +++ b/drivers/ata/sata_highbank.c @@ -444,7 +444,7 @@ static struct scsi_host_template ahci_highbank_platform_sht = { static const struct of_device_id ahci_of_match[] = { { .compatible = "calxeda,hb-ahci" }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ahci_of_match); diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 3b2a0d228306..de5bd02cad44 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -4277,7 +4277,7 @@ static int mv_platform_resume(struct platform_device *pdev) static const struct of_device_id mv_sata_dt_ids[] = { { .compatible = "marvell,armada-370-sata", }, { .compatible = "marvell,orion-sata", }, - {}, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, mv_sata_dt_ids); #endif diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c index 8e4516acb3f6..590ebea99601 100644 --- a/drivers/ata/sata_rcar.c +++ b/drivers/ata/sata_rcar.c @@ -852,7 +852,7 @@ static const struct of_device_id sata_rcar_match[] = { .compatible = "renesas,rcar-gen3-sata", .data = (void *)RCAR_GEN3_SATA }, - { }, + { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sata_rcar_match); From 0ffd498db172258fde312bb8671816f18b2f6d0c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 3 Mar 2022 13:49:18 +0100 Subject: [PATCH 111/124] mmc: host: Drop commas after SoC match table sentinels It does not make sense to have a comma after a sentinel, as any new elements must be added before the sentinel. Add comments to clarify the purpose of the empty elements. Signed-off-by: Geert Uytterhoeven Reviewed-by: Wolfram Sang Link: https://lore.kernel.org/r/9050fa278eaaa9e6ec719a3b158a2fad285560d0.1646311673.git.geert+renesas@glider.be Signed-off-by: Ulf Hansson --- drivers/mmc/host/renesas_sdhi_internal_dmac.c | 2 +- drivers/mmc/host/sdhci-of-esdhc.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/mmc/host/renesas_sdhi_internal_dmac.c b/drivers/mmc/host/renesas_sdhi_internal_dmac.c index 9d2c600fd4ce..1685df00863b 100644 --- a/drivers/mmc/host/renesas_sdhi_internal_dmac.c +++ b/drivers/mmc/host/renesas_sdhi_internal_dmac.c @@ -212,7 +212,7 @@ static const struct soc_device_attribute sdhi_quirks_match[] = { { .soc_id = "r8a7795", .revision = "ES2.0", .data = &sdhi_quirks_4tap }, { .soc_id = "r8a7796", .revision = "ES1.[012]", .data = &sdhi_quirks_4tap_nohs400 }, { .soc_id = "r8a7796", .revision = "ES1.*", .data = &sdhi_quirks_r8a7796_es13 }, - { /* Sentinel. */ }, + { /* Sentinel. */ } }; static const struct renesas_sdhi_of_data_with_quirks of_r8a7795_compatible = { diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 0f3658b36513..d9dc41143bb3 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -934,7 +934,7 @@ static struct soc_device_attribute soc_tuning_erratum_type1[] = { { .family = "QorIQ T1040", }, { .family = "QorIQ T2080", }, { .family = "QorIQ LS1021A", }, - { }, + { /* sentinel */ } }; static struct soc_device_attribute soc_tuning_erratum_type2[] = { @@ -944,7 +944,7 @@ static struct soc_device_attribute soc_tuning_erratum_type2[] = { { .family = "QorIQ LS1080A", }, { .family = "QorIQ LS2080A", }, { .family = "QorIQ LA1575A", }, - { }, + { /* sentinel */ } }; static void esdhc_tuning_block_enable(struct sdhci_host *host, bool enable) @@ -1316,21 +1316,21 @@ static const struct sdhci_pltfm_data sdhci_esdhc_le_pdata = { static struct soc_device_attribute soc_incorrect_hostver[] = { { .family = "QorIQ T4240", .revision = "1.0", }, { .family = "QorIQ T4240", .revision = "2.0", }, - { }, + { /* sentinel */ } }; static struct soc_device_attribute soc_fixup_sdhc_clkdivs[] = { { .family = "QorIQ LX2160A", .revision = "1.0", }, { .family = "QorIQ LX2160A", .revision = "2.0", }, { .family = "QorIQ LS1028A", .revision = "1.0", }, - { }, + { /* sentinel */ } }; static struct soc_device_attribute soc_unreliable_pulse_detection[] = { { .family = "QorIQ LX2160A", .revision = "1.0", }, { .family = "QorIQ LX2160A", .revision = "2.0", }, { .family = "QorIQ LS1028A", .revision = "1.0", }, - { }, + { /* sentinel */ } }; static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) From c4313e75001492f8a288d3ffd595544cbc880821 Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Sat, 5 Mar 2022 16:58:34 -0500 Subject: [PATCH 112/124] mmc: dw_mmc: Support setting f_min from host drivers Host drivers may not be able to support frequencies as low as dw-mmc supports. Unfortunately f_min isn't available when the drv_data->init function is called, as the mmc_host struct hasn't been set up yet. Support the host drivers saving the requested minimum frequency, so we can later set f_min when it is available. Signed-off-by: Peter Geis Link: https://lore.kernel.org/r/20220305215835.2210388-2-pgwipeout@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/dw_mmc.c | 7 ++++++- drivers/mmc/host/dw_mmc.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 3420a7ad6098..06dc56cbada8 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -2898,7 +2898,12 @@ static int dw_mci_init_slot_caps(struct dw_mci_slot *slot) if (host->pdata->caps2) mmc->caps2 = host->pdata->caps2; - mmc->f_min = DW_MCI_FREQ_MIN; + /* if host has set a minimum_freq, we should respect it */ + if (host->minimum_speed) + mmc->f_min = host->minimum_speed; + else + mmc->f_min = DW_MCI_FREQ_MIN; + if (!mmc->f_max) mmc->f_max = DW_MCI_FREQ_MAX; diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 7f1e38621d13..4ed81f94f7ca 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h @@ -99,6 +99,7 @@ struct dw_mci_dma_slave { * @bus_hz: The rate of @mck in Hz. This forms the basis for MMC bus * rate and timeout calculations. * @current_speed: Configured rate of the controller. + * @minimum_speed: Stored minimum rate of the controller. * @fifoth_val: The value of FIFOTH register. * @verid: Denote Version ID. * @dev: Device associated with the MMC controller. @@ -201,6 +202,7 @@ struct dw_mci { u32 bus_hz; u32 current_speed; + u32 minimum_speed; u32 fifoth_val; u16 verid; struct device *dev; From 52c92286b71e28d88642a4a416f40fbdb6cbb46f Mon Sep 17 00:00:00 2001 From: Peter Geis Date: Sat, 5 Mar 2022 16:58:35 -0500 Subject: [PATCH 113/124] mmc: dw-mmc-rockchip: Fix handling invalid clock rates The Rockchip rk356x ciu clock cannot be set as low as the dw-mmc hardware supports. This leads to a situation during card initialization where the clock is set lower than the clock driver can support. The dw-mmc-rockchip driver spews errors when this happens. For normal operation this only happens a few times during boot, but when cd-broken is enabled (in cases such as the SoQuartz module) this fires multiple times each poll cycle. Fix this by testing the lowest possible frequency that the clock driver can support which is within the mmc specification. Divide that rate by the internal divider and set f_min to this. Signed-off-by: Peter Geis Link: https://lore.kernel.org/r/20220305215835.2210388-3-pgwipeout@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/dw_mmc-rockchip.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 95d0ec0f5f3a..f825487aa739 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -15,7 +15,9 @@ #include "dw_mmc.h" #include "dw_mmc-pltfm.h" -#define RK3288_CLKGEN_DIV 2 +#define RK3288_CLKGEN_DIV 2 + +static const unsigned int freqs[] = { 100000, 200000, 300000, 400000 }; struct dw_mci_rockchip_priv_data { struct clk *drv_clk; @@ -51,7 +53,7 @@ static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) ret = clk_set_rate(host->ciu_clk, cclkin); if (ret) - dev_warn(host->dev, "failed to set rate %uHz\n", ios->clock); + dev_warn(host->dev, "failed to set rate %uHz err: %d\n", cclkin, ret); bus_hz = clk_get_rate(host->ciu_clk) / RK3288_CLKGEN_DIV; if (bus_hz != host->bus_hz) { @@ -290,13 +292,30 @@ static int dw_mci_rk3288_parse_dt(struct dw_mci *host) static int dw_mci_rockchip_init(struct dw_mci *host) { + int ret, i; + /* It is slot 8 on Rockchip SoCs */ host->sdio_id0 = 8; - if (of_device_is_compatible(host->dev->of_node, - "rockchip,rk3288-dw-mshc")) + if (of_device_is_compatible(host->dev->of_node, "rockchip,rk3288-dw-mshc")) { host->bus_hz /= RK3288_CLKGEN_DIV; + /* clock driver will fail if the clock is less than the lowest source clock + * divided by the internal clock divider. Test for the lowest available + * clock and set the minimum freq to clock / clock divider. + */ + + for (i = 0; i < ARRAY_SIZE(freqs); i++) { + ret = clk_round_rate(host->ciu_clk, freqs[i] * RK3288_CLKGEN_DIV); + if (ret > 0) { + host->minimum_speed = ret / RK3288_CLKGEN_DIV; + break; + } + } + if (ret < 0) + dev_warn(host->dev, "no valid minimum freq: %d\n", ret); + } + return 0; } From d268afa1ff6f582dede1819fbed7ded7442a406c Mon Sep 17 00:00:00 2001 From: Minghao Chi Date: Wed, 9 Mar 2022 07:28:34 +0000 Subject: [PATCH 114/124] ata: pata_pxa: Use platform_get_irq() to get the interrupt platform_get_resource(pdev, IORESOURCE_IRQ, ..) relies on static allocation of IRQ resources in DT core code, this causes an issue when using hierarchical interrupt domains using "interrupts" property in the node as this bypasses the hierarchical setup and messes up the irq chaining. In preparation for removal of static setup of IRQ resource from DT core code use platform_get_irq(). Reported-by: Zeal Robot Signed-off-by: Minghao Chi Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_pxa.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index 41430f79663c..985f42c4fd70 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c @@ -164,10 +164,10 @@ static int pxa_ata_probe(struct platform_device *pdev) struct resource *cmd_res; struct resource *ctl_res; struct resource *dma_res; - struct resource *irq_res; struct pata_pxa_pdata *pdata = dev_get_platdata(&pdev->dev); struct dma_slave_config config; int ret = 0; + int irq; /* * Resource validation, three resources are needed: @@ -205,9 +205,9 @@ static int pxa_ata_probe(struct platform_device *pdev) /* * IRQ pin */ - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (unlikely(irq_res == NULL)) - return -EINVAL; + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; /* * Allocate the host @@ -287,7 +287,7 @@ static int pxa_ata_probe(struct platform_device *pdev) /* * Activate the ATA host */ - ret = ata_host_activate(host, irq_res->start, ata_sff_interrupt, + ret = ata_host_activate(host, irq, ata_sff_interrupt, pdata->irq_flags, &pxa_ata_sht); if (ret) dma_release_channel(data->dma_chan); From e23b2f54db1dcdde8302e4ada41805c8297fac27 Mon Sep 17 00:00:00 2001 From: Jesse Taube Date: Mon, 7 Mar 2022 14:34:14 +0000 Subject: [PATCH 115/124] dt-bindings: mmc: sunxi: add Allwinner F1c100s compatible The Allwinner F1C100 series contains two MMC controller blocks. From comparing the data sheets, they seem to be compatible with the one used in the Allwinner A20: the register layout is the same, and they use the same separate sample and output clocks design. The only difference is the missing reset line in the A20 version, but both the binding and the Linux driver make this optional, so it's still a fit. Add the new SoC specific name and require it to be paired with the A20 fallback name, as this is all the driver needs to care about. Signed-off-by: Jesse Taube Signed-off-by: Andre Przywara Acked-by: Rob Herring Acked-by: Samuel Holland Link: https://lore.kernel.org/r/20220307143421.1106209-8-andre.przywara@arm.com Signed-off-by: Ulf Hansson --- .../devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml index 94e2c6c4e4b7..7803597b6366 100644 --- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml +++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml @@ -59,6 +59,9 @@ properties: - items: - const: allwinner,sun50i-h616-mmc - const: allwinner,sun50i-a100-mmc + - items: + - const: allwinner,suniv-f1c100s-mmc + - const: allwinner,sun7i-a20-mmc reg: maxItems: 1 From f9da322e864e5cd3dc217480e73f78f47cf40c5b Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sat, 5 Mar 2022 12:46:57 -0800 Subject: [PATCH 116/124] cgroup: cleanup comments for spdx, add a space before // replacements judgement to judgment transofrmed to transformed partitition to partition histrical to historical migratecd to migrated Signed-off-by: Tom Rix Signed-off-by: Tejun Heo --- kernel/cgroup/cpuset.c | 10 +++++----- kernel/cgroup/freezer.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index dc653ab26e50..8324a8fd71bb 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -71,7 +71,7 @@ DEFINE_STATIC_KEY_FALSE(cpusets_enabled_key); /* * There could be abnormal cpuset configurations for cpu or memory - * node binding, add this key to provide a quick low-cost judgement + * node binding, add this key to provide a quick low-cost judgment * of the situation. */ DEFINE_STATIC_KEY_FALSE(cpusets_insane_config_key); @@ -1151,7 +1151,7 @@ enum subparts_cmd { * effective_cpus. The function will return 0 if all the CPUs listed in * cpus_allowed can be granted or an error code will be returned. * - * For partcmd_disable, the cpuset is being transofrmed from a partition + * For partcmd_disable, the cpuset is being transformed from a partition * root back to a non-partition root. Any CPUs in cpus_allowed that are in * parent's subparts_cpus will be taken away from that cpumask and put back * into parent's effective_cpus. 0 should always be returned. @@ -1990,7 +1990,7 @@ out: } /* - * update_prstate - update partititon_root_state + * update_prstate - update partition_root_state * cs: the cpuset to update * new_prs: new partition root state * @@ -2840,7 +2840,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) /* * Clone @parent's configuration if CGRP_CPUSET_CLONE_CHILDREN is * set. This flag handling is implemented in cgroup core for - * histrical reasons - the flag may be specified during mount. + * historical reasons - the flag may be specified during mount. * * Currently, if any sibling cpusets have exclusive cpus or mem, we * refuse to clone the configuration - thereby refusing the task to @@ -3037,7 +3037,7 @@ hotplug_update_tasks_legacy(struct cpuset *cs, /* * Don't call update_tasks_cpumask() if the cpuset becomes empty, - * as the tasks will be migratecd to an ancestor. + * as the tasks will be migrated to an ancestor. */ if (cpus_updated && !cpumask_empty(cs->cpus_allowed)) update_tasks_cpumask(cs); diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c index 3984dd6b8ddb..617861a54793 100644 --- a/kernel/cgroup/freezer.c +++ b/kernel/cgroup/freezer.c @@ -1,4 +1,4 @@ -//SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0 #include #include #include From 3b6c472822f8bdeaa3cea8290f5b4a210dca5585 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 3 Mar 2022 17:45:22 +0100 Subject: [PATCH 117/124] mmc: core: Improve fallback to speed modes if eMMC HS200 fails In the error path of mmc_select_hs200() we are trying our best to restore the card/host into a valid state. This makes sense, especially if we encounter a simple switch error (-EBADMSG). However, rather than then continue with using the legacy speed mode, let's try the other better speed modes first. Additionally, let's update the card->mmc_avail_type to avoid us from trying a broken HS200 mode again. In an Amlogic S905W based TV box where the switch to HS200 mode fails for the eMMC, this allows us to use the eMMC in DDR mode in favor of the legacy mode, which greatly improves the performance. Suggested-by: Heiner Kallweit Signed-off-by: Ulf Hansson Tested-by: Heiner Kallweit Link: https://lore.kernel.org/r/20220303164522.129583-1-ulf.hansson@linaro.org --- drivers/mmc/core/mmc.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 43d1b9b2fa49..3f5d0d7c021c 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1523,13 +1523,23 @@ static int mmc_select_timing(struct mmc_card *card) if (!mmc_can_ext_csd(card)) goto bus_speed; - if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES) { err = mmc_select_hs400es(card); - else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) + goto out; + } + + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200) { err = mmc_select_hs200(card); - else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) + if (err == -EBADMSG) + card->mmc_avail_type &= ~EXT_CSD_CARD_TYPE_HS200; + else + goto out; + } + + if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS) err = mmc_select_hs(card); +out: if (err && err != -EBADMSG) return err; From d6c9219ca1139b74541b2a98cee47a3426d754a9 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 3 Mar 2022 17:51:42 +0100 Subject: [PATCH 118/124] mmc: host: Return an error when ->enable_sdio_irq() ops is missing Even if the current WARN() notifies the user that something is severely wrong, we can still end up in a PANIC() when trying to invoke the missing ->enable_sdio_irq() ops. Therefore, let's also return an error code and prevent the host from being added. While at it, move the code into a separate function to prepare for subsequent changes and for further host caps validations. Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20220303165142.129745-1-ulf.hansson@linaro.org --- drivers/mmc/core/host.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index cf140f4ec864..d739e2b631fe 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -588,6 +588,16 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) EXPORT_SYMBOL(mmc_alloc_host); +static int mmc_validate_host_caps(struct mmc_host *host) +{ + if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) { + dev_warn(host->parent, "missing ->enable_sdio_irq() ops\n"); + return -EINVAL; + } + + return 0; +} + /** * mmc_add_host - initialise host hardware * @host: mmc host @@ -600,8 +610,9 @@ int mmc_add_host(struct mmc_host *host) { int err; - WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) && - !host->ops->enable_sdio_irq); + err = mmc_validate_host_caps(host); + if (err) + return err; err = device_add(&host->class_dev); if (err) From 23e1b8c15b3ab402bc422338073afc7cf2351788 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Thu, 3 Mar 2022 17:51:51 +0100 Subject: [PATCH 119/124] mmc: core: Drop HS400 caps unless 8-bit bus is supported too When mmc_select_hs400es() tries to switch to the HS400 ES mode, it may bail out early if the host doesn't support an 8-bit buswidth, as it's required for the HS400 mode. To improve the situation, let's instead drop the HS400 bits from the capability field if the 8-bit bus isn't supported. In this way, we allow the mmc initialization to continue by trying a lower speed mode. Signed-off-by: Ulf Hansson Link: https://lore.kernel.org/r/20220303165151.129806-1-ulf.hansson@linaro.org --- drivers/mmc/core/host.c | 13 +++++++++++-- drivers/mmc/core/mmc.c | 5 ----- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index d739e2b631fe..2ed2b4d5e5a5 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -590,11 +590,20 @@ EXPORT_SYMBOL(mmc_alloc_host); static int mmc_validate_host_caps(struct mmc_host *host) { - if (host->caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) { - dev_warn(host->parent, "missing ->enable_sdio_irq() ops\n"); + struct device *dev = host->parent; + u32 caps = host->caps, caps2 = host->caps2; + + if (caps & MMC_CAP_SDIO_IRQ && !host->ops->enable_sdio_irq) { + dev_warn(dev, "missing ->enable_sdio_irq() ops\n"); return -EINVAL; } + if (caps2 & (MMC_CAP2_HS400_ES | MMC_CAP2_HS400) && + !(caps & MMC_CAP_8_BIT_DATA)) { + dev_warn(dev, "drop HS400 support since no 8-bit bus\n"); + host->caps2 = caps2 & ~MMC_CAP2_HS400_ES & ~MMC_CAP2_HS400; + } + return 0; } diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 3f5d0d7c021c..e7ea45386c22 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1355,11 +1355,6 @@ static int mmc_select_hs400es(struct mmc_card *card) int err = -EINVAL; u8 val; - if (!(host->caps & MMC_CAP_8_BIT_DATA)) { - err = -ENOTSUPP; - goto out_err; - } - if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V) err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120); From d607667bb8fa2811679ed2c8a5b09d0d4da8c5b9 Mon Sep 17 00:00:00 2001 From: Ben Chuang Date: Mon, 7 Mar 2022 17:00:09 +0800 Subject: [PATCH 120/124] mmc: sdhci-pci-gli: Add runtime PM for GL9763E Add runtime PM for GL9763E and disable PLL in runtime suspend. So power gated of upstream port can be enabled. GL9763E has an auxiliary power so it keep states in runtime suspend. In runtime resume, PLL is enabled and waits for it to stabilize. Signed-off-by: Ben Chuang Tested-by: Kevin Chang Acked-by: Adrian Hunter Link: https://lore.kernel.org/r/20220307090009.1386876-1-benchuanggli@gmail.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-pci-gli.c | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c index ab099cdb081c..d09728c37d03 100644 --- a/drivers/mmc/host/sdhci-pci-gli.c +++ b/drivers/mmc/host/sdhci-pci-gli.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "sdhci.h" #include "sdhci-pci.h" #include "cqhci.h" @@ -951,6 +952,47 @@ static void gli_set_gl9763e(struct sdhci_pci_slot *slot) pci_write_config_dword(pdev, PCIE_GLI_9763E_VHS, value); } +#ifdef CONFIG_PM +static int gl9763e_runtime_suspend(struct sdhci_pci_chip *chip) +{ + struct sdhci_pci_slot *slot = chip->slots[0]; + struct sdhci_host *host = slot->host; + u16 clock; + + clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + clock &= ~(SDHCI_CLOCK_PLL_EN | SDHCI_CLOCK_CARD_EN); + sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL); + + return 0; +} + +static int gl9763e_runtime_resume(struct sdhci_pci_chip *chip) +{ + struct sdhci_pci_slot *slot = chip->slots[0]; + struct sdhci_host *host = slot->host; + u16 clock; + + clock = sdhci_readw(host, SDHCI_CLOCK_CONTROL); + + clock |= SDHCI_CLOCK_PLL_EN; + clock &= ~SDHCI_CLOCK_INT_STABLE; + sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL); + + /* Wait max 150 ms */ + if (read_poll_timeout(sdhci_readw, clock, (clock & SDHCI_CLOCK_INT_STABLE), + 1000, 150000, false, host, SDHCI_CLOCK_CONTROL)) { + pr_err("%s: PLL clock never stabilised.\n", + mmc_hostname(host->mmc)); + sdhci_dumpregs(host); + } + + clock |= SDHCI_CLOCK_CARD_EN; + sdhci_writew(host, clock, SDHCI_CLOCK_CONTROL); + + return 0; +} +#endif + static int gli_probe_slot_gl9763e(struct sdhci_pci_slot *slot) { struct pci_dev *pdev = slot->chip->pdev; @@ -1060,6 +1102,11 @@ const struct sdhci_pci_fixes sdhci_gl9763e = { #ifdef CONFIG_PM_SLEEP .resume = sdhci_cqhci_gli_resume, .suspend = sdhci_cqhci_gli_suspend, +#endif +#ifdef CONFIG_PM + .runtime_suspend = gl9763e_runtime_suspend, + .runtime_resume = gl9763e_runtime_resume, + .allow_runtime_pm = true, #endif .add_host = gl9763e_add_host, }; From 09e7af76db02c74f2a339b3cb2d95460fa2ddbe4 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 8 Mar 2022 15:14:15 +0800 Subject: [PATCH 121/124] mmc: davinci_mmc: Handle error for clk_enable As the potential failure of the clk_enable(), it should be better to check it and return error if fails. Fixes: bbce5802afc5 ("davinci: mmc: updates to suspend/resume implementation") Signed-off-by: Jiasheng Jiang Link: https://lore.kernel.org/r/20220308071415.1093393-1-jiasheng@iscas.ac.cn Signed-off-by: Ulf Hansson --- drivers/mmc/host/davinci_mmc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 0cf646ec9a80..7138dfa065bf 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c @@ -1373,8 +1373,12 @@ static int davinci_mmcsd_suspend(struct device *dev) static int davinci_mmcsd_resume(struct device *dev) { struct mmc_davinci_host *host = dev_get_drvdata(dev); + int ret; + + ret = clk_enable(host->clk); + if (ret) + return ret; - clk_enable(host->clk); mmc_davinci_reset_ctrl(host, 0); return 0; From 33106d78b4c0981ec3f21674d6736852785b5ddf Mon Sep 17 00:00:00 2001 From: Alexandre Bailon Date: Fri, 11 Mar 2022 11:33:20 +0100 Subject: [PATCH 122/124] mmc: mtk-sd: Silence delay phase calculation debug log The driver prints the following log everytime data is written to RPMB: mtk-msdc 11230000.mmc: phase: [map:ffffffff] [maxlen:32] [final:10] dev_info is used to print that log but it seems that log is only useful for debbuging. Use dev_dbg instead of dev_info. Signed-off-by: Alexandre Bailon Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20220311103320.3072171-1-abailon@baylibre.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/mtk-sd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c index 65037e1d7723..e61b0b98065a 100644 --- a/drivers/mmc/host/mtk-sd.c +++ b/drivers/mmc/host/mtk-sd.c @@ -1911,8 +1911,8 @@ static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay) final_phase = (start_final + len_final / 3) % PAD_DELAY_MAX; else final_phase = (start_final + len_final / 2) % PAD_DELAY_MAX; - dev_info(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n", - delay, len_final, final_phase); + dev_dbg(host->dev, "phase: [map:%x] [maxlen:%d] [final:%d]\n", + delay, len_final, final_phase); delay_phase.maxlen = len_final; delay_phase.start = start_final; From 11b51bff0a2e347ec14d27a76c6430cb98f0207a Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 11 Mar 2022 15:05:42 +0100 Subject: [PATCH 123/124] mmc: tmio: remove outdated members from host struct The wrappers are gone for two years now but they have still pointers reserved in the tmio_mmc_host struct. Remove them. Reported-by: Yoshihiro Shimoda Fixes: f22084b662e5 ("mmc: tmio: remove superfluous callback wrappers") Signed-off-by: Wolfram Sang Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20220311140542.5407-1-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/tmio_mmc.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index f936aad945ce..e754bb3f5c32 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -186,10 +186,6 @@ struct tmio_mmc_host { void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq); unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host); - void (*prepare_hs400_tuning)(struct tmio_mmc_host *host); - void (*hs400_downgrade)(struct tmio_mmc_host *host); - void (*hs400_complete)(struct tmio_mmc_host *host); - const struct tmio_mmc_dma_ops *dma_ops; }; From dc3d879c6ffa25e90875237265898e49b2cabb7e Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 15 Mar 2022 15:32:58 +0000 Subject: [PATCH 124/124] dt-bindings: mmc: renesas,sdhi: Document RZ/G2UL SoC Document RZ/G2UL SDHI bindings. RZ/G2UL SDHI is almost identical to one found on the R-Car Gen3. No driver changes are required as generic compatible string "renesas,rcar-gen3-sdhi" will be used as a fallback. Signed-off-by: Biju Das Reviewed-by: Lad Prabhakar Reviewed-by: Geert Uytterhoeven Acked-by: Wolfram Sang Link: https://lore.kernel.org/r/20220315153258.21097-1-biju.das.jz@bp.renesas.com Signed-off-by: Ulf Hansson --- Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml index 3b191fb89cf1..9ac4986988c5 100644 --- a/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml +++ b/Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml @@ -57,6 +57,7 @@ properties: - renesas,sdhi-r8a77990 # R-Car E3 - renesas,sdhi-r8a77995 # R-Car D3 - renesas,sdhi-r8a779a0 # R-Car V3U + - renesas,sdhi-r9a07g043 # RZ/G2UL - renesas,sdhi-r9a07g044 # RZ/G2{L,LC} - renesas,sdhi-r9a07g054 # RZ/V2L - const: renesas,rcar-gen3-sdhi # R-Car Gen3 or RZ/G2 @@ -109,6 +110,7 @@ allOf: compatible: contains: enum: + - renesas,sdhi-r9a07g043 - renesas,sdhi-r9a07g044 - renesas,sdhi-r9a07g054 then: