diff options
Diffstat (limited to 'package')
| -rw-r--r-- | package/system/utils/usb-modeswitch/Makefile | 63 | ||||
| -rw-r--r-- | package/system/utils/usb-modeswitch/files/modeswitch.hotplug | 140 | 
2 files changed, 203 insertions, 0 deletions
diff --git a/package/system/utils/usb-modeswitch/Makefile b/package/system/utils/usb-modeswitch/Makefile new file mode 100644 index 000000000..e78a5b476 --- /dev/null +++ b/package/system/utils/usb-modeswitch/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (C) 2008-2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=usb-modeswitch +PKG_UTIL_VERSION:=1.2.5 +PKG_DATA_VERSION:=20121109 +PKG_VERSION:=$(PKG_UTIL_VERSION)+$(PKG_DATA_VERSION) +PKG_RELEASE:=1 + +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_UTIL_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_UTIL_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://www.draisberghof.de/usb_modeswitch +PKG_MD5SUM:=c393603908eceab95444c5bde790f6f0 + +PKG_DATA_PATH:=usb-modeswitch-data-$(PKG_DATA_VERSION) +PKG_DATA_FILENAME:=$(PKG_DATA_PATH).tar.bz2 + +PKG_MAINTAINER := Felix Fietkau <nbd@openwrt.org> + +include $(INCLUDE_DIR)/package.mk + +define Package/usb-modeswitch +  SECTION:=utils +  CATEGORY:=Utilities +  DEPENDS:=+libusb-compat +  TITLE:=USB ModeSwitch +  URL:=http://www.draisberghof.de/usb_modeswitch/ +endef + +define Package/usb-modeswitch/description +  A mode switching tool for controlling +  "flip flop" (multiple device) USB gear. +endef + +define Download/data +  FILE:=$(PKG_DATA_FILENAME) +  URL:=$(PKG_SOURCE_URL) +  MD5SUM:=a7d23a03157871013a0d708ab2b1b6df +endef +$(eval $(call Download,data)) + +define Build/Compile +	tar xvfj $(DL_DIR)/$(PKG_DATA_FILENAME) -C $(PKG_BUILD_DIR) +	$(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_CPPFLAGS) $(TARGET_LDFLAGS) \ +		-lusb \ +		-o $(PKG_BUILD_DIR)/usb_modeswitch-OpenWrt \ +		$(PKG_BUILD_DIR)/usb_modeswitch.c +endef + +define Package/usb-modeswitch/install +	$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/hotplug.d/usb +	$(INSTALL_BIN) $(PKG_BUILD_DIR)/usb_modeswitch-OpenWrt $(1)/usr/bin/usb_modeswitch +	$(INSTALL_DATA) ./files/modeswitch.hotplug $(1)/etc/hotplug.d/usb/20-modeswitch +	$(CP) $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d $(1)/etc/ +endef + +$(eval $(call BuildPackage,usb-modeswitch)) diff --git a/package/system/utils/usb-modeswitch/files/modeswitch.hotplug b/package/system/utils/usb-modeswitch/files/modeswitch.hotplug new file mode 100644 index 000000000..eb71b3056 --- /dev/null +++ b/package/system/utils/usb-modeswitch/files/modeswitch.hotplug @@ -0,0 +1,140 @@ +#!/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 +			*-*:*.*) : ;; +			*) 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" +			# ugly workaround, but working for all hw we got for testing +			switching_done=0 +			switching_tries=0 +			local usb_dir="/sys/$DEVPATH" +			[ -f "$usb_dir/idVendor" ] || usb_dir="${usb_dir%/*}" +			while [ $switching_done -lt 1 -a $switching_tries -le 6 ]; do +				$modeswitch -v $uVid -p $uPid -I -D -n -s 30 -c "${configs%% *}" +				if [ $(sanitize "$usb_dir/idProduct") = $uPid ]; then +					log "$DEVICENAME: Switching seemingly failed" +					sleep 1 +				else +					switching_done=1 +				fi +				switching_tries=$(( $switching_tries + 1 )) +			done +		} +	} +fi  | 
