1+ #! /bin/sh
2+
3+ # Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4+ # SPDX-License-Identifier: BSD-3-Clause-Clear
5+
6+ # Robustly find and source init_env
7+ SCRIPT_DIR=" $( cd " $( dirname " $0 " ) " && pwd) "
8+ INIT_ENV=" "
9+ SEARCH=" $SCRIPT_DIR "
10+ while [ " $SEARCH " != " /" ]; do
11+ if [ -f " $SEARCH /init_env" ]; then
12+ INIT_ENV=" $SEARCH /init_env"
13+ break
14+ fi
15+ SEARCH=$( dirname " $SEARCH " )
16+ done
17+
18+ if [ -z " $INIT_ENV " ]; then
19+ echo " [ERROR] Could not find init_env (starting at $SCRIPT_DIR )" >&2
20+ exit 1
21+ fi
22+
23+ # Only source if not already loaded
24+ if [ -z " $__INIT_ENV_LOADED " ]; then
25+ # shellcheck disable=SC1090
26+ . " $INIT_ENV "
27+ fi
28+
29+ # Always source functestlib.sh
30+ # shellcheck disable=SC1090,SC1091
31+ . " $TOOLS /functestlib.sh"
32+
33+ TESTNAME=" ufs_gear_lane"
34+ test_path=$( find_test_case_by_name " $TESTNAME " )
35+ cd " $test_path " || exit 1
36+ res_file=" ./$TESTNAME .res"
37+
38+ log_info " --------------------------------------------------"
39+ log_info " ------------- Starting $TESTNAME Test ------------"
40+
41+ check_dependencies dd grep cut head tail udevadm sleep
42+
43+ MANDATORY_CONFIGS=" CONFIG_SCSI_UFSHCD CONFIG_SCSI_UFS_QCOM"
44+ 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"
45+
46+ log_info " Checking mandatory kernel configs for UFS..."
47+ if ! check_kernel_config " $MANDATORY_CONFIGS " 2> /dev/null; then
48+ log_skip " Missing mandatory UFS kernel configs: $MANDATORY_CONFIGS "
49+ echo " $TESTNAME SKIP" > " $res_file "
50+ exit 0
51+ fi
52+
53+ log_info " Checking optional kernel configs for UFS..."
54+ missing_optional=" "
55+ for cfg in $OPTIONAL_CONFIGS ; do
56+ if ! check_kernel_config " $cfg " 2> /dev/null; then
57+ log_info " [OPTIONAL] $cfg is not enabled"
58+ missing_optional=" $missing_optional $cfg "
59+ fi
60+ done
61+ [ -n " $missing_optional " ] && log_info " Optional configs not present but continuing:$missing_optional "
62+
63+ check_dt_nodes " /sys/bus/platform/devices/*ufs*" || {
64+ echo " $TESTNAME SKIP" > " $res_file "
65+ exit 0
66+ }
67+
68+ block_dev=$( detect_ufs_partition_block)
69+ if [ -z " $block_dev " ]; then
70+ log_skip " No UFS block device found."
71+ echo " $TESTNAME SKIP" > " $res_file "
72+ exit 0
73+ fi
74+ log_info " Detected UFS block: $block_dev "
75+
76+ if command -v findmnt > /dev/null 2>&1 ; then
77+ rootfs_dev=$( findmnt -n -o SOURCE /)
78+ else
79+ log_warn " findmnt not available, using fallback rootfs detection"
80+ rootfs_dev=$( awk ' $2 == "/" { print $1 }' /proc/mounts)
81+ fi
82+
83+ resolved_block=$( readlink -f " $block_dev " 2> /dev/null)
84+ resolved_rootfs=$( readlink -f " $rootfs_dev " 2> /dev/null)
85+
86+ if [ -n " $resolved_block " ] && [ -n " $resolved_rootfs " ] && [ " $resolved_block " = " $resolved_rootfs " ]; then
87+ log_warn " Detected block ($resolved_block ) is the root filesystem. Skipping read test."
88+ echo " $TESTNAME SKIP" > " $res_file "
89+ exit 0
90+ fi
91+
92+ # Function to get the first matching node path
93+ get_dt_node_path () {
94+ node_pattern=" $1 "
95+ found_node=" "
96+
97+ for node in $node_pattern ; do
98+ if [ -d " $node " ] || [ -f " $node " ]; then
99+ found_node=" $node "
100+ break
101+ fi
102+ done
103+
104+ printf " %s" " $found_node "
105+ }
106+
107+ # Get UFS gear based on specification version
108+ get_ufs_gear () {
109+ spec_version=" $1 "
110+ gear=" "
111+
112+ case " $spec_version " in
113+ 0x0100) # UFS 1.0
114+ gear=" 1"
115+ ;;
116+ 0x0110) # UFS 1.1
117+ gear=" 1"
118+ ;;
119+ 0x0200) # UFS 2.0
120+ gear=" 2"
121+ ;;
122+ 0x0210) # UFS 2.1
123+ gear=" 3"
124+ ;;
125+ 0x0220) # UFS 2.2
126+ gear=" 3"
127+ ;;
128+ 0x0300) # UFS 3.0
129+ gear=" 4"
130+ ;;
131+ 0x0310) # UFS 3.1
132+ gear=" 4"
133+ ;;
134+ 0x0400) # UFS 4.0
135+ gear=" 5"
136+ ;;
137+ 0x0410) # UFS 4.1
138+ gear=" 5"
139+ ;;
140+ * )
141+ log_warn " Unknown UFS specification version: $spec_version "
142+ return 1
143+ ;;
144+ esac
145+ printf " %s" " $gear "
146+ }
147+
148+ log_info " Validating UFS Gear & Lane on load & no-load conditions"
149+
150+ # Check for UFS Spec Version node and assign to variable
151+ log_info " Checking for UFS device descriptor specification_version node..."
152+ if ! check_dt_nodes " /sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version" ; then
153+ log_skip " UFS device descriptor specification_version node not found"
154+ echo " $TESTNAME SKIP" > " $res_file "
155+ exit 0
156+ fi
157+
158+ SPEC_VERSION=$( get_dt_node_path " /sys/devices/platform/soc@0/*ufs*/device_descriptor/specification_version" )
159+ if [ -z " $SPEC_VERSION " ]; then
160+ log_skip " Failed to get specification_version node path"
161+ echo " $TESTNAME SKIP" > " $res_file "
162+ exit 0
163+ fi
164+ log_info " Found specification version node: $SPEC_VERSION "
165+
166+ # Check for UFS Gear node and assign to variable
167+ log_info " Checking for UFS Gear node..."
168+ if ! check_dt_nodes " /sys/devices/platform/soc@0/*ufs*/power_info/gear" ; then
169+ log_skip " UFS Gear status node not found"
170+ echo " $TESTNAME SKIP" > " $res_file "
171+ exit 0
172+ fi
173+
174+ GEAR_NODE=$( get_dt_node_path " /sys/devices/platform/soc@0/*ufs*/power_info/gear" )
175+ if [ -z " $GEAR_NODE " ]; then
176+ log_skip " Failed to get gear node path"
177+ echo " $TESTNAME SKIP" > " $res_file "
178+ exit 0
179+ fi
180+ log_info " Found gear node: $GEAR_NODE "
181+
182+ # Check for UFS Lane node and assign to variable
183+ log_info " Checking for UFS Lane node..."
184+ if ! check_dt_nodes " /sys/devices/platform/soc@0/*ufs*/power_info/lane" ; then
185+ log_skip " UFS Lane status node not found"
186+ echo " $TESTNAME SKIP" > " $res_file "
187+ exit 0
188+ fi
189+
190+ LANE_NODE=$( get_dt_node_path " /sys/devices/platform/soc@0/*ufs*/power_info/lane" )
191+ if [ -z " $LANE_NODE " ]; then
192+ log_skip " Failed to get lane node path"
193+ echo " $TESTNAME SKIP" > " $res_file "
194+ exit 0
195+ fi
196+ log_info " Found lane node: $LANE_NODE "
197+
198+ # Get UFS version and determine expected gear
199+ spec_version_value=$( cat " $SPEC_VERSION " 2> /dev/null)
200+ if [ -z " $spec_version_value " ]; then
201+ log_fail " Failed to read specification version from $SPEC_VERSION "
202+ echo " $TESTNAME FAIL" > " $res_file "
203+ exit 1
204+ fi
205+ log_info " UFS Specification Version: $spec_version_value "
206+
207+ EXPECTED_GEAR=$( get_ufs_gear " $spec_version_value " )
208+ if [ -z " $EXPECTED_GEAR " ]; then
209+ log_fail " Failed to determine expected gear for spec version $spec_version_value "
210+ echo " $TESTNAME FAIL" > " $res_file "
211+ exit 1
212+ fi
213+ log_info " Expected UFS Gear: HS_GEAR$EXPECTED_GEAR "
214+
215+ # Start dd command in background and check gear/lane under load
216+ log_info " Starting I/O load test to verify UFS Gear and Lane under load..."
217+ tmpfile=" /ufs_gear_lane.tmp"
218+
219+ # Start dd in background
220+ dd if=/dev/zero of=" $tmpfile " bs=3M count=1024 > /dev/null 2>&1 &
221+ DD_PID=$!
222+
223+ sleep 1
224+
225+ # Read current gear and lane values
226+ CURRENT_GEAR=$( cat " $GEAR_NODE " 2> /dev/null | tr -d ' [:space:]' )
227+ CURRENT_LANE=$( cat " $LANE_NODE " 2> /dev/null | tr -d ' [:space:]' )
228+
229+ wait $DD_PID 2> /dev/null
230+
231+ # Clean up temp file
232+ rm -f " $tmpfile "
233+
234+ log_info " Current UFS Gear under load: $CURRENT_GEAR "
235+ log_info " Current UFS Lane under load: $CURRENT_LANE "
236+
237+ # Verify gear and lane values
238+ if [ -z " $CURRENT_GEAR " ] || [ -z " $CURRENT_LANE " ]; then
239+ log_fail " Failed to read current gear or lane values"
240+ echo " $TESTNAME FAIL" > " $res_file "
241+ exit 1
242+ fi
243+
244+ # Check if gear matches expected and lane is 2
245+ if [ " $CURRENT_GEAR " = " HS_GEAR$EXPECTED_GEAR " ] && [ " $CURRENT_LANE " = " 2" ]; then
246+ log_pass " UFS Gear and Lane validation passed"
247+ log_info " Gear: $CURRENT_GEAR (Expected: HS_GEAR$EXPECTED_GEAR )"
248+ log_info " Lane: $CURRENT_LANE (Expected: 2)"
249+ scan_dmesg_errors " ufs" " $test_path "
250+ echo " $TESTNAME PASS" > " $res_file "
251+ else
252+ log_fail " UFS Gear and Lane validation failed"
253+ if [ " $CURRENT_GEAR " != " HS_GEAR$EXPECTED_GEAR " ]; then
254+ log_fail " Gear mismatch: Current=$CURRENT_GEAR , Expected=HS_GEAR$EXPECTED_GEAR "
255+ fi
256+ if [ " $CURRENT_LANE " != " 2" ]; then
257+ log_fail " Lane mismatch: Current=$CURRENT_LANE , Expected=2"
258+ fi
259+ echo " $TESTNAME FAIL" > " $res_file "
260+ exit 1
261+ fi
262+
263+ scan_dmesg_errors " ufs" " $test_path "
264+ log_pass " $TESTNAME completed successfully"
265+ echo " $TESTNAME PASS" > " $res_file "
266+ exit 0
0 commit comments