From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id CD54EC433F5 for ; Mon, 28 Feb 2022 19:12:31 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id A2E9783CEE; Mon, 28 Feb 2022 20:11:25 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="bKHe9ZPX"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 3F13483BC3; Mon, 28 Feb 2022 20:09:41 +0100 (CET) Received: from mail-oi1-x233.google.com (mail-oi1-x233.google.com [IPv6:2607:f8b0:4864:20::233]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id ED54F83C6F for ; Mon, 28 Feb 2022 20:09:18 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=sjg@chromium.org Received: by mail-oi1-x233.google.com with SMTP id j2so14096827oie.7 for ; Mon, 28 Feb 2022 11:09:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fcljhd8GlptyDBnSTh2pmNIT4U+aDCMyi0bm/ffLoRw=; b=bKHe9ZPX9mWzSlC0yJVJZqozW2nJChbq/K91Zg3ZsE4GmGYvKlsBwwh8l7A3e/uHUN 2xz6/GpdJ7+sE2vSrvlLl68oxfBiLA8MYU3WBFw0gP/15GOKKECtmeCzBhowQiPY7eP3 nz2iSn1O0CEa80CGkCbkBcNh4gbvhHk16EnGc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fcljhd8GlptyDBnSTh2pmNIT4U+aDCMyi0bm/ffLoRw=; b=wLATJCpQb1R1CeUgLDzxOBe7RIi75EAm6ppaRnWSEBznLOMpA1KOhM4AvYLNNqbiK7 p9ztyawlXbQcnCb66D7opd7mePGSuQWiEAzBSeVI8inLlMKLSjE2j69dYCm+CDlOxV8v cSH4XNAPQ4Izm/PZtmOwb4WPzAZKfq7eYwdK3+0t6zuIwNBd3eMwhOJpiGSm4D97XQzv tlQnJqYrFGgiA46ygcrcomOazwZjtkwMWYzK07vFpf5C8ekBhnCOk3om5Qt4z/FKi8jH TenpveVybhLFp1NhTrOhD5KtPsh9iW8wwsSMv2ARK1+Nrn7lqDZwF9pbm0KSzpzDDQZz BGTA== X-Gm-Message-State: AOAM532KSvKtr3TrTSbZws6yYQMWWaLayKt9cyfwnnVBxnnHxilnHsMx eclIXSEARRg0PP4JMeTtxHd5msqW5UFt0A== X-Google-Smtp-Source: ABdhPJyKDnhOnvyPzCqYSoGO55zQjKP29RHKCNt0Lc6/c9INIKh8NlQkLsPFsLf/lunkUlW2cxjoFg== X-Received: by 2002:a05:6808:2095:b0:2d5:328d:f61b with SMTP id s21-20020a056808209500b002d5328df61bmr11833471oiw.9.1646075357453; Mon, 28 Feb 2022 11:09:17 -0800 (PST) Received: from kiwi.bld.corp.google.com (c-67-190-101-114.hsd1.co.comcast.net. [67.190.101.114]) by smtp.gmail.com with ESMTPSA id f188-20020a4a58c5000000b0031ccb8272f1sm5290577oob.33.2022.02.28.11.09.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Feb 2022 11:09:17 -0800 (PST) From: Simon Glass To: U-Boot Mailing List Cc: Tom Rini , Simon Glass , AKASHI Takahiro , Heinrich Schuchardt , Marek Vasut , Masahisa Kojima , Patrick Delaunay , Pavel Herrmann Subject: [PATCH 18/18] dm: blk: Expand iteration and add tests Date: Mon, 28 Feb 2022 12:08:35 -0700 Message-Id: <20220228190835.1480772-19-sjg@chromium.org> X-Mailer: git-send-email 2.35.1.574.g5d30c73bfb-goog In-Reply-To: <20220228190835.1480772-1-sjg@chromium.org> References: <20220228190835.1480772-1-sjg@chromium.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.5 at phobos.denx.de X-Virus-Status: Clean Add some functions which support iteration before probing. Also add tests for the functions. Signed-off-by: Simon Glass --- drivers/block/blk-uclass.c | 24 ++++++++ include/blk.h | 45 +++++++++++++++ test/dm/blk.c | 111 +++++++++++++++++++++++++++++++++++++ 3 files changed, 180 insertions(+) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index bee1cd6f0d..84502bb47c 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -552,6 +552,30 @@ static int blk_flags_check(struct udevice *dev, enum blk_flag_t req_flags) return flags & req_flags ? 0 : 1; } +int blk_find_first(enum blk_flag_t flags, struct udevice **devp) +{ + int ret; + + for (ret = uclass_find_first_device(UCLASS_BLK, devp); + *devp && !blk_flags_check(*devp, flags); + ret = uclass_find_next_device(devp)) + return 0; + + return -ENODEV; +} + +int blk_find_next(enum blk_flag_t flags, struct udevice **devp) +{ + int ret; + + for (ret = uclass_find_next_device(devp); + *devp && !blk_flags_check(*devp, flags); + ret = uclass_find_next_device(devp)) + return 0; + + return -ENODEV; +} + int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp) { int ret; diff --git a/include/blk.h b/include/blk.h index d06098bc13..dbe9ae219d 100644 --- a/include/blk.h +++ b/include/blk.h @@ -731,6 +731,51 @@ int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp); */ int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp); +/** + * blk_find_first() - Return the first matching block device + * @flags: Indicates type of device to return + * @devp: Returns pointer to device, or NULL on error + * + * The device is not prepared for use - this is an internal function. + * The function uclass_get_device_tail() can be used to probe the device. + * + * Note that some devices are considered removable until they have been probed + * + * @return 0 if found, -ENODEV if not found + */ +int blk_find_first(enum blk_flag_t flags, struct udevice **devp); + +/** + * blk_find_next() - Return the next matching block device + * @flags: Indicates type of device to return + * @devp: On entry, pointer to device to lookup. On exit, returns pointer + * to the next device in the same uclass, or NULL if none + * + * The device is not prepared for use - this is an internal function. + * The function uclass_get_device_tail() can be used to probe the device. + * + * Note that some devices are considered removable until they have been probed + * + * @return 0 if found, -ENODEV if not found + */ +int blk_find_next(enum blk_flag_t flags, struct udevice **devp); + +/** + * blk_foreach() - iterate through block devices + * + * This creates a for() loop which works through the available block devices in + * order from start to end. + * + * If for some reason the uclass cannot be found, this does nothing. + * + * @_flags: Indicates type of device to return + * @_pos: struct udevice * to hold the current device. Set to NULL when there + * are no more devices. + */ +#define blk_foreach(_flags, _pos) \ + for (int _ret = blk_find_first(_flags, &_pos); !_ret && _pos; \ + _ret = blk_find_next(_flags, &_pos)) + /** * blk_foreach_probe() - Helper function to iteration through block devices * diff --git a/test/dm/blk.c b/test/dm/blk.c index deccf05289..8556cc7159 100644 --- a/test/dm/blk.c +++ b/test/dm/blk.c @@ -217,3 +217,114 @@ static int dm_test_blk_iter(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_blk_iter, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test finding fixed/removable block devices */ +static int dm_test_blk_flags(struct unit_test_state *uts) +{ + struct udevice *dev; + + /* Iterate through devices without probing them */ + ut_assertok(blk_find_first(BLKF_BOTH, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc2.blk", dev->name); + + ut_assertok(blk_find_next(BLKF_BOTH, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc1.blk", dev->name); + + ut_assertok(blk_find_next(BLKF_BOTH, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc0.blk", dev->name); + + ut_asserteq(-ENODEV, blk_find_next(BLKF_BOTH, &dev)); + ut_assertnull(dev); + + /* All devices are removable until probed */ + ut_asserteq(-ENODEV, blk_find_first(BLKF_FIXED, &dev)); + + ut_assertok(blk_find_first(BLKF_REMOVABLE, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc2.blk", dev->name); + + /* Now probe them and iterate again */ + ut_assertok(blk_first_device_err(BLKF_BOTH, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc2.blk", dev->name); + + ut_assertok(blk_next_device_err(BLKF_BOTH, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc1.blk", dev->name); + + ut_assertok(blk_next_device_err(BLKF_BOTH, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc0.blk", dev->name); + + ut_asserteq(-ENODEV, blk_next_device_err(BLKF_BOTH, &dev)); + + /* Look only for fixed devices */ + ut_assertok(blk_first_device_err(BLKF_FIXED, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc2.blk", dev->name); + + ut_asserteq(-ENODEV, blk_next_device_err(BLKF_FIXED, &dev)); + + /* Look only for removable devices */ + ut_assertok(blk_first_device_err(BLKF_REMOVABLE, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc1.blk", dev->name); + + ut_assertok(blk_next_device_err(BLKF_REMOVABLE, &dev)); + ut_assertnonnull(dev); + ut_asserteq_str("mmc0.blk", dev->name); + + ut_asserteq(-ENODEV, blk_next_device_err(BLKF_REMOVABLE, &dev)); + + return 0; +} +DM_TEST(dm_test_blk_flags, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test blk_foreach() and friend */ +static int dm_test_blk_foreach(struct unit_test_state *uts) +{ + struct udevice *dev; + int found; + + /* Test blk_foreach() - use the 3rd bytes of the name (0/1/2) */ + found = 0; + blk_foreach(BLKF_BOTH, dev) + found |= 1 << dectoul(&dev->name[3], NULL); + ut_asserteq(7, found); + + /* All devices are removable until probed */ + found = 0; + blk_foreach(BLKF_FIXED, dev) + found |= 1 << dectoul(&dev->name[3], NULL); + ut_asserteq(0, found); + + found = 0; + blk_foreach(BLKF_REMOVABLE, dev) + found |= 1 << dectoul(&dev->name[3], NULL); + ut_asserteq(7, found); + + /* Now try again with the probing functions */ + found = 0; + blk_foreach_probe(BLKF_BOTH, dev) + found |= 1 << dectoul(&dev->name[3], NULL); + ut_asserteq(7, found); + ut_asserteq(3, blk_count_devices(BLKF_BOTH)); + + found = 0; + blk_foreach_probe(BLKF_FIXED, dev) + found |= 1 << dectoul(&dev->name[3], NULL); + ut_asserteq(4, found); + ut_asserteq(1, blk_count_devices(BLKF_FIXED)); + + found = 0; + blk_foreach_probe(BLKF_REMOVABLE, dev) + found |= 1 << dectoul(&dev->name[3], NULL); + ut_asserteq(3, found); + ut_asserteq(2, blk_count_devices(BLKF_REMOVABLE)); + + return 0; +} +DM_TEST(dm_test_blk_foreach, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -- 2.35.1.574.g5d30c73bfb-goog