📄 usb.agent
字号:
#!/bin/sh## USB-specific hotplug policy agent.## This should handle 2.2.18+, 2.4.*, and 2.5.* USB hotplugging,# with a consistent framework for adding device and driver# specific handling.## Normally, adding a usb device will modprobe a driver. If there# is a /etc/hotplug/usb/$DRIVER script set up, it will also run,# handling tasks like loading firmware or starting daemons.## Kernel USB hotplug params include:# # ACTION=%s [add or remove]# DEVPATH=%s [in 2.5 kernels, /sys/$DEVPATH]# PRODUCT=%x/%x/%x# INTERFACE=%d/%d/%d [ for interface 0, if TYPE=0/*/* ]# TYPE=%d/%d/%d## And if usbfs (originally called usbdevfs) is configured, also:## DEVFS=/proc/bus/usb [gone in 2.5]# DEVICE=/proc/bus/usb/%03d/%03d## This script then adds the variable:## REMOVER=/var/run/usb/<some string unique to $DEVICE>## This is the path where the script would like to find a remover, if# the target device needs one. This script is executed on remove if# it is executable when the remove happens.## If usbfs is mounted on /proc/bus/usb, $DEVICE is a file which# can be read to get the device's current configuration descriptor.# (The "usbmodules" utility does that.) Or it can be used by a# user mode driver to interact with the usb device. USB hotplug# does *not* require usbfs (or sysfs) to work, although on 2.4# some devices work better if "usbmodules" can help.## For Linux 2.5+ kernels, there's no need for "usbmodules". For# two reasons: first, hotplug is invoked for each interface, not# just the first one. Second, sysfs exposes descriptors so they# are easy to use for "coldplug" event simulation. (But sysfs is# not a replacement for the driver I/O capabilities in usbfs.)## On systems using Linux 2.4.* kernels, be sure to use the right# modutils (2.4.2+). That ensures that hotplugging uses the list# of modules installed for your kernel, rather than the one that's# included here for use on systems without MODULE_DEVICE_TABLE# support.### HISTORY:## 20-Nov-2002 some 2.5 updates; handle new 'device' hotplug; turn off# 'sleep' hack since hcds must all queue control traffic# 08-Aug-2002 support for multiple usermaps (maxk), minor cleanup# 18-Jan-2002 fix match algorithm in usb_map_modules()# 14-Jan-2002 fix work around 2.2 brokeness of $PRODUCT# 09-Jan-2002 REMOVER for system without usbdevfs## 14-Mar-2001 Cleanup, bitmask the match_flags# 26-Feb-2001 Cleanup, support comments (Gioele Barabucci)# 15-Feb-2001 Remove use of "<<" (Adam Richter)# 23-Jan-2001 Update 2.2 handling; unfortunately there's no "feature# test" that can work robustly# 05-Jan-2001 Quick hack for kernel 2.4.0 and modutils 2.4.1# 03-Jan-2001 Initial version of "new" hotplug agent, using feedback# and contributions from Adam Richter, Ryan VanderBijl,# Norbert Preining, Florian Lohoff, David Brownell and# others. To replace the original /etc/usb/policy. (db)## $Id: usb.agent,v 1.41 2004/04/01 07:30:26 kroah Exp $#if [ -f /etc/sysconfig/usb ]; then . /etc/sysconfig/usbfiif [ -f /etc/conf.d/usb ]; then . /etc/conf.d/usbficd /etc/hotplug. ./hotplug.functions# DEBUG=yes export DEBUG# generated by modutils, for current 2.4.x (and later) kernelsMAP_CURRENT=$MODULE_DIR/modules.usbmap# used if MAP_CURRENT is missing; for 2.2.x kernelsMAP_DISTMAP=$HOTPLUG_DIR/usb.distmap## used for kernel drivers that don't show up in CURRENT or DISTMAP,# currently input drivers (joysticks, keyboards, etc). newer systems# should use input hotplug events instead.#MAP_HANDMAP=$HOTPLUG_DIR/usb.handmap## used to run config scripts for user mode drivers (jPhoto, gPhoto2,# rio500 tools, etc) ... instead of naming kernel modules, it names# config scripts. those could change $DEVICE permissions, etc.## for purely user mode drivers, scripts $HOTPLUG_DIR/usb/NAME should be# installed with usermap files in $HOTPLUG_DIR/usb/NAME.usermap instead# of continuing to use/modify $MAP_USERMAP #MAP_USERMAP=$HOTPLUG_DIR/usb.usermap# accumulates list of modules we may care aboutDRIVERS=""if [ "$ACTION" = "" ]; then mesg Bad USB agent invocation, no action exit 1fi# starting in kernel 2.5 there are two kinds of USB hotplug events.# - per-interface; 2.2/2.4 kernels only reported the first one.# "new" events have nonzero /sys/$DEVPATH/bInterfaceNumber# - per-device; "new" events don't have $PRODUCTSYSFS=/sysif [ "$PRODUCT" = "" ]; then # this is either an error, or we're on a 2.5 system... if [ "$DEVPATH" = "" ]; then mesg Bad USB agent invocation exit 1 fi # sysfs files may already be gone if [ $ACTION = 'remove' ]; then exit 0 fi # we could be running before usb populated these attributes... if [ ! -f $SYSFS/$DEVPATH/bNumConfigurations ]; then # FIXME wait till they appear, or N seconds elapse sleep 2 fi # this could care about changing the default config, or warning # when the user hooked a fast device up so it runs slowly. if [ ! -f $SYSFS/$DEVPATH/bNumConfigurations ]; then exit 0 fi TMP=$(cat $SYSFS/$DEVPATH/bNumConfigurations) if [ $TMP -ne 1 -a "$ACTION" = add ]; then mesg Keeping default configuration with $SYSFS/$DEVPATH fi # NOTE: it might be good to add an extension hook here rather # than ignore these events, but even device-scope tasks such # as firmware download can still use the interface-0 event # (as they did with 2.2/2.4 hotplug setup scripts). exit 0fi# we can't "unset IFS" on bash1, so save a copyDEFAULT_IFS="$IFS"## Each modules.usbmap format line corresponds to one entry in a# MODULE_DEVICE_TABLE(usb,...) declaration in a kernel file.## Think of it as a database column with up to three "match specs"# to associate kernel modules with particular devices or classes# of device. The match specs provide a reasonably good filtering# mechanism, but some driver probe() routines need to provide# extra filtering.#usb_convert_vars (){ # work around 2.2.early brokenness # munges the usb_bcdDevice such that it is a integer rather # than a float: e.g. 1.0 become 0100 PRODUCT=`echo $PRODUCT | sed -e "s+\.\([0-9]\)$+.\10+" -e "s/\.$/00/" \ -e "s+/\([0-9]\)\.\([0-9][0-9]\)+/0\1\2+" \ -e "s+/\([0-9][0-9]\)\.\([0-9][0-9]\)+/\1\2+"` set $(echo $PRODUCT | sed -e 's+\([^/]*\)/\([^/]*\)/\(.*\)+\1 \2 \3+') usb_idVendor=$((0x$1)) usb_idProduct=$((0x$2)) usb_bcdDevice=$((0x$3)) if [ "$TYPE" != "" ]; then IFS=/ set $TYPE '' usb_bDeviceClass=$1 usb_bDeviceSubClass=$2 usb_bDeviceProtocol=$3 IFS="$DEFAULT_IFS" elif [ -r $SYSFS/$DEVPATH/bDeviceClass ]; then usb_bDeviceClass=$((0x$(cat $SYSFS/$DEVPATH/bDeviceClass))) usb_bDeviceSubClass=$((0x$(cat $SYSFS/$DEVPATH/bDeviceSubClass))) usb_bDeviceProtocol=$((0x$(cat $SYSFS/$DEVPATH/bDeviceProtocol))) else # out-of-range values usb_bDeviceClass=1000 usb_bDeviceSubClass=1000 usb_bDeviceProtocol=1000 fi if [ "$INTERFACE" != "" ]; then IFS=/ set $INTERFACE '' usb_bInterfaceClass=$1 usb_bInterfaceSubClass=$2 usb_bInterfaceProtocol=$3 IFS="$DEFAULT_IFS" elif [ -r $SYSFS/$DEVPATH/bInterfaceClass ]; then usb_bInterfaceClass=$((0x$(cat $SYSFS/$DEVPATH/bInterfaceClass))) usb_bInterfaceSubClass=$((0x$(cat $SYSFS/$DEVPATH/bInterfaceSubClass))) usb_bInterfaceProtocol=$((0x$(cat $SYSFS/$DEVPATH/bInterfaceProtocol))) else # out-of-range values usb_bInterfaceClass=1000 usb_bInterfaceSubClass=1000 usb_bInterfaceProtocol=1000 fi}USB_MATCH_VENDOR=$((0x0001))USB_MATCH_PRODUCT=$((0x0002))USB_MATCH_DEV_LO=$((0x0004))USB_MATCH_DEV_HI=$((0x0008))USB_MATCH_DEV_CLASS=$((0x0010))USB_MATCH_DEV_SUBCLASS=$((0x0020))USB_MATCH_DEV_PROTOCOL=$((0x0040))USB_MATCH_INT_CLASS=$((0x0080))USB_MATCH_INT_SUBCLASS=$((0x0100))USB_MATCH_INT_PROTOCOL=$((0x0200))## stdin is "modules.usbmap" syntax# on return, all matching modules were added to $DRIVERS#usb_map_modules (){ local line module # look at each usb_device_id entry # collect all matches in $DRIVERS while read line do # comments are lines that start with "#" ... # be careful, they still get parsed by bash! case "$line" in \#*) continue ;; esac set $line module=$1 match_flags=$(($2)) idVendor=$(($3)) idProduct=$(($4)) bcdDevice_lo=$(($5)) bcdDevice_hi=$(($6)) bDeviceClass=$(($7)) bDeviceSubClass=$(($8)) bDeviceProtocol=$(($9)) shift 9 bInterfaceClass=$(($1)) bInterfaceSubClass=$(($2)) bInterfaceProtocol=$(($3)) : checkmatch $module : idVendor $idVendor $usb_idVendor if [ $USB_MATCH_VENDOR -eq $(( $match_flags & $USB_MATCH_VENDOR )) ] && [ $idVendor -ne $usb_idVendor ]; then continue fi : idProduct $idProduct $usb_idProduct if [ $USB_MATCH_PRODUCT -eq $(( $match_flags & $USB_MATCH_PRODUCT )) ] && [ $idProduct -ne $usb_idProduct ]; then continue fi : bcdDevice range $bcdDevice_hi $bcdDevice_lo actual $usb_bcdDevice if [ $USB_MATCH_DEV_LO -eq $(( $match_flags & $USB_MATCH_DEV_LO )) ] && [ $usb_bcdDevice -lt $bcdDevice_lo ]; then continue fi # bcdDevice_lo <= bcdDevice <= bcdDevice_hi if [ $USB_MATCH_DEV_HI -eq $(( $match_flags & $USB_MATCH_DEV_HI )) ] && [ $usb_bcdDevice -gt $bcdDevice_hi ]; then continue fi : bDeviceClass $bDeviceClass $usb_bDeviceClass if [ $USB_MATCH_DEV_CLASS -eq $(( $match_flags & $USB_MATCH_DEV_CLASS )) ] && [ $bDeviceClass -ne $usb_bDeviceClass ]; then continue fi : bDeviceSubClass $bDeviceSubClass $usb_bDeviceSubClass if [ $USB_MATCH_DEV_SUBCLASS -eq $(( $match_flags & $USB_MATCH_DEV_SUBCLASS )) ] && [ $bDeviceSubClass -ne $usb_bDeviceSubClass ]; then continue fi : bDeviceProtocol $bDeviceProtocol $usb_bDeviceProtocol if [ $USB_MATCH_DEV_PROTOCOL -eq $(( $match_flags & $USB_MATCH_DEV_PROTOCOL )) ] && [ $bDeviceProtocol -ne $usb_bDeviceProtocol ]; then continue fi # NOTE: for now, this only checks the first of perhaps # several interfaces for this device. : bInterfaceClass $bInterfaceClass $usb_bInterfaceClass if [ $USB_MATCH_INT_CLASS -eq $(( $match_flags & $USB_MATCH_INT_CLASS )) ] && [ $bInterfaceClass -ne $usb_bInterfaceClass ]; then continue fi : bInterfaceSubClass $bInterfaceSubClass $usb_bInterfaceSubClass if [ $USB_MATCH_INT_SUBCLASS -eq $(( $match_flags & $USB_MATCH_INT_SUBCLASS )) ] && [ $bInterfaceSubClass -ne $usb_bInterfaceSubClass ]; then continue fi : bInterfaceProtocol $bInterfaceProtocol $usb_bInterfaceProtocol if [ $USB_MATCH_INT_PROTOCOL -eq $(( $match_flags & $USB_MATCH_INT_PROTOCOL )) ] && [ $bInterfaceProtocol -ne $usb_bInterfaceProtocol ]; then continue fi # It was a match! DRIVERS="$module $DRIVERS" : drivers $DRIVERS done}## declare a REMOVER name that the add action can use to create a# remover, or that the remove action can use to execute a remover.#if [ "$DEVPATH" != "" ]; then # probably, 2.6.x REMOVER=/var/run/usb/$(echo -n $SYSFS/$DEVPATH | sed -e 's;/;%;g')elif [ "$DEVICE" != "" ]; then # 2.4.x? REMOVER=/var/run/usb/$(echo $DEVICE | sed -e 's;/;%;g')else # should not happen? REMOVER=/var/run/usb/$(echo "$INTERFACE/$PRODUCT/$TYPE" | sed -e 's;/;%;g')fiexport REMOVER## What to do with this USB hotplug event?#case $ACTION inadd) # partial workaround for 2.4 uhci/usb-uhci driver problem: they don't # queue control requests, so device drivers can confuse each other if # they happen to issue requests at the same time ... it happens easily # with slow HID devices and "usbmodules". # starting with 2.5 (DEVPATH set), all hcds must queue control traffic. if [ "$DEVPATH" = "" ]; then sleep 3 fi usb_convert_vars FOUND=false if [ -f $SYSFS/$DEVPATH/manufacturer ]; then LABEL="USB `cat $SYSFS/$DEVPATH/manufacturer` `cat $SYSFS/$DEVPATH/product`" else LABEL="USB product $PRODUCT" fi if [ -e "$REMOVER" ]; then rm -f "$REMOVER" fi # on 2.4 systems, modutils 2.4.2+ maintains MAP_CURRENT # ... otherwise we can't rely on it (sigh) case "$KERNEL" in 2.4.*|2.5.*|2.6.*) if [ -r $MAP_CURRENT ]; then load_drivers usb $MAP_CURRENT "$LABEL" fi;; *) if [ -r $MAP_DISTMAP ]; then load_drivers usb $MAP_DISTMAP "$LABEL" fi;; esac if [ "$DRIVERS" != "" ]; then FOUND=true fi # cope with special driver module configurations # (mostly HID devices, until we have an input.agent) # not needed on 2.6 - they are loaded by hotplug case "$KERNEL" in 2.6.* ) : nothing ;; * ) if [ -r $MAP_HANDMAP ]; then load_drivers usb $MAP_HANDMAP "$LABEL" if [ "$DRIVERS" != "" ]; then FOUND=true fi fi ;; esac # some devices have user-mode drivers (no kernel module, but config) # or specialized user-mode setup helpers MODPROBE=: for MAP in $MAP_USERMAP $HOTPLUG_DIR/usb/*.usermap do if [ -r $MAP ]; then load_drivers usb $MAP "$LABEL" if [ "$DRIVERS" != "" ]; then FOUND=true fi fi done if [ "$FOUND" = "false" ]; then debug_mesg "... no modules for $LABEL" exit 2 fi ;;remove) if [ -x $REMOVER ]; then $REMOVER fi rm -f $REMOVER if [ -x /usr/sbin/updfstab ]; then /usr/sbin/updfstab fi ;;*) debug_mesg USB $ACTION event not supported exit 1 ;;esac
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -