diff --git a/Runner/plans/qcom-next-ci-premerge.yaml b/Runner/plans/qcom-next-ci-premerge.yaml index 188d839a..de31f1ba 100755 --- a/Runner/plans/qcom-next-ci-premerge.yaml +++ b/Runner/plans/qcom-next-ci-premerge.yaml @@ -48,6 +48,16 @@ run: - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/smmu/smmu.res || true - $PWD/suites/Kernel/Baseport/Storage/UFS_Validation/run.sh || true - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/Storage/UFS_Validation/UFS_Validation.res || true + - $PWD/suites/Kernel/Baseport/Storage/ufs_gear_lane/run.sh || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/Storage/ufs_gear_lane/ufs_gear_lane.res || true + - $PWD/suites/Kernel/Baseport/Storage/ufs_hibern8/run.sh || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/Storage/ufs_hibern8/ufs_hibern8.res || true + - $PWD/suites/Kernel/Baseport/Storage/ufs_read_writes/run.sh || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/Storage/ufs_read_writes/ufs_read_writes.res || true + - $PWD/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/run.sh || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/ufs_runtime_suspend_resume.res || true + - $PWD/suites/Kernel/Baseport/Storage/ufs_write_booster/run.sh || true + - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/Storage/ufs_write_booster/ufs_write_booster.res || true - $PWD/suites/Kernel/Baseport/wpss_remoteproc/run.sh || true - $PWD/utils/send-to-lava.sh $PWD/suites/Kernel/Baseport/wpss_remoteproc/wpss_remoteproc.res || true - $PWD/suites/Kernel/DCVS/Freq_Scaling/run.sh || true diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_gear_lane/README.md b/Runner/suites/Kernel/Baseport/Storage/ufs_gear_lane/README.md new file mode 100644 index 00000000..4afd7b15 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_gear_lane/README.md @@ -0,0 +1,42 @@ +# UFS Gear/Lane Validation +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies the UFS Gear & Lane based on the UFS spec supported by the device on application of load to UFS driver. + +The test script performs these functional checks: + +1. **Kernel Configuration**: + - Validates presence of `CONFIG_SCSI_UFS_QCOM`, `CONFIG_SCSI_UFSHCD` and entries in `/proc/config.gz`. + +2. **Read UFS Specification Version**: + - Reads the UFS specification version from `/sys/devices/platform/soc@0/1d84000.ufs/device_descriptor/specification_version` + - Based on the UFS specification version decides the max operating gear. + +2. **Runtime Verification**: + - Checks `/sys/devices/platform/soc@0/1d84000.ufs/power_info/gear` on application of load whether the operating gear is same as max supported gear. + +## How to Run + +```sh +source init_env +cd suites/Kernel/Baseport/Storage/ufs_gear_lane +./run.sh +``` + +## Prerequisites + +- `dd`, `grep`, `dmesg`, `lsmod`, `cut`, `head`, `tail`, `udevadm`, `sleep` must be available +- Root access may be required for complete validation + +## Result Format + +Test result will be saved in `ufs_gear_lane.res` as: +- `UFS Gear Validation Successful. Test Passed` – if all validations pass +- `UFS Gear did not reach max gear on load. Test Failed` – if any check fails + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_gear_lane/run.sh b/Runner/suites/Kernel/Baseport/Storage/ufs_gear_lane/run.sh new file mode 100755 index 00000000..daa522dc --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_gear_lane/run.sh @@ -0,0 +1,266 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# Always source functestlib.sh +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="ufs_gear_lane" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +res_file="./$TESTNAME.res" + +log_info "--------------------------------------------------" +log_info "------------- Starting $TESTNAME Test ------------" + +check_dependencies dd grep cut head tail udevadm sleep + +MANDATORY_CONFIGS="CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM" +OPTIONAL_CONFIGS="CONFIG_SCSI_UFSHCD_PLATFORM CONFIG_SCSI_UFSHCD_PCI CONFIG_SCSI_UFS_CDNS_PLATFORM CONFIG_SCSI_UFS_HISI CONFIG_SCSI_UFS_EXYNOS CONFIG_SCSI_UFS_ROCKCHIP CONFIG_SCSI_UFS_BSG" + +log_info "Checking mandatory kernel configs for UFS..." +if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then + log_skip "Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "Checking optional kernel configs for UFS..." +missing_optional="" +for cfg in $OPTIONAL_CONFIGS; do + if ! check_kernel_config "$cfg" 2>/dev/null; then + log_info "[OPTIONAL] $cfg is not enabled" + missing_optional="$missing_optional $cfg" + fi +done +[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional" + +check_dt_nodes "/sys/bus/platform/devices/*ufs*" || { + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +} + +block_dev=$(detect_ufs_partition_block) +if [ -z "$block_dev" ]; then + log_skip "No UFS block device found." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Detected UFS block: $block_dev" + +if command -v findmnt >/dev/null 2>&1; then + rootfs_dev=$(findmnt -n -o SOURCE /) +else + log_warn "findmnt not available, using fallback rootfs detection" + rootfs_dev=$(awk '$2 == "/" { print $1 }' /proc/mounts) +fi + +resolved_block=$(readlink -f "$block_dev" 2>/dev/null) +resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null) + +if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then + log_warn "Detected block ($resolved_block) is the root filesystem. Skipping read test." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +# Function to get the first matching node path +get_dt_node_path() { + node_pattern="$1" + found_node="" + + for node in $node_pattern; do + if [ -d "$node" ] || [ -f "$node" ]; then + found_node="$node" + break + fi + done + + printf "%s" "$found_node" +} + +# Get UFS gear based on specification version +get_ufs_gear() { + spec_version="$1" + gear="" + + case "$spec_version" in + 0x0100) # UFS 1.0 + gear="1" + ;; + 0x0110) # UFS 1.1 + gear="1" + ;; + 0x0200) # UFS 2.0 + gear="2" + ;; + 0x0210) # UFS 2.1 + gear="3" + ;; + 0x0220) # UFS 2.2 + gear="3" + ;; + 0x0300) # UFS 3.0 + gear="4" + ;; + 0x0310) # UFS 3.1 + gear="4" + ;; + 0x0400) # UFS 4.0 + gear="5" + ;; + 0x0410) # UFS 4.1 + gear="5" + ;; + *) + log_warn "Unknown UFS specification version: $spec_version" + return 1 + ;; + esac + printf "%s" "$gear" +} + +log_info "Validating UFS Gear & Lane on load & no-load conditions" + +# Check for UFS Spec Version node and assign to variable +log_info "Checking for UFS device descriptor specification_version node..." +if ! check_dt_nodes "/sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version"; then + log_skip "UFS device descriptor specification_version node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +SPEC_VERSION=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version") +if [ -z "$SPEC_VERSION" ]; then + log_skip "Failed to get specification_version node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found specification version node: $SPEC_VERSION" + +# Check for UFS Gear node and assign to variable +log_info "Checking for UFS Gear node..." +if ! check_dt_nodes "/sys/devices/platform/soc@0/*ufs*/power_info/gear"; then + log_skip "UFS Gear status node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +GEAR_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/power_info/gear") +if [ -z "$GEAR_NODE" ]; then + log_skip "Failed to get gear node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found gear node: $GEAR_NODE" + +# Check for UFS Lane node and assign to variable +log_info "Checking for UFS Lane node..." +if ! check_dt_nodes "/sys/devices/platform/soc@0/*ufs*/power_info/lane"; then + log_skip "UFS Lane status node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +LANE_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/power_info/lane") +if [ -z "$LANE_NODE" ]; then + log_skip "Failed to get lane node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found lane node: $LANE_NODE" + +# Get UFS version and determine expected gear +spec_version_value=$(cat "$SPEC_VERSION" 2>/dev/null) +if [ -z "$spec_version_value" ]; then + log_fail "Failed to read specification version from $SPEC_VERSION" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_info "UFS Specification Version: $spec_version_value" + +EXPECTED_GEAR=$(get_ufs_gear "$spec_version_value") +if [ -z "$EXPECTED_GEAR" ]; then + log_fail "Failed to determine expected gear for spec version $spec_version_value" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_info "Expected UFS Gear: HS_GEAR$EXPECTED_GEAR" + +# Start dd command in background and check gear/lane under load +log_info "Starting I/O load test to verify UFS Gear and Lane under load..." +tmpfile="/ufs_gear_lane.tmp" + +# Start dd in background +dd if=/dev/zero of="$tmpfile" bs=3M count=1024 >/dev/null 2>&1 & +DD_PID=$! + +sleep 1 + +# Read current gear and lane values +CURRENT_GEAR=$(cat "$GEAR_NODE" 2>/dev/null | tr -d '[:space:]') +CURRENT_LANE=$(cat "$LANE_NODE" 2>/dev/null | tr -d '[:space:]') + +wait $DD_PID 2>/dev/null + +# Clean up temp file +rm -f "$tmpfile" + +log_info "Current UFS Gear under load: $CURRENT_GEAR" +log_info "Current UFS Lane under load: $CURRENT_LANE" + +# Verify gear and lane values +if [ -z "$CURRENT_GEAR" ] || [ -z "$CURRENT_LANE" ]; then + log_fail "Failed to read current gear or lane values" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +# Check if gear matches expected and lane is 2 +if [ "$CURRENT_GEAR" = "HS_GEAR$EXPECTED_GEAR" ] && [ "$CURRENT_LANE" = "2" ]; then + log_pass "UFS Gear and Lane validation passed" + log_info "Gear: $CURRENT_GEAR (Expected: HS_GEAR$EXPECTED_GEAR)" + log_info "Lane: $CURRENT_LANE (Expected: 2)" + scan_dmesg_errors "ufs" "$test_path" + echo "$TESTNAME PASS" > "$res_file" +else + log_fail "UFS Gear and Lane validation failed" + if [ "$CURRENT_GEAR" != "HS_GEAR$EXPECTED_GEAR" ]; then + log_fail "Gear mismatch: Current=$CURRENT_GEAR, Expected=HS_GEAR$EXPECTED_GEAR" + fi + if [ "$CURRENT_LANE" != "2" ]; then + log_fail "Lane mismatch: Current=$CURRENT_LANE, Expected=2" + fi + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +scan_dmesg_errors "ufs" "$test_path" +log_pass "$TESTNAME completed successfully" +echo "$TESTNAME PASS" > "$res_file" +exit 0 \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_hibern8/README.md b/Runner/suites/Kernel/Baseport/Storage/ufs_hibern8/README.md new file mode 100644 index 00000000..e205c6e4 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_hibern8/README.md @@ -0,0 +1,45 @@ +# UFS Hibern8 Validation +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies the UFS Hibern8/Active state transitions on load and no-load conditions. + +The test script performs these functional checks: + +1. **Kernel Configuration**: + - Validates presence of `CONFIG_SCSI_UFS_QCOM`, `CONFIG_SCSI_UFSHCD` and entries in `/proc/config.gz`. + +2. **UFS Link State Verification**: + - Checks the UFS link state in `/sys/bus/platform/devices/*ufs*/power_info/link_state` + - Verifies the link state is "ACTIVE" during I/O load + - Verifies the link state transitions to "HIBERN8" after an idle period + +3. **Runtime Verification**: + - Generates I/O load using `dd` command and monitors link state + - Creates an idle time to allow Hibern8 entry + - Validates proper state transitions between active and hibernation states + +## How to Run + +```sh +source init_env +cd suites/Kernel/Baseport/Storage/ufs_hibern8 +./run.sh +``` + +## Prerequisites + +- `dd`, `grep`, `dmesg`, `cut`, `head`, `tail`, `udevadm`, `sleep` must be available +- Root access may be required for complete validation + +## Result Format + +Test result will be saved in `ufs_hibern8.res` as: +- `ufs_hibern8 PASS` – if link state is ACTIVE on application of load & HIBERN8 when idle +- `ufs_hibern8 FAIL` – if any check fails + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_hibern8/run.sh b/Runner/suites/Kernel/Baseport/Storage/ufs_hibern8/run.sh new file mode 100755 index 00000000..d7180610 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_hibern8/run.sh @@ -0,0 +1,189 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# Always source functestlib.sh +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="ufs_hibern8" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +res_file="./$TESTNAME.res" + +log_info "--------------------------------------------------" +log_info "------------- Starting $TESTNAME Test ------------" + +check_dependencies dd grep cut head tail udevadm sleep + +MANDATORY_CONFIGS="CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM" +OPTIONAL_CONFIGS="CONFIG_SCSI_UFSHCD_PLATFORM CONFIG_SCSI_UFSHCD_PCI CONFIG_SCSI_UFS_CDNS_PLATFORM CONFIG_SCSI_UFS_HISI CONFIG_SCSI_UFS_EXYNOS CONFIG_SCSI_UFS_ROCKCHIP CONFIG_SCSI_UFS_BSG" + +log_info "Checking mandatory kernel configs for UFS..." +if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then + log_skip "Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "Checking optional kernel configs for UFS..." +missing_optional="" +for cfg in $OPTIONAL_CONFIGS; do + if ! check_kernel_config "$cfg" 2>/dev/null; then + log_info "[OPTIONAL] $cfg is not enabled" + missing_optional="$missing_optional $cfg" + fi +done +[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional" + +check_dt_nodes "/sys/bus/platform/devices/*ufs*" || { + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +} + +block_dev=$(detect_ufs_partition_block) +if [ -z "$block_dev" ]; then + log_skip "No UFS block device found." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Detected UFS block: $block_dev" + +if command -v findmnt >/dev/null 2>&1; then + rootfs_dev=$(findmnt -n -o SOURCE /) +else + log_warn "findmnt not available, using fallback rootfs detection" + rootfs_dev=$(awk '$2 == "/" { print $1 }' /proc/mounts) +fi + +resolved_block=$(readlink -f "$block_dev" 2>/dev/null) +resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null) + +if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then + log_warn "Detected block ($resolved_block) is the root filesystem. Skipping read test." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +# Function to get the first matching node path +get_dt_node_path() { + node_pattern="$1" + found_node="" + + for node in $node_pattern; do + if [ -d "$node" ] || [ -f "$node" ]; then + found_node="$node" + break + fi + done + + printf "%s" "$found_node" +} + +log_info "Validating UFS Hibern8/Active state on load & no-load conditions" + +# Check for UFS Hibern8 link state node and assign to variable +log_info "Checking for UFS Hibern8 link state node..." +if ! check_dt_nodes "/sys/bus/platform/devices/*ufs*/power_info/link_state"; then + log_skip "UFS Hibern8 link state node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +HIBERN8_STATE_NODE=$(get_dt_node_path "/sys/bus/platform/devices/*ufs*/power_info/link_state") +if [ -z "$HIBERN8_STATE_NODE" ]; then + log_skip "Failed to get Hibern8 link state node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found Hibern8 link state node: $HIBERN8_STATE_NODE" + +# Step 2: Generate load using dd command and check for ACTIVE state +log_info "Starting I/O load test to verify UFS link ACTIVE state..." +tmpfile="/ufs_hibern8_test.tmp" + +# Start dd in background +dd if=/dev/zero of="$tmpfile" bs=3M count=1024 >/dev/null 2>&1 & +DD_PID=$! + +# Wait 1 second for I/O to ramp up +sleep 1 + +# Read Hibern8 link state during load +HIBERN8_STATE_LOAD=$(cat "$HIBERN8_STATE_NODE" 2>/dev/null | tr -d '[:space:]') +log_info "Hibern8 link state under load: $HIBERN8_STATE_LOAD" + +# Verify the state is "ACTIVE" during load +if [ "$HIBERN8_STATE_LOAD" != "ACTIVE" ]; then + log_fail "UFS link state is not 'ACTIVE' during load. Current state: $HIBERN8_STATE_LOAD" + kill "$DD_PID" 2>/dev/null + wait "$DD_PID" 2>/dev/null + rm -f "$tmpfile" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "UFS link state is 'ACTIVE' during load" + +# Wait for dd command to complete +log_info "Waiting for dd command to complete..." +wait "$DD_PID" +DD_EXIT_CODE=$? + +# Clean up temp file +rm -f "$tmpfile" + +if [ $DD_EXIT_CODE -ne 0 ]; then + log_fail "dd command failed with exit code: $DD_EXIT_CODE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "dd command completed successfully" + +# Step 3: Wait for 60 seconds for Hibern8 entry +log_info "Waiting 60 seconds for UFS to enter Hibern8 state..." +sleep 60 + +# Step 4: Check Hibern8 link state after idle period +HIBERN8_STATE_IDLE=$(cat "$HIBERN8_STATE_NODE" 2>/dev/null | tr -d '[:space:]') +log_info "Hibern8 link state after 60 seconds idle: $HIBERN8_STATE_IDLE" + +# Verify the state is "HIBERN8" after idle period +if [ "$HIBERN8_STATE_IDLE" != "HIBERN8" ]; then + log_fail "UFS link state is not 'HIBERN8' after idle period. Current state: $HIBERN8_STATE_IDLE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "UFS link state is 'HIBERN8' after idle period" + +# Final validation +log_pass "UFS Hibern8/Active state validation passed" +log_info "Link state during load: $HIBERN8_STATE_LOAD (Expected: ACTIVE)" +log_info "Link state after idle: $HIBERN8_STATE_IDLE (Expected: HIBERN8)" + +scan_dmesg_errors "ufs" "$test_path" +log_pass "$TESTNAME completed successfully" +echo "$TESTNAME PASS" > "$res_file" +exit 0 \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_read_writes/README.md b/Runner/suites/Kernel/Baseport/Storage/ufs_read_writes/README.md new file mode 100644 index 00000000..55dc94c4 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_read_writes/README.md @@ -0,0 +1,43 @@ +# UFS Read/Writes +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies whether basic UFS file read writes are functional. + +The test script performs these functional checks: + +1. **Kernel Configuration**: + - Validates presence of `CONFIG_SCSI_UFS_QCOM`, `CONFIG_SCSI_UFSHCD` and entries in `/proc/config.gz`. + +2. **UFS Block Device Detection**: + - Detects UFS block devices using `detect_ufs_partition_block()` + - Verifies the detected block is not the root filesystem + +3. **Runtime Verification**: + - Performs basic read test on the UFS block device using `dd` + - Runs I/O stress test with 64MB read and write operations on a temporary file + +## How to Run + +```sh +source init_env +cd suites/Kernel/Baseport/Storage/ufs_read_writes +./run.sh +``` + +## Prerequisites + +- `dd`, `grep`, `cut`, `head`, `tail`, `udevadm` must be available +- Root access may be required for complete validation + +## Result Format + +Test result will be saved in `ufs_read_writes.res` as: +- `ufs_read_writes PASS` – if read/writes are successful +- `ufs_read_writes FAIL` – if any check fails + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_read_writes/run.sh b/Runner/suites/Kernel/Baseport/Storage/ufs_read_writes/run.sh new file mode 100755 index 00000000..4623b0f1 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_read_writes/run.sh @@ -0,0 +1,146 @@ +#!/bin/sh + +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# Always source functestlib.sh +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="ufs_read_writes" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +res_file="./$TESTNAME.res" + +log_info "--------------------------------------------------" +log_info "------------- Starting $TESTNAME Test ------------" + +check_dependencies dd grep cut head tail udevadm + +MANDATORY_CONFIGS="CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM" +OPTIONAL_CONFIGS="CONFIG_SCSI_UFSHCD_PLATFORM CONFIG_SCSI_UFSHCD_PCI CONFIG_SCSI_UFS_CDNS_PLATFORM CONFIG_SCSI_UFS_HISI CONFIG_SCSI_UFS_EXYNOS CONFIG_SCSI_UFS_ROCKCHIP CONFIG_SCSI_UFS_BSG" + +log_info "Checking mandatory kernel configs for UFS..." +if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then + log_skip "Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "Checking optional kernel configs for UFS..." +missing_optional="" +for cfg in $OPTIONAL_CONFIGS; do + if ! check_kernel_config "$cfg" 2>/dev/null; then + log_info "[OPTIONAL] $cfg is not enabled" + missing_optional="$missing_optional $cfg" + fi +done +[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional" + +check_dt_nodes "/sys/bus/platform/devices/*ufs*" || { + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +} + +block_dev=$(detect_ufs_partition_block) +if [ -z "$block_dev" ]; then + log_skip "No UFS block device found." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Detected UFS block: $block_dev" + +if command -v findmnt >/dev/null 2>&1; then + rootfs_dev=$(findmnt -n -o SOURCE /) +else + log_warn "findmnt not available, using fallback rootfs detection" + rootfs_dev=$(awk '$2 == "/" { print $1 }' /proc/mounts) +fi + +resolved_block=$(readlink -f "$block_dev" 2>/dev/null) +resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null) + +if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then + log_warn "Detected block ($resolved_block) is the root filesystem. Skipping read test." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "Running basic read test on $block_dev (non-rootfs)..." +if echo | dd of=/dev/null iflag=direct 2>/dev/null; then + DD_CMD="dd if=$block_dev of=/dev/null bs=1M count=32 iflag=direct" +else + log_warn "'iflag=direct' not supported by dd. Falling back to standard dd." + DD_CMD="dd if=$block_dev of=/dev/null bs=1M count=32" +fi + +if $DD_CMD >/dev/null 2>&1; then + log_pass "UFS read test succeeded" +else + log_fail "UFS read test failed" + log_info "Try manually: $DD_CMD" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +log_info "Running I/O stress test (64MB read+write on tmpfile)..." +tmpfile="$test_path/ufs_test.img" + +if echo | dd of=/dev/null conv=fsync 2>/dev/null; then + DD_WRITE="dd if=/dev/zero of=$tmpfile bs=1M count=64 conv=fsync" +else + log_warn "'conv=fsync' not supported by dd. Using basic write." + DD_WRITE="dd if=/dev/zero of=$tmpfile bs=1M count=64" +fi + +if $DD_WRITE >/dev/null 2>&1 && + dd if="$tmpfile" of=/dev/null bs=1M count=64 >/dev/null 2>&1; then + log_pass "UFS I/O stress test passed" + if command -v stat >/dev/null 2>&1; then + stat --format="[INFO] Size: %s bytes File: %n" "$tmpfile" + else + find "$tmpfile" -printf "[INFO] Size: %s bytes File: %p\n" + fi + rm -f "$tmpfile" +else + log_fail "UFS I/O stress test failed" + df -h . | sed 's/^/[INFO] /' + if [ -f "$tmpfile" ]; then + if command -v stat >/dev/null 2>&1; then + stat --format="[INFO] Size: %s bytes File: %n" "$tmpfile" + else + find "$tmpfile" -printf "[INFO] Size: %s bytes File: %p\n" + fi + rm -f "$tmpfile" + fi + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi + +scan_dmesg_errors "ufs" "$test_path" +log_pass "$TESTNAME completed successfully" +echo "$TESTNAME PASS" > "$res_file" +exit 0 diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/README.md b/Runner/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/README.md new file mode 100644 index 00000000..ce813b99 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/README.md @@ -0,0 +1,45 @@ +# UFS Runtime Suspend/Resume Validation +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies the UFS Runtime Suspend/Resume functionality on load and no-load conditions. + +The test script performs these functional checks: + +1. **Kernel Configuration**: + - Validates presence of `CONFIG_SCSI_UFS_QCOM`, `CONFIG_SCSI_UFSHCD` and entries in `/proc/config.gz`. + +2. **UFS Runtime Status Verification**: + - Checks the UFS runtime status in `/sys/devices/platform/soc@0/*ufs*/power/runtime_status` + - Verifies the runtime status is "active" during I/O load + - Verifies the runtime status transitions to "suspended" after an idle period + +3. **Runtime Verification**: + - Generates I/O load using `dd` command and monitors runtime status + - Creates an idle time to allow runtime suspend + - Validates proper state transitions between active and suspended states + +## How to Run + +```sh +source init_env +cd suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume +./run.sh +``` + +## Prerequisites + +- `dd`, `grep`, `cut`, `head`, `tail`, `udevadm`, `sleep` must be available +- Root access may be required for complete validation + +## Result Format + +Test result will be saved in `ufs_runtime_suspend_resume.res` as: +- `ufs_runtime_suspend_resume PASS` – if runtime status is active on application of load & suspended when idle +- `ufs_runtime_suspend_resume FAIL` – if any check fails + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/run.sh b/Runner/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/run.sh new file mode 100755 index 00000000..5202e71c --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_runtime_suspend_resume/run.sh @@ -0,0 +1,188 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# Always source functestlib.sh +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="ufs_runtime_suspend_resume" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +res_file="./$TESTNAME.res" + +log_info "--------------------------------------------------" +log_info "------------- Starting $TESTNAME Test ------------" + +check_dependencies dd grep cut head tail udevadm sleep + +MANDATORY_CONFIGS="CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM" +OPTIONAL_CONFIGS="CONFIG_SCSI_UFSHCD_PLATFORM CONFIG_SCSI_UFSHCD_PCI CONFIG_SCSI_UFS_CDNS_PLATFORM CONFIG_SCSI_UFS_HISI CONFIG_SCSI_UFS_EXYNOS CONFIG_SCSI_UFS_ROCKCHIP CONFIG_SCSI_UFS_BSG" + +log_info "Checking mandatory kernel configs for UFS..." +if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then + log_skip "Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "Checking optional kernel configs for UFS..." +missing_optional="" +for cfg in $OPTIONAL_CONFIGS; do + if ! check_kernel_config "$cfg" 2>/dev/null; then + log_info "[OPTIONAL] $cfg is not enabled" + missing_optional="$missing_optional $cfg" + fi +done +[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional" + +check_dt_nodes "/sys/bus/platform/devices/*ufs*" || { + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +} + +block_dev=$(detect_ufs_partition_block) +if [ -z "$block_dev" ]; then + log_skip "No UFS block device found." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Detected UFS block: $block_dev" + +if command -v findmnt >/dev/null 2>&1; then + rootfs_dev=$(findmnt -n -o SOURCE /) +else + log_warn "findmnt not available, using fallback rootfs detection" + rootfs_dev=$(awk '$2 == "/" { print $1 }' /proc/mounts) +fi + +resolved_block=$(readlink -f "$block_dev" 2>/dev/null) +resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null) + +if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then + log_warn "Detected block ($resolved_block) is the root filesystem. Skipping read test." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +# Function to get the first matching node path +get_dt_node_path() { + node_pattern="$1" + found_node="" + + for node in $node_pattern; do + if [ -d "$node" ] || [ -f "$node" ]; then + found_node="$node" + break + fi + done + + printf "%s" "$found_node" +} + +log_info "Validating UFS Runtime/Suspend on load & no-load conditions" +# Check for UFS runtime status node and assign to variable +log_info "Checking for UFS runtime status node..." +if ! check_dt_nodes "/sys/devices/platform/soc@0/*ufs*/power/runtime_status"; then + log_skip "UFS runtime status node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +RUNTIME_STATUS_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/power/runtime_status") +if [ -z "$RUNTIME_STATUS_NODE" ]; then + log_skip "Failed to get runtime status node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found runtime status node: $RUNTIME_STATUS_NODE" + +# Step 2: Generate load using dd command and check for active state +log_info "Starting I/O load test to verify UFS runtime active state..." +tmpfile="/ufs_runtime_test.tmp" + +# Start dd in background +dd if=/dev/zero of="$tmpfile" bs=3M count=1024 >/dev/null 2>&1 & +DD_PID=$! + +# Wait 0.5 seconds for I/O to ramp up +sleep 1 + +# Read runtime status during load +RUNTIME_STATUS_LOAD=$(cat "$RUNTIME_STATUS_NODE" 2>/dev/null | tr -d '[:space:]') +log_info "Runtime status under load: $RUNTIME_STATUS_LOAD" + +# Verify the status is "active" during load +if [ "$RUNTIME_STATUS_LOAD" != "active" ]; then + log_fail "UFS runtime status is not 'active' during load. Current status: $RUNTIME_STATUS_LOAD" + kill "$DD_PID" 2>/dev/null + wait "$DD_PID" 2>/dev/null + rm -f "$tmpfile" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "UFS runtime status is 'active' during load" + +# Wait for dd command to complete +log_info "Waiting for dd command to complete..." +wait "$DD_PID" +DD_EXIT_CODE=$? + +# Clean up temp file +rm -f "$tmpfile" + +if [ $DD_EXIT_CODE -ne 0 ]; then + log_fail "dd command failed with exit code: $DD_EXIT_CODE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "dd command completed successfully" + +# Step 3: Wait for 60 seconds for runtime suspend +log_info "Waiting 60 seconds for UFS to enter runtime suspend..." +sleep 60 + +# Step 4: Check runtime status after idle period +RUNTIME_STATUS_IDLE=$(cat "$RUNTIME_STATUS_NODE" 2>/dev/null | tr -d '[:space:]') +log_info "Runtime status after 60 seconds idle: $RUNTIME_STATUS_IDLE" + +# Verify the status is "suspended" after idle period +if [ "$RUNTIME_STATUS_IDLE" != "suspended" ]; then + log_fail "UFS runtime status is not 'suspended' after idle period. Current status: $RUNTIME_STATUS_IDLE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "UFS runtime status is 'suspended' after idle period" + +# Final validation +log_pass "UFS Runtime Suspend/Resume validation passed" +log_info "Status during load: $RUNTIME_STATUS_LOAD (Expected: active)" +log_info "Status after idle: $RUNTIME_STATUS_IDLE (Expected: suspended)" + +scan_dmesg_errors "ufs" "$test_path" +log_pass "$TESTNAME completed successfully" +echo "$TESTNAME PASS" > "$res_file" +exit 0 \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_write_booster/README.md b/Runner/suites/Kernel/Baseport/Storage/ufs_write_booster/README.md new file mode 100644 index 00000000..f0b927a7 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_write_booster/README.md @@ -0,0 +1,43 @@ +# UFS Write Booster Validation +## Overview + +This shell script executes on the DUT (Device-Under-Test) and verifies the UFS Write Booster feature activation on application of write load to UFS driver. + +The test script performs these functional checks: + +1. **Kernel Configuration**: + - Validates presence of `CONFIG_SCSI_UFS_QCOM`, `CONFIG_SCSI_UFSHCD` and entries in `/proc/config.gz`. + +2. **Read UFS Specification Version**: + - Reads the UFS specification version from `/sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version` + - Verifies the UFS specification version is 3.1 (0x0310) or higher, which supports Write Booster feature + +3. **Runtime Verification**: + - Checks `/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/device/wb_on` on application of load + - Verifies Write Booster is enabled (value = 1) during write operations + +## How to Run + +```sh +source init_env +cd suites/Kernel/Baseport/Storage/ufs_write_booster +./run.sh +``` + +## Prerequisites + +- `dd`, `grep`, `cut`, `head`, `tail`, `udevadm`, `sleep` must be available +- Root access may be required for complete validation + +## Result Format + +Test result will be saved in `ufs_write_booster.res` as: +- `ufs_write_booster PASS` – if Write Booster is enabled during write operations +- `ufs_write_booster FAIL` – if any check fails + +## License + +``` +Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +SPDX-License-Identifier: BSD-3-Clause-Clear +``` \ No newline at end of file diff --git a/Runner/suites/Kernel/Baseport/Storage/ufs_write_booster/run.sh b/Runner/suites/Kernel/Baseport/Storage/ufs_write_booster/run.sh new file mode 100755 index 00000000..65a2be31 --- /dev/null +++ b/Runner/suites/Kernel/Baseport/Storage/ufs_write_booster/run.sh @@ -0,0 +1,224 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause-Clear + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# Always source functestlib.sh +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="ufs_write_booster" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +res_file="./$TESTNAME.res" + +log_info "--------------------------------------------------" +log_info "------------- Starting $TESTNAME Test ------------" + +check_dependencies dd grep cut head tail udevadm sleep + +MANDATORY_CONFIGS="CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM" +OPTIONAL_CONFIGS="CONFIG_SCSI_UFSHCD_PLATFORM CONFIG_SCSI_UFSHCD_PCI CONFIG_SCSI_UFS_CDNS_PLATFORM CONFIG_SCSI_UFS_HISI CONFIG_SCSI_UFS_EXYNOS CONFIG_SCSI_UFS_ROCKCHIP CONFIG_SCSI_UFS_BSG" + +log_info "Checking mandatory kernel configs for UFS..." +if ! check_kernel_config "$MANDATORY_CONFIGS" 2>/dev/null; then + log_skip "Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "Checking optional kernel configs for UFS..." +missing_optional="" +for cfg in $OPTIONAL_CONFIGS; do + if ! check_kernel_config "$cfg" 2>/dev/null; then + log_info "[OPTIONAL] $cfg is not enabled" + missing_optional="$missing_optional $cfg" + fi +done +[ -n "$missing_optional" ] && log_info "Optional configs not present but continuing:$missing_optional" + +check_dt_nodes "/sys/bus/platform/devices/*ufs*" || { + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +} + +block_dev=$(detect_ufs_partition_block) +if [ -z "$block_dev" ]; then + log_skip "No UFS block device found." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Detected UFS block: $block_dev" + +if command -v findmnt >/dev/null 2>&1; then + rootfs_dev=$(findmnt -n -o SOURCE /) +else + log_warn "findmnt not available, using fallback rootfs detection" + rootfs_dev=$(awk '$2 == "/" { print $1 }' /proc/mounts) +fi + +resolved_block=$(readlink -f "$block_dev" 2>/dev/null) +resolved_rootfs=$(readlink -f "$rootfs_dev" 2>/dev/null) + +if [ -n "$resolved_block" ] && [ -n "$resolved_rootfs" ] && [ "$resolved_block" = "$resolved_rootfs" ]; then + log_warn "Detected block ($resolved_block) is the root filesystem. Skipping read test." + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +# Function to get the first matching node path +get_dt_node_path() { + node_pattern="$1" + found_node="" + + for node in $node_pattern; do + if [ -d "$node" ] || [ -f "$node" ]; then + found_node="$node" + break + fi + done + + printf "%s" "$found_node" +} + +# Function to compare UFS specification versions +# Returns 0 if version1 >= version2, 1 otherwise +compare_ufs_version() { + version1="$1" + version2="$2" + + # Convert hex to decimal for comparison + ver1_dec=$((version1)) + ver2_dec=$((version2)) + + if [ "$ver1_dec" -ge "$ver2_dec" ]; then + return 0 + else + return 1 + fi +} + +log_info "Validating UFS Write Booster feature" + +# Check for UFS Spec Version node and assign to variable +log_info "Checking for UFS device descriptor specification_version node..." +if ! check_dt_nodes "/sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version"; then + log_skip "UFS device descriptor specification_version node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +SPEC_VERSION=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version") +if [ -z "$SPEC_VERSION" ]; then + log_skip "Failed to get specification_version node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found specification version node: $SPEC_VERSION" + +# Get UFS version +spec_version_value=$(cat "$SPEC_VERSION" 2>/dev/null) +if [ -z "$spec_version_value" ]; then + log_fail "Failed to read specification version from $SPEC_VERSION" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_info "UFS Specification Version: $spec_version_value" + +# Check if UFS version is 3.1 or higher (0x0310) +if ! compare_ufs_version "$spec_version_value" "0x0310"; then + log_skip "Write booster feature is supported from and after UFS spec 3.1" + log_info "Current UFS spec version: $spec_version_value (Required: >= 0x0310)" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +log_info "UFS spec version $spec_version_value supports Write Booster feature" + +# Check for Write Booster status node +log_info "Checking for UFS Write Booster status node..." +if ! check_dt_nodes "/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/device/wb_on"; then + log_skip "UFS Write Booster status node not found" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi + +WB_STATUS_NODE=$(get_dt_node_path "/sys/devices/platform/soc@0/*ufs*/devfreq/*ufs*/device/wb_on") +if [ -z "$WB_STATUS_NODE" ]; then + log_skip "Failed to get Write Booster status node path" + echo "$TESTNAME SKIP" > "$res_file" + exit 0 +fi +log_info "Found Write Booster status node: $WB_STATUS_NODE" + +# Generate load using dd command and check Write Booster status +log_info "Starting I/O load test to verify Write Booster activation..." +tmpfile="/ufs_wb_test.tmp" + +# Start dd in background +dd if=/dev/zero of="$tmpfile" bs=3M count=1024 >/dev/null 2>&1 & +DD_PID=$! + +# Wait 1 second for I/O to ramp up +sleep 1 + +# Read Write Booster status during load +WB_STATUS=$(cat "$WB_STATUS_NODE" 2>/dev/null | tr -d '[:space:]') +log_info "Write Booster status under load: $WB_STATUS" + +# Verify the Write Booster is enabled (value should be 1) +if [ "$WB_STATUS" != "1" ]; then + log_fail "UFS Write Booster is not enabled during load. Current status: $WB_STATUS (Expected: 1)" + kill "$DD_PID" 2>/dev/null + wait "$DD_PID" 2>/dev/null + rm -f "$tmpfile" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "UFS Write Booster is enabled during load" + +# Wait for dd command to complete +log_info "Waiting for dd command to complete..." +wait "$DD_PID" +DD_EXIT_CODE=$? + +# Clean up temp file +rm -f "$tmpfile" + +if [ $DD_EXIT_CODE -ne 0 ]; then + log_fail "dd command failed with exit code: $DD_EXIT_CODE" + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi +log_pass "dd command completed successfully" + +# Final validation +log_pass "UFS Write Booster validation passed" +log_info "Write Booster status during load: $WB_STATUS (Expected: 1)" + +scan_dmesg_errors "ufs" "$test_path" +log_pass "$TESTNAME completed successfully" +echo "$TESTNAME PASS" > "$res_file" +exit 0 \ No newline at end of file