#!/bin/bash
# Copyright (c) 2017 Arista Networks, Inc.  All rights reserved.
# Arista Networks, Inc. Confidential and Proprietary.

oniePlatform=${ONIE_PLATFORM:-$(grep -Po '(?<=onie_platform=)[^ ]+' /proc/cmdline)}
platform=${EOS_PLATFORM:-$(xargs -n1 < /proc/cmdline |
                                        sed -ne's/^platform=//p')}

# the slowest known system to powercycle is Wheatland hence the long sleep value
powercycle_wait=10

# use a dedicated script to powercycle the platform if one exists
powercycleScript="/usr/bin/powercycle-$platform"
if [ -x "$powercycleScript" ]; then
   # Execute powercycle script
   if "$powercycleScript"; then
      # Sleep if the execution of the dedicated powercycle was sucessful.
      # Some platforms do not have the ability to powercycle beyond cpu reset.
      # These should not be stuck waiting for nothing.
      sleep $powercycle_wait
   fi
   # This line should not be reached
   echo "Powercycle script $powercycleScript had no effect"
   exit
elif [ ! -z "$oniePlatform" ]; then
   # Whiteboxes are expected to provide a dedicated script for powercycle.
   # Print a message on the console if none is available.
   echo "Missing powercycle script $powercycleScript"
   exit
fi

for mntPt in flash drive drive2; do
   device=$(grep -w $mntPt /proc/self/mounts | grep -oP '^/dev/sd[a-z]')
   if [ $? -eq 0 ]; then
      hdparm -y ${device} &> /dev/null
   fi
done
# product is not a whitebox
case "$platform" in
   blackbird)
      # On PtReyes systems, we need to reboot through toggling a powercycle gpio.
      pchgpio --reboot
      ;;
   grackle)
       # grackle reboots via powercycle gpio as well
      kabinigpio 51 1
      ;;
   rook|sprucefish|sprucefishS|dawson|surfbird|jeffersonpass)
      # These systems have two scd devices.On these systems cpu/supe cpld is
      # also considered as scd device and powrcycle register cpu/supe cpld,
      # so need to explicitly mention the pci addr of cpu/supe cpld to power cycle.
      scd ff:0b.3 write 0x7000 0x0000DEAD
      ;;
   woodpecker)
      # These systems have two scd devices. On these systems cpu cpld is
      # also considered as scd device and powercycle register is on cpu cpld,
      # so need to explicitly mention the pci addr of cpu cpld to power cycle.
      scd 00:09.0 write 0x7000 0x0000DEAD
      ;;
   belvedere)
      scd write 0x7000 0x0000DEAD
      sleep 1
      # If powercycle via scd does not work fall back to gpio.
      kabinigpio 92 1
      ;;
   lorikeet|cormorant)
      # lorikeet reboots via powercycle gpio as well
      kabinigpio 4 1
      ;;
   newportprime)
      kabinigpio 92 1
      sleep 1
      ;;
   newport)
      # BUG514910 - Remove SCD powercycle method when P1 duts are decommissioned.
      # For P2s and onwards we will rely only on the GPIO.
      scd write 0x7000 0x0000DEAD
      sleep 1
      # If powercycle via scd does not work fall back to gpio.
      kabinigpio 33 1
      ;;
   raspberryisland)
      scd write 0x7000 0x0000DEAD
      sleep 1
      # Use powercycle gpio as a backup
      kabinigpio 69 1
      ;;
   prairieisland)
      scd write 0x7000 0x0000DEAD
      sleep 1
      # Use powercycle gpio as a backup
      kabinigpio 140 1
      ;;
   alcatraz)
      scd write 0x7000 0x0000DEAD
      sleep 1
      # Use powercycle gpio as a backup
      kabinigpio 92 1
      ;;
   puffin|headland)
      kabinigpio 92 1
      ;;
   councilbluffs)
      scd write 0x7000 0x0000DEAD
      sleep 1
      ;;
   waxwing)
      # Use GPIO SATA_PDETECT2_SLOAD2_GPP_E22 (CPU_CMD_PWR_CYC)
      # to powercycle the system
      cedarforkgpio 0xc5 0x960 1
      ;;
   fairywren)
      scd 07:00.0 write 0x7000 0x0000DEAD
      ;;
   shearwater)
      # Powercycle the system using CPU CPLD reg 0x7000
      scd 00:18.7 write 0x7000 0x0000DEAD
      ;;
   redstart|skylark)
      scd 04:00.0 write 0x7000 0x0000DEAD
      sleep 1
      # Use powercycle gpio as a backup
      kabinigpio 92 1
      ;;
   veos)
      sudo reboot
      exit
      ;;
   willamette)
      i2cset -y 1 0x23 0x04 0xde
      sleep 1
      # Willamette reboot with gpio as fallback
      willamettegpio 0xc5 0x0528 1
      ;;
   wh3p)
      # Enable reload on user requested cause - This will eventually be default 
      # enabled and can be removed - BUG999498
      i2cset -f -y 0 0x23 0x1D 0x00 0x01 0x00 0x00 s
      # Set reload cause to "Software Requested Power Cycle"
      i2cset -f -y 0 0x23 0x20 0x08 0x00 0x00 0x00 s
      # Trigger the reload
      i2cset -f -y 0 0x23 0x1F 0xAD 0xDE 0x00 0x80 s
      ;;
   blackfish)
      # Use GPIO SATA_PDETECT2_SLOAD2_GPP_E22 (CPU_CMD_PWR_CYC)
      # to powercycle the system
      cedarforkgpio 0xc5 0x960 1
      sleep 1
      # If it didn't work, try SCD as a fallback
      scd 00:1a.3 write 0x7000 0x0000DEAD
      sleep 1
      ;;
   *)
      # powercycle the system via the scd
      scd write 0x7000 0x0000DEAD

      # the above command does nothing on Bodega if the primary fpga is
      # non functional. As such write to the secondary CPLD's suicide
      # register. Napa boards should not arrive at this code.
      smbus write8 /sb/1/0x23 0x04 0xde
      ;;
esac

# and wait for it to go
sleep $powercycle_wait

# this line should not be reached
echo "Powercycle script had no effect; platform = $platform"
