blob: 2b44a1a2ce7abde5cfdaa0aa547e751eecf133aa [file] [log] [blame] [edit]
#!/bin/sh
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
. /usr/share/misc/shflags
. /opt/google/touch/scripts/chromeos-touch-common.sh
DEFINE_string 'device_path' '' "device path" 'p'
DEFINE_boolean 'recovery' ${FLAGS_FALSE} "Recovery. Allows for rollback" 'r'
# Parse command line
FLAGS "$@" || exit 1
eval set -- "${FLAGS_ARGV}"
SIS_FW_UPDATE_USER="sisfwupdate"
SIS_FW_UPDATE_GROUP="sisfwupdate"
SIS_TOUCH_I2C_HIDRAW="/dev/sis_touch_i2c_hidraw"
SIS_TOUCH_USB_HIDRAW="/dev/sis_touch_usb_hidraw"
SIS_FIRMWARE_NAME='sis.bin'
SIS_VENDOR_ID="0457"
# Consoletool path
CONSOLETOOL_DIR="/usr/sbin"
GET_FIRMWARE_ID="${CONSOLETOOL_DIR}/SiSGetFirmwareId"
UPDATE_FW="${CONSOLETOOL_DIR}/SiSUpdateFW"
# Consoletool settings
WAIT_RESET_TIME="4"
get_active_product_id() {
local hidpath="$(echo "${FLAGS_device_path}"/*:${SIS_VENDOR_ID}:*.*)"
local hidname="hid-$(echo "${hidpath##*/}" | \
awk -F'[:.]' '{ print $2 "_" $3 }')"
local product_id="${hidname#*_}"
echo "${product_id}"
}
get_active_firmware_version() {
local sis_touch_hidraw="$1"
local sis_log=""
sis_log="$(minijail0 -u "${SIS_FW_UPDATE_USER}" -g "${SIS_FW_UPDATE_GROUP}" \
-n -S /opt/google/touch/policies/sisupdate.query.policy \
${GET_FIRMWARE_ID} "-n=${sis_touch_hidraw}" "-dis-crto")"
local ret="$?"
if [ "${ret}" -eq "0" ]; then
# Parse active firmware version
local version_text="$(echo "${sis_log}" \
| grep "Active Firmware Version : " | head -1)"
echo "${version_text##*"Active Firmware Version : "}"
exit 0
else
# Some error occurred when executing "getFirmwareId"
die "'getFirmwareId' failed, code=${ret}"
fi
}
compare_fw_versions() {
local active_fw_version="$1"
local fw_version="$2"
local active_fw_version_major=${active_fw_version%%.*}
local active_fw_version_minor=${active_fw_version##*.}
local fw_version_major=${fw_version%%.*}
local fw_version_minor=${fw_version##*.}
compare_multipart_version "${active_fw_version_major}" "${fw_version_major}" \
"${active_fw_version_minor}" "${fw_version_minor}"
}
update_firmware() {
local sis_touch_hidraw="$1"
local fw_path="$2"
minijail0 -u "${SIS_FW_UPDATE_USER}" -g "${SIS_FW_UPDATE_GROUP}" \
-n -S /opt/google/touch/policies/sisupdate.update.policy \
${UPDATE_FW} "-n=${sis_touch_hidraw}" "-ba" \
"${fw_path}" "-wrs=${WAIT_RESET_TIME}"
local ret="$?"
# Show info for the exit-value of ececuting "updateFW"
if [ "${ret}" -eq "0" ]; then
log_msg "'updateFW' succeeded"
else
# Some error occurred when executing "updateFW"
log_msg "error: 'updateFW' failed, code=${ret}"
fi
}
create_sis_hidraw() {
local sis_touch_hidraw=""
local touch_device=""
local dev_t_major=""
local dev_t_minor=""
# Check touch interface if i2c or usb
case "${FLAGS_device_path}" in
*/i2c*)
sis_touch_hidraw=${SIS_TOUCH_I2C_HIDRAW}
;;
*/usb*)
sis_touch_hidraw=${SIS_TOUCH_USB_HIDRAW}
;;
*)
sis_touch_hidraw=${SIS_TOUCH_I2C_HIDRAW}
esac
# Remove sis_touch_hidraw if it exists. The det_t_major/minor may be changed.
if [ -e "${sis_touch_hidraw}" ]; then
rm -rf ${sis_touch_hidraw}
fi
# Find the device path if it exists "/dev/hidrawX".
hidraw_sysfs_path="$(echo "${FLAGS_device_path}"/*:${SIS_VENDOR_ID}:*.*/hidraw/hidraw*)"
touch_device="/dev/${hidraw_sysfs_path##*/}"
if [ -c "${touch_device}" ]; then
# create a device node for touch firmware update
dev_t_major="$(ls -l "${touch_device}" | awk '{print $5}')"
dev_t_major=${dev_t_major%%,}
dev_t_minor="$(ls -l "${touch_device}" | awk '{print $6}')"
mknod "${sis_touch_hidraw}" c "${dev_t_major}" "${dev_t_minor}"
if [ $? -ne 0 ]; then
die "Failed create node: '${sis_touch_hidraw}'."
fi
# Change ownership for sis touch device
chown "${SIS_FW_UPDATE_USER}":"${SIS_FW_UPDATE_GROUP}" \
"${sis_touch_hidraw}"
if [ $? -ne 0 ]; then
die "Failed change owner of node: '${sis_touch_hidraw}'."
fi
# Change access mode for sis touch device
chmod 0660 ${sis_touch_hidraw}
if [ $? -ne 0 ]; then
die "Failed change mode of node: '${sis_touch_hidraw}'."
fi
else
die "Not a legal node: '${touch_device}'."
fi
echo "${sis_touch_hidraw}"
}
main() {
local sis_touch_hidraw=""
local active_product_id=""
local fw_link_path=""
local fw_filename=""
local fw_name=""
local product_id=""
local fw_version=""
local active_fw_version=""
local update_type=""
local update_needed="${FLAGS_FALSE}"
local ret=""
local product_id_matches="${FLAGS_FALSE}"
# Check if specify the hidraw_name.
if [ -z "${FLAGS_device_path}" ]; then
die "Please specify a hidraw_name using -d"
fi
# Get the active product-id.
active_product_id="$(get_active_product_id)"
if [ -z "${active_product_id}" ]; then
log_msg "Unable to determine active product id"
die "Aborting. Can not continue safely without knowing active product id"
fi
# Find the FW that the updater is considering flashing on the touch device.
fw_link_path="$(find_fw_link_path ${SIS_FIRMWARE_NAME} ${active_product_id})"
fw_path="$(readlink -f "${fw_link_path}")"
log_msg "Attempting to load FW: '${fw_link_path}'"
if [ ! -e "${fw_link_path}" ] || [ ! -e "${fw_path}" ]; then
die "No valid firmware for ${FLAGS_device_path} found."
fi
fw_filename=${fw_path##*/}
fw_name=${fw_filename%.bin}
product_id=${fw_name%_*}
fw_version=${fw_name#"${product_id}_"}
# Make sure the product ID is what the updater expects.
log_msg "Hardware product id : ${active_product_id}"
log_msg "Updater product id : ${product_id}"
if [ "${product_id}" = "${active_product_id}" ]; then
product_id_matches=${FLAGS_TRUE}
fi
if [ "${product_id_matches}" -ne ${FLAGS_TRUE} ]; then
die "Touch firmware updater: Product ID mismatch!"
fi
# Create sis hidraw
sis_touch_hidraw="$(create_sis_hidraw)"
log_msg "Create node succeeded: '${sis_touch_hidraw}'."
# Get device's fw version.
active_fw_version="$(get_active_firmware_version ${sis_touch_hidraw})"
ret="$?"
if [ ${ret} -ne "0" ]; then
log_msg "Unable to determine active firmware version"
die "Aborting. Can not continue safely without knowing active FW version"
elif [ -z "${active_fw_version}" ]; then
log_msg "Get empty active firmware version"
die "Aborting. Can not continue safely without knowing active FW version"
fi
# Compare the two versions, and see if an update is needed
log_msg "Current Firmware: ${active_fw_version}"
log_msg "Updater Firmware: ${fw_version}"
report_initial_version "${FLAGS_device_path}" "SiS" "${active_fw_version}"
update_type="$(compare_fw_versions "${active_fw_version}" "${fw_version}")"
log_update_type "${update_type}"
update_needed="$(is_update_needed "${update_type}")"
# If an update is needed, start it now and confirm it worked.
if [ "${update_needed}" -eq ${FLAGS_TRUE} ]; then
log_msg "Update FW to ${fw_name}"
update_firmware ${sis_touch_hidraw} ${fw_path}
# Recreate sis hidraw. The /dev/hidrawX may be changed after device reset.
sis_touch_hidraw="$(create_sis_hidraw)"
log_msg "Recreate node succeeded: '${sis_touch_hidraw}'."
# Confirm that the FW was updated by checking the current FW version again
active_fw_version="$(get_active_firmware_version ${sis_touch_hidraw})"
update_type="$(compare_fw_versions "${active_fw_version}" "${fw_version}")"
if [ "${update_type}" -ne "${UPDATE_NOT_NEEDED_UP_TO_DATE}" ]; then
report_update_result "${FLAGS_device_path}" "${REPORT_RESULT_FAILURE}" \
"${fw_version}"
die "Firmware update failed. Current Firmware: ${active_fw_version}"
fi
log_msg "Update FW succeeded. Current Firmware: ${active_fw_version}"
report_update_result "${FLAGS_device_path}" "${REPORT_RESULT_SUCCESS}" \
"${active_fw_version}"
fi
}
main