#!/bin/sh # xpp_fxloader: load Xorcom Astribank (XPP) firmware # # This script can be run manually or from hotplug/udev. # # Firmware files should be located in $FIRMWARE_DIR which defaults: # 1. /usr/share/zaptel # 2. Can be overidden by setting $FIRMWARE_DIR in the environment # 3. Can be overidden by setting $FIRMWARE_DIR in /etc/default/zaptel # # Manual Run # ########## # # path/to/xpp_fxloader load # # Make sure the firmware files are in $FIRMWARE_DIR # # UDEV Installation # ################# # # Copy xpp.rules to /etc/udev/udev.d and xpp_fxloader to /etc/hotplug/usb/ . # # Hotplug Installation # #################### # # Copy this file and the file xpp_fxloader.usermap to /etc/hotplug/usb/ . # # # Written by Tzafrir Cohen # Copyright (C) 2006, Xorcom # # All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. set -e # Make sure fxload is in the path: PATH="$PATH:/usr/local/sbin:/sbin:/usr/sbin" export PATH me=`basename $0` DEFAULTS="/etc/default/zaptel" if [ -t 2 ]; then LOGGER="logger -i -t '$me' -s" else LOGGER="logger -i -t '$me'" fi USBFS_PREFIX=/proc/bus/usb DEVUSB_PREFIX=/dev/bus/usb USB_PREFIX= FIRMWARE_DIR="${FIRMWARE_DIR:-/usr/share/zaptel}" FIRM_FXS=$FIRMWARE_DIR/FPGA_FXS.hex REENUM_SLEEP_TIME=3 # only used on manual runs FPGA_LOAD=${FPGA_LOAD:-/usr/sbin/fpga_load} if [ -r "$DEFAULTS" ]; then . "$DEFAULTS" fi if [ "$USB_PREFIX" = '' ]; then if [ -d "$DEVUSB_PREFIX" ]; then USB_PREFIX=$DEVUSB_PREFIX elif [ -r "$USBFS_PREFIX/devices" ]; then USB_PREFIX=$USBFS_PREFIX fi fi # With Kernels older that 2.6.10 it seems to be possible # to trigger a race condition by running fxload or fpga_load # immediately after the detection of the device. KERNEL_HAS_USB_RACE=0 case "`uname -r`" in 2.6.[89]*) KERNEL_HAS_USB_RACE=1;; esac sleep_if_race() { if [ "$KERNEL_HAS_USB_RACE" = '1' ]; then sleep 2 fi } find_dev() { v_id=$1 p_id=$2 lsusb | tr -d : | awk "/ ID $v_id$p_id/{printf \"$USB_PREFIX/%s/%s \",\$2,\$4}" } do_fxload() { sleep_if_race ( fxload -t fx2 $* 2>&1 1>/dev/null || exit 1 ) | $LOGGER } load_fw() { v_id=$1 p_id=$2 fw=$3 devices=`find_dev $v_id $p_id` for dev in $devices do $LOGGER "USB Firmware $FIRMWARE_DIR/$fw into $dev" do_fxload -D $dev -I $FIRMWARE_DIR/$fw || exit 1 done # Allow time for reenumeration: This only matters in the manual case. if [ "$devices" != '' ]; then sleep $REENUM_SLEEP_TIME; fi } reset_fpga() { v_id=$1 p_id=$2 devices=`find_dev $v_id $p_id` for dev in $devices do $LOGGER "Resetting FPGA Firmware on $dev" sleep_if_race $FPGA_LOAD -D "$dev" -r 2>&1 >/dev/null | $LOGGER status=$PIPESTATUS if [ "$status" != 0 ]; then echo "fpga_load failed remoivng with status $status" | $LOGGER exit 78 fi done } load_fpga() { v_id=$1 p_id=$2 fw=$3 devices=`find_dev $v_id $p_id` for dev in $devices do card_ver=`$FPGA_LOAD -g -D $dev | sed -n 's/^.*Release: *//'` $LOGGER "FPGA Firmware into $dev" sleep_if_race $FPGA_LOAD -D "$dev" -I "$FIRMWARE_DIR/$fw" -i | $LOGGER status=$PIPESTATUS if [ $status != 0 ]; then echo "fpga_load failed with status $status" | $LOGGER exit 77 fi done } ######################### ## ## Manual run ## # to run manually, pass the parameter 'xppdetect' case "$1" in udev) # the following emulate hotplug's environment from udev's environment: DEVICE="$DEVNAME" PRODUCT="$2" # skip on to the rest of the script. Don't exit. ;; reset) # TODO: does the use of wildcards here work? reset_fpga e4e4 '11[345][12]' ;; xppdetect|load|usb) echo "--------- FIRMWARE LOADING: ($1)" load_fw 04b4 8613 USB_8613.hex load_fw e4e4 1130 USB_1130.hex load_fw e4e4 1140 USB_1140.hex load_fw e4e4 1150 USB_1150.hex if [ "$1" != 'usb' ] then load_fpga e4e4 1131 FPGA_FXS.hex load_fpga e4e4 1141 FPGA_1141.hex load_fpga e4e4 1151 FPGA_1151.hex fi sleep 3 # Let it stabilize echo "--------- FIRMWARE IS LOADED" exit 0 ;; help) echo "$0: Astribank firmware loading script." echo "Usage: " echo "$0 load : manual firmware loading." echo "$0 usb : manual firmware loading: USB firmware only." echo "$0 help : this text." echo "" echo "('xppdetect' is an alias of 'load')" exit 0 ;; esac ######################### ## ## Hotplug run ## # allow disabling automatic hotplugging: if [ "$XPP_HOTPLUG_DISABLED" != '' ]; then $LOGGER -p kern.info "Exiting... XPP_HOTPLUG_DISABLED" exit 0 fi if [ "$ACTION" = "add" ] && [ -w "$DEVICE" ] then $LOGGER "Trying to find what to do for product $PRODUCT, device $DEVICE" prod_id=`echo "$PRODUCT" | cut -d/ -f2` case "$PRODUCT" in 4b4/8613/*|e4e4/11[345]0/*) FIRM_USB="$FIRMWARE_DIR/USB_$prod_id.hex" $LOGGER "Loading firmware '$FIRM_USB' into '$DEVICE'" do_fxload -D "$DEVICE" -I "$FIRM_USB" ;; e4e4/11[345]1/*) if [ "$prod_id" = 1131 ]; then FIRM_FPGA="$FIRMWARE_DIR/FPGA_FXS.hex" # Legacy else FIRM_FPGA="$FIRMWARE_DIR/FPGA_$prod_id.hex" fi sleep_if_race $FPGA_LOAD -D "$DEVICE" -I "$FIRM_FPGA" 2>&1 >/dev/null | $LOGGER ;; esac fi