| # Copyright 2017 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. |
| |
| description "Hammer firmware updater task" |
| author "chromium-os-dev@chromium.org" |
| |
| # When the hammer device is plugged, udev emits hammer-device-added signal. |
| # The example rule file: hammerd/udev/99-hammerd.rules.example |
| # Additionally, start hammerd when ash gets initialized. Ash observes |
| # signals from hammerd and, if needed, notifies the user of connected hammer |
| # state. This means that hammerd should be rerun to ensure ash has received |
| # relavant signals, in case ash missed signals emitted when hammer device was |
| # added (e.g. if ash had restarted after hammer device addition due to user |
| # session restart). |
| # NOTE: ash-initialized signal is emitted by session manager on request from |
| # the browser process once ash initialization completes. |
| start on hammer-device-added or ash-initialized |
| |
| # If the device pairs correctly, expose hammer's sysfs path for other |
| # applications to use. Store sysfs path file in a separate directory |
| # to allow for metrics sandboxing. |
| env WRITE_SYSFS_PATH="/run/metrics/external/hammer/hammer_sysfs_path" |
| |
| # Arguments should be empty here and overridden at `hammerd.override`. |
| env EC_IMAGE_PATH= |
| env TOUCHPAD_IMAGE_PATH= |
| env VENDOR_ID= |
| env PRODUCT_ID= |
| env USB_BUS= |
| env USB_PORT= |
| env AUTOSUSPEND_DELAY_MS="1000" |
| |
| # These variables may be passed when the job gets started from |
| # hammerd-at-boot.sh. |
| import AT_BOOT |
| import UPDATE_IF |
| |
| # Set the argument to True when triggering at boot. |
| env AT_BOOT="false" |
| # The argument to determine the update condition. |
| # Valid values are "never", "mismatch", and "always". |
| env UPDATE_IF="never" |
| |
| task |
| |
| pre-start script |
| # Because the upstart job `boot-update-firmware` will force invoking hammerd |
| # once before UI is started, we need to make sure hammerd isn't invoked by |
| # udev before boot-update-firmware gets to run. |
| if [ "${UPSTART_EVENTS}" = 'hammer-device-added' ] && \ |
| ! initctl status boot-update-firmware | grep -q "start/running"; then |
| logger -t hammerd "boot-update-firmware hasn't started yet, ignore." |
| stop |
| fi |
| sysfs_parent_dir="$(dirname "${WRITE_SYSFS_PATH}")" |
| mkdir -p "${sysfs_parent_dir}" |
| # Change ownership so that both metrics and hammerd can have write access. |
| chown hammerd:metrics "${sysfs_parent_dir}" |
| chmod 770 "${sysfs_parent_dir}" |
| end script |
| |
| # Trigger hammerd process. |
| # Note: minijail0 "-N" argument (cgroup namespace) is only supported on |
| # kernel >= 3.14. Remove if the hammerd runs on kernel < 3.14. |
| script |
| # If reacting to ash-initialized event, verify that the base is actually |
| # connected before proceeding - hammerd expects the base to be connected, |
| # which is not guaranteed on ash initialization signal (unlike on |
| # hammerd-device-added). |
| if [ "${UPSTART_EVENTS}" = 'ash-initialized' ]; then |
| HAMMERD_DETECTOR_SCRIPT='/usr/share/cros/init/hammerd-base-detector.sh' |
| if [ -e "${HAMMERD_DETECTOR_SCRIPT}" ]; then |
| # Import base_connected function. |
| . "${HAMMERD_DETECTOR_SCRIPT}" |
| |
| if ! base_connected "${UPSTART_JOB}"; then |
| logger -t "${UPSTART_JOB}" \ |
| "Base not connected during ash initialization" |
| exit 0 |
| fi |
| else |
| logger -t hammerd "hammerd-base-detector script not found." |
| fi |
| fi |
| |
| # Adopt chromeos-config. |
| hammer_name="$(cros_config /detachable-base ec-image-name)" |
| # If we find the unibuild config, then override the config. |
| if [ -n "${hammer_name}" ]; then |
| EC_IMAGE_PATH="/lib/firmware/${hammer_name}" |
| touch_name="$(cros_config /detachable-base touch-image-name)" |
| if [ -n "${touch_name}" ]; then |
| TOUCHPAD_IMAGE_PATH="/lib/firmware/${touch_name}" |
| fi |
| VENDOR_ID="$(cros_config /detachable-base vendor-id)" |
| PRODUCT_ID="$(cros_config /detachable-base product-id)" |
| USB_PATH="$(cros_config /detachable-base usb-path)" |
| fi |
| |
| exit_status=0 |
| /sbin/minijail0 -e -N -p -l -u hammerd -g hammerd -c 0002 \ |
| /usr/bin/hammerd --ec_image_path="${EC_IMAGE_PATH}" \ |
| --touchpad_image_path="${TOUCHPAD_IMAGE_PATH}" \ |
| --vendor_id="${VENDOR_ID}" \ |
| --product_id="${PRODUCT_ID}" \ |
| --usb_path="${USB_PATH}" \ |
| --autosuspend_delay_ms="${AUTOSUSPEND_DELAY_MS}" \ |
| --at_boot="${AT_BOOT}" \ |
| --update_if="${UPDATE_IF}" || exit_status="$?" |
| |
| if [ "${exit_status}" -eq 0 ]; then |
| usb_device_path="/sys/bus/usb/devices/${USB_PATH}" |
| if ! echo "${usb_device_path}" > "${WRITE_SYSFS_PATH}"; then |
| logger -t ${UPSTART_JOB} \ |
| "FAILED to write into sysfs tag file: ${WRITE_SYSFS_PATH}" |
| exit 1 # Exit status for "unknown error" in hammerd. |
| fi |
| else |
| rm "${WRITE_SYSFS_PATH}" || true |
| fi |
| exit "${exit_status}" |
| end script |