From 9cc0bb27de5c694793f5678fade787bdaa54f7fc Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Sun, 4 Jul 2010 18:19:03 +0000 Subject: [PATCH] [packages] usb-modeswitch: add hotplug handler to invoke usb_modeswitch when a flip flop dongle is detected, the handler should be 100% compatible to Debian usb-modeswitch-data config collection SVN-Revision: 22062 --- utils/usb-modeswitch/Makefile | 4 +- utils/usb-modeswitch/files/modeswitch.hotplug | 128 ++++++++++++++++++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 utils/usb-modeswitch/files/modeswitch.hotplug diff --git a/utils/usb-modeswitch/Makefile b/utils/usb-modeswitch/Makefile index 24f0d00bcf..0aa202189e 100644 --- a/utils/usb-modeswitch/Makefile +++ b/utils/usb-modeswitch/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=usb-modeswitch PKG_VERSION:=1.1.2 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 PKG_SOURCE_URL:=http://www.draisberghof.de/usb_modeswitch @@ -40,6 +40,8 @@ endef define Package/usb-modeswitch/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/usb_modeswitch-OpenWrt $(1)/usr/bin/usb_modeswitch + $(INSTALL_DIR) $(1)/etc/hotplug.d/usb + $(INSTALL_DATA) ./files/modeswitch.hotplug $(1)/etc/hotplug.d/usb/20-modeswitch endef $(eval $(call BuildPackage,usb-modeswitch)) diff --git a/utils/usb-modeswitch/files/modeswitch.hotplug b/utils/usb-modeswitch/files/modeswitch.hotplug new file mode 100644 index 0000000000..eebaf1355e --- /dev/null +++ b/utils/usb-modeswitch/files/modeswitch.hotplug @@ -0,0 +1,128 @@ +#!/bin/sh + +local uVid uPid uMa uPr uSe +local sVe sMo sRe + +local modeswitch="/usr/bin/usb_modeswitch" + + +log() { + logger -t "usb-modeswitch" "$@" +} + +sanitize() { + sed -e 's/[[:space:]]\+$//; s/[[:space:]]\+/_/g' "$@" +} + +find_scsi_attrs() { + [ -n "$DEVPATH" ] && [ -d /sys/$DEVPATH/host* ] && { + log "$DEVICENAME is a SCSI device, waiting for it to settle..." + local timeout=20 + while [ $((--timeout)) -ge 0 ]; do + [ -d /sys/$DEVPATH/host*/target* ] && { + local scsi_dir + for scsi_dir in /sys/$DEVPATH/host*/target*/*; do + [ -d "$scsi_dir" ] || break + case "$scsi_dir" in + */host*/target*/*:*:*:*) + sVe=$(sanitize "$scsi_dir/vendor") + sMo=$(sanitize "$scsi_dir/model") + sRe=$(sanitize "$scsi_dir/rev") + + log "$DEVICENAME: Vendor=${sVe:-?} Model=${sMo:-?} Revision=${sRe:-?}" + return 0 + ;; + esac + done + } || { + sleep 1 + } + done + log "$DEVICENAME: Failed to get SCSI attributes!" + } + + return 1 +} + +find_usb_attrs() { + local usb_dir="/sys/$DEVPATH" + [ -f "$usb_dir/idVendor" ] || usb_dir="${usb_dir%/*}" + + uVid=$(cat "$usb_dir/idVendor") + uPid=$(cat "$usb_dir/idProduct") + uMa=$(sanitize "$usb_dir/manufacturer") + uPr=$(sanitize "$usb_dir/product") + uSe=$(sanitize "$usb_dir/serial") + + log "$DEVICENAME: Manufacturer=${uMa:-?} Product=${uPr:-?} Serial=${uSe:-?}" +} + +match_config_tag() { + local conf="$1" + local tag="$2" + + case "${conf##*/}" in + *:*$tag=*) + local cmp; eval "cmp=\$$tag" + local pat="${conf#*:$tag=}"; pat="${pat%%:*}" + case "$cmp" in + *$pat*) return 0 ;; + *) return 1 ;; + esac + ;; + esac + + return 0 +} + +match_config() { + local conf="$1" + local tag + + for tag in uMa uPr uSe sVe sMo sRe; do + match_config_tag "$conf" "$tag" || return 1 + done + + return 0 +} + + + +if [ "$ACTION" = add ]; then + [ -d "/etc/usb_modeswitch.d" ] && [ -x "$modeswitch" ] && { + case "$DEVICENAME" in + *-*:*.*) : ;; + *) log "Not handling $DEVICENAME"; exit 0 ;; + esac + + find_usb_attrs + + local candidates=0 + local conf configs + for conf in /etc/usb_modeswitch.d/$uVid:$uPid*; do + [ -f "$conf" ] || break + configs="${configs:+$configs }$conf" + $((candidates++)) + done + + # Found more than one candidate, read SCSI attributes and find the best match + [ $candidates -gt 1 ] && { + find_scsi_attrs + for conf in $configs; do + match_config "$conf" && { + configs="$conf" + candidates=1 + break + } + done + } + + # If a candidate is remaining, start usb-modeswitch + [ -n "$configs" ] && { + log "$DEVICENAME: Selecting ${configs%% *} for mode switching" + $modeswitch -c "${configs%% *}" + } || { + log "$DEVICENAME: Device does not seem to need mode switching" + } + } +fi -- 2.30.2