home *** CD-ROM | disk | FTP | other *** search
/ HAKERIS 11 / HAKERIS 11.ISO / linux / system / LinuxConsole 0.4 / linuxconsole0.4install-en.iso / linuxconsole0.4.lcm / etc / hotplug / usb.agent.back < prev    next >
Encoding:
Text File  |  2004-03-26  |  10.1 KB  |  369 lines

  1. #!/bin/bash
  2. #
  3. # USB-specific hotplug policy agent.
  4. #
  5. # This should handle 2.2.18+ and 2.4.* USB hotplugging,
  6. # with a consistent framework for adding device and driver
  7. # specific treatments.
  8. #
  9. # Kernel USB hotplug params include:
  10. #    
  11. #    ACTION=%s [add or remove]
  12. #    PRODUCT=%x/%x/%x
  13. #    INTERFACE=%d/%d/%d
  14. #    TYPE=%d/%d/%d
  15. #
  16. # And if usbfs (originally called usbdevfs) is configured, also:
  17. #
  18. #    DEVFS=/proc/bus/usb
  19. #    DEVICE=/proc/bus/usb/%03d/%03d
  20. #
  21. # This script then adds the variable:
  22. #
  23. #       REMOVER=/var/run/usb/<some string unique to $DEVICE>
  24. #
  25. # This is the path where the script would like to find a remover, if
  26. # the target device needs one. This script is executed on remove if
  27. # it is executable when the remove happens.
  28. #
  29. # If usbfs is mounted on /proc/bus/usb, $DEVICE is a file which
  30. # can be read to get the device's current configuration descriptor.
  31. # (The "usbmodules" utility helps do that.)
  32. #
  33. # On systems using Linux 2.4.* kernels, be sure to use the right
  34. # modutils (2.4.2+).  That ensures that hotplugging uses the list
  35. # of modules installed for your kernel, rather than the one that's
  36. # included here for use on systems without MODULE_DEVICE_TABLE
  37. # support.
  38. #
  39. #
  40. # HISTORY:
  41. #
  42. # 18-Jan-2002    fix match algorithm in usb_map_modules()
  43. # 14-Jan-2002    fix work around 2.2 brokeness of $PRODUCT
  44. # 09-Jan-2002    REMOVER for system without usbdevfs
  45. # 14-Mar-2001    Cleanup, bitmask the match_flags
  46. # 26-Feb-2001    Cleanup, support comments (Gioele Barabucci)
  47. # 23-Jan-2001    Update 2.2 handling; unfortunately there's no "feature
  48. #        test" that can work robustly
  49. # 05-Jan-2001    Quick hack for kernel 2.4.0 and modutils 2.4.1
  50. # 03-Jan-2001    Initial version of "new" hotplug agent, using feedback
  51. #        and contributions from Adam Richter, Ryan VanderBijl,
  52. #        Norbert Preining, Florian Lohoff, David Brownell and
  53. #        others.  To replace the original /etc/usb/policy. (db)
  54. # 15-Feb-2001    Remove use of "<<" (Adam Richter)
  55. #
  56. # $Id: usb.agent,v 1.22 2002/04/01 21:15:24 dbrownell Exp $
  57. #
  58.  
  59. if [ -f /etc/sysconfig/usb ]; then
  60.     . /etc/sysconfig/usb
  61. fi
  62.  
  63. cd /etc/hotplug
  64. . hotplug.functions
  65. # DEBUG=yes export DEBUG
  66.  
  67. # generated by modutils, for current 2.4.x kernels
  68. MAP_CURRENT=$MODULE_DIR/modules.usbmap
  69.  
  70. # used if MAP_CURRENT is missing; for 2.2.x kernels
  71. MAP_DISTMAP=$HOTPLUG_DIR/usb.distmap
  72.  
  73. #
  74. # used for kernel drivers that don't show up in CURRENT or DISTMAP,
  75. # currently input drivers (joysticks, UPSs, etc) and usb storage;
  76. #
  77. MAP_HANDMAP=$HOTPLUG_DIR/usb.handmap
  78.  
  79. #
  80. # used to run config scripts for user mode drivers (jPhoto, gPhoto2,
  81. # rio500 tools, etc) ... instead of naming kernel modules, it names
  82. # config scripts (which mustn't overlap with kernel modules).  Those
  83. # could change $DEVICE permissions, etc.
  84. #
  85. MAP_USERMAP=$HOTPLUG_DIR/usb.usermap
  86.  
  87.  
  88. # accumulates list of modules we may care about
  89. DRIVERS=""
  90.  
  91. if [ "$PRODUCT" = "" -o "$ACTION" = "" ]; then
  92.     mesg Bad USB agent invocation
  93.     exit 1
  94. fi
  95.  
  96. # we can't "unset IFS" on bash1, so save a copy
  97. DEFAULT_IFS="$IFS"
  98.  
  99. #
  100. # Each modules.usbmap format line corresponds to one entry in a
  101. # MODULE_DEVICE_TABLE(usb,...) declaration in a kernel file.
  102. #
  103. # Think of it as a database column with up to three "match specs"
  104. # to associate kernel modules with particular devices or classes
  105. # of device.  The match specs provide a reasonably good filtering
  106. # mechanism, but some driver probe() routines need to provide
  107. # extra filtering.
  108. #
  109. declare -i usb_idVendor usb_idProduct usb_bcdDevice
  110. declare -i usb_bDeviceClass usb_bDeviceSubClass usb_bDeviceProtocol
  111. declare -i usb_bInterfaceClass usb_bInterfaceSubClass usb_bInterfaceProtocol
  112.  
  113. usb_convert_vars ()
  114. {
  115.     if [ "$AWK" = "" ]; then
  116.     mesg "can't find awk!"
  117.     exit 1
  118.     fi
  119.  
  120.     # work around 2.2 brokenness
  121.     # munges the usb_bcdDevice such that it is a integer rather
  122.     # than a float: e.g. 1.0 become 0100
  123.     PRODUCT=`echo $PRODUCT | sed -e "s+\.\([0-9]\)$+.\10+" -e "s/\.$/00/" \
  124.                                   -e "s+/\([0-9]\)\.\([0-9][0-9]\)+/0\1\2+" \
  125.               -e "s+/\([0-9][0-9]\)\.\([0-9][0-9]\)+/\1\2+"`
  126.     set `echo $PRODUCT | $AWK -F/ '{print "0x" $1, "0x" $2, "0x" $3 }'` ''
  127.     usb_idVendor=$1
  128.     usb_idProduct=$2
  129.     usb_bcdDevice=$3
  130.  
  131.     if [ "$TYPE" != "" ]; then
  132.         IFS=/
  133.         set $TYPE ''
  134.     usb_bDeviceClass=$1
  135.         usb_bDeviceSubClass=$2
  136.         usb_bDeviceProtocol=$3
  137.     IFS="$DEFAULT_IFS"
  138.     else
  139.     # out-of-range values
  140.     usb_bDeviceClass=1000
  141.     usb_bDeviceSubClass=1000
  142.     usb_bDeviceProtocol=1000
  143.     fi
  144.  
  145.     if [ "$INTERFACE" != "" ]; then
  146.     IFS=/
  147.     set $INTERFACE ''
  148.     usb_bInterfaceClass=$1
  149.     usb_bInterfaceSubClass=$2
  150.         usb_bInterfaceProtocol=$3
  151.     IFS="$DEFAULT_IFS"
  152.     else
  153.     # out-of-range values
  154.     usb_bInterfaceClass=1000
  155.     usb_bInterfaceSubClass=1000
  156.     usb_bInterfaceProtocol=1000
  157.     fi
  158. }
  159.  
  160. declare -i USB_MATCH_VENDOR=0x0001
  161. declare -i USB_MATCH_PRODUCT=0x0002
  162. declare -i USB_MATCH_DEV_LO=0x0004
  163. declare -i USB_MATCH_DEV_HI=0x0008
  164. declare -i USB_MATCH_DEV_CLASS=0x0010
  165. declare -i USB_MATCH_DEV_SUBCLASS=0x0020
  166. declare -i USB_MATCH_DEV_PROTOCOL=0x0040
  167. declare -i USB_MATCH_INT_CLASS=0x0080
  168. declare -i USB_MATCH_INT_SUBCLASS=0x0100
  169. declare -i USB_MATCH_INT_PROTOCOL=0x0200
  170.  
  171. #
  172. # stdin is "modules.usbmap" syntax
  173. # on return, all matching modules were added to $DRIVERS
  174. #
  175. usb_map_modules ()
  176. {
  177.     # convert the usb_device_id fields to integers as we read them 
  178.     local line module
  179.     declare -i match_flags
  180.     declare -i idVendor idProduct bcdDevice_lo bcdDevice_hi
  181.     declare -i bDeviceClass bDeviceSubClass bDeviceProtocol
  182.     declare -i bInterfaceClass bInterfaceSubClass bInterfaceProtocol
  183.  
  184.     # look at each usb_device_id entry
  185.     # collect all matches in $DRIVERS
  186.  
  187.     while read line
  188.     do
  189.         # comments are lines that start with "#" ...
  190.     # be careful, they still get parsed by bash!
  191.     case "$line" in
  192.     \#*) continue ;;
  193.     esac
  194.  
  195.     set $line
  196.  
  197.     module=$1
  198.     match_flags=$2
  199.  
  200.     idVendor=$3
  201.     idProduct=$4
  202.     bcdDevice_lo=$5
  203.     bcdDevice_hi=$6
  204.  
  205.     bDeviceClass=$7
  206.     bDeviceSubClass=$8
  207.     bDeviceProtocol=$9
  208.  
  209.     shift 9
  210.     bInterfaceClass=$1
  211.     bInterfaceSubClass=$2
  212.     bInterfaceProtocol=$3
  213.  
  214.     : checkmatch $module
  215.  
  216.     : idVendor $idVendor $usb_idVendor
  217.         if [ $USB_MATCH_VENDOR -eq $(( $match_flags & $USB_MATCH_VENDOR )) ] && 
  218.        [ $idVendor -ne $usb_idVendor ]; then
  219.         continue
  220.     fi
  221.  
  222.     : idProduct $idProduct $usb_idProduct
  223.     if [ $USB_MATCH_PRODUCT -eq $(( $match_flags & $USB_MATCH_PRODUCT )) ] &&
  224.        [ $idProduct -ne $usb_idProduct ]; then
  225.         continue
  226.     fi
  227.  
  228.     : bcdDevice range $bcdDevice_hi $bcdDevice_lo actual $usb_bcdDevice
  229.     if [ $USB_MATCH_DEV_LO -eq $(( $match_flags & $USB_MATCH_DEV_LO )) ] &&
  230.        [ $usb_bcdDevice -lt $bcdDevice_lo ]; then
  231.         continue
  232.     fi
  233.  
  234.     # bcdDevice_lo <= bcdDevice <= bcdDevice_hi
  235.     if [ $USB_MATCH_DEV_HI -eq $(( $match_flags & $USB_MATCH_DEV_HI )) ] &&
  236.        [ $usb_bcdDevice -gt $bcdDevice_hi ]; then
  237.         continue
  238.     fi
  239.  
  240.     : bDeviceClass $bDeviceClass $usb_bDeviceClass
  241.     if [ $USB_MATCH_DEV_CLASS -eq $(( $match_flags & $USB_MATCH_DEV_CLASS )) ] &&
  242.        [ $bDeviceClass -ne $usb_bDeviceClass ]; then
  243.         continue
  244.     fi
  245.     : bDeviceSubClass $bDeviceSubClass $usb_bDeviceSubClass
  246.     if [ $USB_MATCH_DEV_SUBCLASS -eq $(( $match_flags & $USB_MATCH_DEV_SUBCLASS )) ] &&
  247.        [ $bDeviceSubClass -ne $usb_bDeviceSubClass ]; then
  248.         continue
  249.     fi
  250.     : bDeviceProtocol $bDeviceProtocol $usb_bDeviceProtocol
  251.     if [ $USB_MATCH_DEV_PROTOCOL -eq $(( $match_flags & $USB_MATCH_DEV_PROTOCOL )) ] &&
  252.        [ $bDeviceProtocol -ne $usb_bDeviceProtocol ]; then
  253.         continue
  254.     fi
  255.  
  256.     # NOTE:  for now, this only checks the first of perhaps
  257.     # several interfaces for this device.
  258.  
  259.     : bInterfaceClass $bInterfaceClass $usb_bInterfaceClass
  260.     if [ $USB_MATCH_INT_CLASS -eq $(( $match_flags & $USB_MATCH_INT_CLASS )) ] &&
  261.        [ $bInterfaceClass -ne $usb_bInterfaceClass ]; then
  262.         continue
  263.     fi
  264.     : bInterfaceSubClass $bInterfaceSubClass $usb_bInterfaceSubClass
  265.     if [ $USB_MATCH_INT_SUBCLASS -eq $(( $match_flags & $USB_MATCH_INT_SUBCLASS )) ] &&
  266.        [ $bInterfaceSubClass -ne $usb_bInterfaceSubClass ]; then
  267.         continue
  268.     fi
  269.     : bInterfaceProtocol $bInterfaceProtocol $usb_bInterfaceProtocol
  270.     if [ $USB_MATCH_INT_PROTOCOL -eq $(( $match_flags & $USB_MATCH_INT_PROTOCOL )) ] &&
  271.        [ $bInterfaceProtocol -ne $usb_bInterfaceProtocol ]; then
  272.         continue
  273.     fi
  274.  
  275.     # It was a match!
  276.     DRIVERS="$module $DRIVERS"
  277.     : drivers $DRIVERS
  278.     done
  279. }
  280.  
  281. #
  282. # declare a REMOVER name that the add action can use to create a
  283. # remover, or that the remove action can use to execute a remover.
  284. #
  285. if [ "$DEVICE" = "" ]; then
  286.   declare -rx REMOVER=/var/run/usb/`echo "$INTERFACE/$PRODUCT/$TYPE" | sed -e 's;/;%;g'`
  287. else
  288.   declare -rx REMOVER=/var/run/usb/`echo $DEVICE | sed -e 's;/;%;g'`
  289. fi
  290.  
  291. #
  292. # What to do with this USB hotplug event?
  293. #
  294. case $ACTION in
  295.  
  296. add)
  297.     # Let the usb subsystem finish talking to the device, before we do
  298.     # NOTE:  This hack doesn't fix the real problem. It seems to be
  299.     # needed for some HID devices because "usbmodules" does control
  300.     # messaging, and the HCDs don't all queue such messages safely.
  301.     sleep 3
  302.  
  303.     usb_convert_vars
  304.  
  305.     FOUND=false
  306.     LABEL="USB product $PRODUCT"
  307.  
  308.     if [ -e "$REMOVER" ]; then
  309.     rm -f "$REMOVER"
  310.     fi
  311.  
  312.     # on 2.4 systems, modutils 2.4.2+ maintains MAP_CURRENT
  313.     # ... otherwise we can't rely on it (sigh)
  314.     case "$KERNEL" in
  315.     2.4.*|2.5.*)
  316.     if [ -r $MAP_CURRENT ]; then
  317.         load_drivers usb $MAP_CURRENT "$LABEL"
  318.         echo load_drivers usb $MAP_DISTMAP "$LABEL" >> /tmp/tse23
  319.     fi;;
  320.     *)
  321.     if [ -r $MAP_DISTMAP ]; then
  322.         load_drivers usb $MAP_DISTMAP "$LABEL"
  323.         echo load_drivers usb $MAP_DISTMAP "$LABEL" >> /tmp/tse23
  324.     fi;;
  325.     esac
  326.     if [ "$DRIVERS" != "" ]; then
  327.     FOUND=true
  328.     fi
  329.  
  330.     # cope with special driver module configurations
  331.     # (mostly HID devices, until input can hotplug)
  332.     if [ -r $MAP_HANDMAP ]; then
  333.         load_drivers usb $MAP_HANDMAP "$LABEL"
  334.     if [ "$DRIVERS" != "" ]; then
  335.         FOUND=true
  336.     fi
  337.     fi
  338.  
  339.     # some devices have user-mode drivers (no kernel module, but config)
  340.     # or specialized user-mode setup helpers 
  341.     if [ -r $MAP_USERMAP ]; then
  342.     MODPROBE=:
  343.         load_drivers usb $MAP_USERMAP "$LABEL"
  344.     if [ "$DRIVERS" != "" ]; then
  345.         FOUND=true
  346.     fi
  347.     fi
  348.  
  349.     if [ "$FOUND" = "false" ]; then
  350.     mesg "... no modules for $LABEL"
  351.     exit 2
  352.     fi
  353.  
  354.     ;;
  355.  
  356. remove)
  357.     if [ -x $REMOVER ]; then
  358.     $REMOVER
  359.     fi
  360.     rm -f $REMOVER
  361.     ;;
  362.  
  363. *)
  364.     debug_mesg USB $ACTION event not supported
  365.     exit 1
  366.     ;;
  367.  
  368. esac
  369.