|
| 1 | +#!/bin/sh |
| 2 | +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. |
| 3 | +# SPDX-License-Identifier: BSD-3-Clause-Clear |
| 4 | +# Sensor helpers (DT-free): discovery via ssc_sensor_info, run see_workhorse/ssc_drva_test, parse PASS/FAIL. |
| 5 | + |
| 6 | +# Global outputs set by sensors_check_adsp_remoteproc() |
| 7 | +SENSORS_ADSP_FW="" |
| 8 | +SENSORS_ADSP_RPROC_PATH="" |
| 9 | +SENSORS_ADSP_STATE="" |
| 10 | + |
| 11 | +sensors__trim_ws() { |
| 12 | + # usage: sensors__trim_ws " abc " -> prints "abc" |
| 13 | + # shellcheck disable=SC2001 |
| 14 | + echo "$1" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' |
| 15 | +} |
| 16 | + |
| 17 | +# Append a line to a newline-separated list if it doesn't already exist. |
| 18 | +# usage: new_list="$(sensors_append_unique_line "$list" "accel")" |
| 19 | +sensors_append_unique_line() { |
| 20 | + list="$1" |
| 21 | + line="$2" |
| 22 | + |
| 23 | + [ -z "$line" ] && { printf '%s\n' "$list"; return 0; } |
| 24 | + |
| 25 | + if [ -z "$list" ]; then |
| 26 | + printf '%s\n' "$line" |
| 27 | + return 0 |
| 28 | + fi |
| 29 | + |
| 30 | + printf '%s\n' "$list" | grep -Fxq "$line" 2>/dev/null && { |
| 31 | + printf '%s\n' "$list" |
| 32 | + return 0 |
| 33 | + } |
| 34 | + |
| 35 | + printf '%s\n%s\n' "$list" "$line" |
| 36 | +} |
| 37 | + |
| 38 | +sensors__firmware_exists_quick() { |
| 39 | + fw="$1" |
| 40 | + [ -z "$fw" ] && return 1 |
| 41 | + # quick/cheap checks only (avoid heavy find): |
| 42 | + [ -f "/lib/firmware/$fw" ] && return 0 |
| 43 | + [ -f "/lib/firmware/qcom/$fw" ] && return 0 |
| 44 | + [ -f "/lib/firmware/qcom/qcs6490/$fw" ] && return 0 |
| 45 | + [ -f "/vendor/firmware/$fw" ] && return 0 |
| 46 | + [ -f "/vendor/firmware_mnt/image/$fw" ] && return 0 |
| 47 | + return 1 |
| 48 | +} |
| 49 | + |
| 50 | +# Return codes: |
| 51 | +# 0 = running |
| 52 | +# 1 = remoteproc found but not running |
| 53 | +# 2 = remoteproc not running and firmware missing |
| 54 | +# 3 = remoteproc not found (by firmware mapping) |
| 55 | +sensors_check_adsp_remoteproc() { |
| 56 | + fw="${1:-adsp.mbn}" |
| 57 | + |
| 58 | + # NOTE: these are intentionally "output variables" for the caller (run.sh) |
| 59 | + # shellcheck disable=SC2034 |
| 60 | + SENSORS_ADSP_FW="$fw" |
| 61 | + # shellcheck disable=SC2034 |
| 62 | + SENSORS_ADSP_RPROC_PATH="" |
| 63 | + SENSORS_ADSP_STATE="" |
| 64 | + |
| 65 | + if ! command -v get_remoteproc_path_by_firmware >/dev/null 2>&1; then |
| 66 | + return 3 |
| 67 | + fi |
| 68 | + |
| 69 | + rpath="$(get_remoteproc_path_by_firmware "$fw" 2>/dev/null || true)" |
| 70 | + if [ -z "$rpath" ] || [ ! -d "$rpath" ]; then |
| 71 | + return 3 |
| 72 | + fi |
| 73 | + |
| 74 | + # shellcheck disable=SC2034 |
| 75 | + SENSORS_ADSP_RPROC_PATH="$rpath" |
| 76 | + |
| 77 | + if command -v get_remoteproc_state >/dev/null 2>&1; then |
| 78 | + SENSORS_ADSP_STATE="$(get_remoteproc_state "$rpath" 2>/dev/null || true)" |
| 79 | + SENSORS_ADSP_STATE="$(sensors__trim_ws "$SENSORS_ADSP_STATE")" |
| 80 | + else |
| 81 | + if [ -r "$rpath/state" ]; then |
| 82 | + SENSORS_ADSP_STATE="$(cat "$rpath/state" 2>/dev/null || true)" |
| 83 | + SENSORS_ADSP_STATE="$(sensors__trim_ws "$SENSORS_ADSP_STATE")" |
| 84 | + fi |
| 85 | + fi |
| 86 | + |
| 87 | + [ "$SENSORS_ADSP_STATE" = "running" ] && return 0 |
| 88 | + |
| 89 | + if sensors__firmware_exists_quick "$fw"; then |
| 90 | + return 1 |
| 91 | + fi |
| 92 | + return 2 |
| 93 | +} |
| 94 | + |
| 95 | +sensors_dump_ssc_sensor_info() { |
| 96 | + out_file="$1" |
| 97 | + : >"$out_file" 2>/dev/null || true |
| 98 | + ssc_sensor_info >"$out_file" 2>&1 |
| 99 | + return $? |
| 100 | +} |
| 101 | + |
| 102 | +sensors_types_from_ssc_file() { |
| 103 | + f="$1" |
| 104 | + [ -r "$f" ] || return 1 |
| 105 | + |
| 106 | + awk ' |
| 107 | + function trim(s) { sub(/^[ \t\r\n]+/, "", s); sub(/[ \t\r\n]+$/, "", s); return s } |
| 108 | + /^TYPE[[:space:]]*=/ { |
| 109 | + type = $0 |
| 110 | + sub(/^TYPE[[:space:]]*=[[:space:]]*/, "", type) |
| 111 | + type = trim(type) |
| 112 | + } |
| 113 | + /^AVAILABLE[[:space:]]*=/ { |
| 114 | + avail = $0 |
| 115 | + sub(/^AVAILABLE[[:space:]]*=[[:space:]]*/, "", avail) |
| 116 | + avail = trim(avail) |
| 117 | + } |
| 118 | + /^PHYSICAL_SENSOR[[:space:]]*=/ { |
| 119 | + phys = $0 |
| 120 | + sub(/^PHYSICAL_SENSOR[[:space:]]*=[[:space:]]*/, "", phys) |
| 121 | + phys = trim(phys) |
| 122 | + } |
| 123 | + /^$/ { |
| 124 | + if (type != "" && avail == "true") { |
| 125 | + if (phys == "" || phys == "true") print type |
| 126 | + } |
| 127 | + type=""; avail=""; phys="" |
| 128 | + } |
| 129 | + END { |
| 130 | + if (type != "" && avail == "true") { |
| 131 | + if (phys == "" || phys == "true") print type |
| 132 | + } |
| 133 | + } |
| 134 | + ' "$f" 2>/dev/null | sort -u |
| 135 | +} |
| 136 | + |
| 137 | +sensors_type_present() { |
| 138 | + types_nl="$1" |
| 139 | + needle="$2" |
| 140 | + printf '%s\n' "$types_nl" | grep -Fxq "$needle" 2>/dev/null |
| 141 | +} |
| 142 | + |
| 143 | +# Run a command in background, redirect all output to logfile, and print a heartbeat. |
| 144 | +# sensors_run_cmd_with_progress <logfile> <label> <duration_sec> <heartbeat_sec> -- <cmd...> |
| 145 | +sensors_run_cmd_with_progress() { |
| 146 | + logf="$1" |
| 147 | + label="$2" |
| 148 | + dur="$3" |
| 149 | + hb="$4" |
| 150 | + shift 4 |
| 151 | + |
| 152 | + [ "${1:-}" = "--" ] || return 2 |
| 153 | + shift |
| 154 | + |
| 155 | + : >"$logf" 2>/dev/null || true |
| 156 | + |
| 157 | + "$@" >"$logf" 2>&1 & |
| 158 | + pid=$! |
| 159 | + |
| 160 | + elapsed=0 |
| 161 | + pad="${SENSORS_TIMEOUT_PAD_SECS:-15}" |
| 162 | + case "$dur" in ""|*[!0-9]*) dur=10 ;; esac |
| 163 | + case "$hb" in ""|*[!0-9]*) hb=5 ;; esac |
| 164 | + timeout=$((dur + pad)) |
| 165 | + |
| 166 | + log_info "$label started (log: $logf)" |
| 167 | + |
| 168 | + while kill -0 "$pid" 2>/dev/null; do |
| 169 | + if [ "$elapsed" -ge "$timeout" ]; then |
| 170 | + log_error "$label TIMEOUT after ${elapsed}s (killing pid $pid). Log: $logf" |
| 171 | + kill "$pid" 2>/dev/null || true |
| 172 | + sleep 1 |
| 173 | + kill -9 "$pid" 2>/dev/null || true |
| 174 | + break |
| 175 | + fi |
| 176 | + |
| 177 | + # Sleep in small steps so we don't oversleep after the cmd already finished |
| 178 | + step=1 |
| 179 | + while [ "$step" -le "$hb" ]; do |
| 180 | + sleep 1 2>/dev/null || true |
| 181 | + kill -0 "$pid" 2>/dev/null || break |
| 182 | + step=$((step + 1)) |
| 183 | + done |
| 184 | + |
| 185 | + kill -0 "$pid" 2>/dev/null || break |
| 186 | + elapsed=$((elapsed + hb)) |
| 187 | + log_info "$label running... ${elapsed}/${dur}s (log: $logf)" |
| 188 | + done |
| 189 | + |
| 190 | + wait "$pid" 2>/dev/null |
| 191 | + return $? |
| 192 | +} |
| 193 | + |
| 194 | +sensors_see_workhorse_passed() { |
| 195 | + logf="$1" |
| 196 | + [ -r "$logf" ] || return 1 |
| 197 | + |
| 198 | + # Decide verdict by the *last* PASS/FAIL marker in the log. |
| 199 | + # This handles duplicate PASS lines and any earlier noise. |
| 200 | + last="$(grep -E '^(PASS|FAIL)[[:space:]]+see_workhorse' "$logf" 2>/dev/null | tail -n 1 | awk '{print $1}')" |
| 201 | + |
| 202 | + if [ "$last" = "PASS" ]; then |
| 203 | + return 0 |
| 204 | + fi |
| 205 | + if [ "$last" = "FAIL" ]; then |
| 206 | + return 1 |
| 207 | + fi |
| 208 | + |
| 209 | + # Fallback if no explicit markers found: |
| 210 | + # consider non-empty log as "likely ran", but you can make this stricter if needed. |
| 211 | + [ -s "$logf" ] && return 0 |
| 212 | + return 1 |
| 213 | +} |
| 214 | + |
| 215 | +sensors_run_see_workhorse() { |
| 216 | + sensor="$1" |
| 217 | + duration="$2" |
| 218 | + outdir="$3" |
| 219 | + hb="${4:-5}" |
| 220 | + disp="${SENSORS_DISPLAY_EVENTS:-1}" |
| 221 | + |
| 222 | + logf="$outdir/see_workhorse_${sensor}.log" |
| 223 | + label="see_workhorse(${sensor})" |
| 224 | + |
| 225 | + sensors_run_cmd_with_progress "$logf" "$label" "$duration" "$hb" -- \ |
| 226 | + see_workhorse -sensor="$sensor" -sample_rate=max -duration="$duration" -display_events="$disp" |
| 227 | + |
| 228 | + sensors_see_workhorse_passed "$logf" |
| 229 | + return $? |
| 230 | +} |
| 231 | + |
| 232 | +sensors_run_ssc_drva_test() { |
| 233 | + sensor="$1" |
| 234 | + duration="$2" |
| 235 | + outdir="$3" |
| 236 | + hb="${4:-5}" |
| 237 | + |
| 238 | + command -v ssc_drva_test >/dev/null 2>&1 || return 2 |
| 239 | + |
| 240 | + logf="$outdir/ssc_drva_test_${sensor}.log" |
| 241 | + label="ssc_drva_test(${sensor})" |
| 242 | + |
| 243 | + set -- ssc_drva_test -sensor="$sensor" -duration="$duration" -sample_rate=-1 |
| 244 | + if [ "$sensor" = "accel" ] && [ -n "${SENSORS_DRVA_NUM_SAMPLES:-}" ]; then |
| 245 | + set -- "$@" -num_samples="${SENSORS_DRVA_NUM_SAMPLES}" |
| 246 | + fi |
| 247 | + |
| 248 | + sensors_run_cmd_with_progress "$logf" "$label" "$duration" "$hb" -- "$@" |
| 249 | + rc=$? |
| 250 | + |
| 251 | + grep -q '^FAIL' "$logf" 2>/dev/null && return 1 |
| 252 | + [ "$rc" -eq 0 ] && return 0 |
| 253 | + return 1 |
| 254 | +} |
0 commit comments