#!/bin/sh # # usb.rc This brings the USB subsystem up and down safely. # # $Id: usb.rc,v 1.2 2002/02/25 23:02:14 woodchip Exp $ # # Best invoked via /etc/init.d/hotplug or equivalent, with # writable /tmp, /usr mounted, and syslogging active. # # Bus management is basically unrelated to runlevel changes; it # relates to physical topology, including possibly hotpluggable # busses (USB, Cardbus) or controllers. If a bus is physically # present, it should normally be available. # # USB-dependant systems (iMacs, Aero, and so on) should statically # link USB keyboard support into the kernel (USB core, UHCI/OHCI, # hid, input, keybdev; and likely mousedev) so the system console # can't be removed by accident. # # Modified for Gentoo linux, sworley 2002-02-20 PATH=/sbin:/bin:/usr/sbin:/usr/bin STATIC_MODULE_LIST= # USBD_ENABLE=true X11_USBMICE_HACK=false # override any of the defaults above? if [ -f /etc/conf.d/usb ]; then . /etc/conf.d/usb # e.g. USBD_ENABLE=false but STATIC_MODULE_LIST has your devices fi MOUSE_MODULES="mousedev input" # In its currently-recommended configuration, XFree86 3.3.6 always opens # /dev/input/mice; so mousedev and input must be loaded before X11 starts. if [ $X11_USBMICE_HACK = true ]; then STATIC_MODULE_LIST="$MOUSE_MODULES $STATIC_MODULE_LIST" fi usb_boot_events () { # synthesize hotplug events if we can # we need (non-bash) programs to parse descriptors. LISTER=`type -p usbmodules` if [ "$LISTER" = "" -o ! -f /proc/bus/usb/devices ]; then echo $"** can't synthesize root hub events" return 1 fi # make sure the usb agent will run ACTION=add PRODUCT=0/0/0 export ACTION PRODUCT DEVFS=/proc/bus/usb DEVICE= export DEVFS DEVICE # these notifications will be handled by pcimodules for DEVICE in /proc/bus/usb/*/* do /etc/hotplug/usb.agent done } maybe_start_usb () { local COUNT SYNTHESIZE COUNT=0 SYNTHESIZE=false # if USB is partially initted, synthesize hotplug events since # the kernel probably dropped them (missing root, unwritable /tmp) if [ -d /proc/bus/usb -a `ls /proc/bus/usb 2>&1 | wc -l` -gt 2 ]; then SYNTHESIZE=true fi # if distro hasn't already done part of this ... load core, # and mount usbdevfs before the first hotplug agent fires # (so it'll be available to the agents). modprobe -q usbcore >/dev/null 2>&1 if [ -d /proc/bus/usb ]; then # if it's not mounted, try to mount it if [ ! -f /proc/bus/usb/devices ]; then if grep -q "[ ]/proc/bus/usb[ ]" /etc/fstab ; then mount /proc/bus/usb else mount -t usbdevfs usbdevfs /proc/bus/usb fi fi fi # Load Host Controller Drivers (HCDs) ... this automatically handles # systems with _both_ UHCI and OHCI controllers, without relying on # /proc or tools (lspci -v|grep USB, etc) to do so. If hotplugging # is enabled on this system, initting a root hub will cause hotplug # events to fire for every device on the tree at that root. # NOTE: this prefers "usb-uhci"; you may prefer "uhci". # FIXME: all this should be driven by PCI hotplugging, and have # the blacklist control which uhci driver gets used. modprobe -q ehci-hcd >/dev/null 2>&1 modprobe -q usb-ohci >/dev/null 2>&1 modprobe -q usb-uhci >/dev/null 2>&1 || modprobe -q uhci >/dev/null 2>&1 # modprobe -q uhci >/dev/null 2>&1 || modprobe -q usb-uhci >/dev/null 2>&1 if [ -d /proc/bus/usb ]; then # If we see there are no busses, we "failed" and # can report so even if we're partially nonmodular. COUNT=`ls /proc/bus/usb | wc -l` if [ $COUNT -le 2 ]; then umount /proc/bus/usb rmmod usbcore >/dev/null 2>&1 return 1 fi # if USB is fully modular and yet can clean up, # we know init failed without needing usbdevfs elif rmmod usbcore >/dev/null 2>&1; then return 1 fi # hotplug events didn't fire during booting; # cope with devices that enumerated earlier # and may not have been fully configured. if [ $SYNTHESIZE = true ]; then usb_boot_events fi # Some modules are statically loaded, perhaps because they are # needed to activate filesystem device nodes. for MODULE in $STATIC_MODULE_LIST; do modprobe $MODULE done # we did everything we could ... return 0 } maybe_stop_usb () { # call this multiple times if you had to take down components of the # USB subsystem by hand; it cleans up whatever can # be cleaned up, letting the system quiesce further. # disconnect all controllers we can, and kernel drivers # HCDs first, so most drivers reduce their use counts. rmmod usb-ohci usb-uhci uhci >/dev/null 2>&1 rmmod ehci-hcd hcd >/dev/null 2>&1 # user mode code may keep usbdevfs busy for a while yet ... # OK, usbcore won't actually be removed unless there happen to be # no USB drivers loaded, and usbdevfs isn't mounted. let's force # removal of autocleanable modules before trying to rmmod usbcore rmmod -as # Now let's workaround the fact that some USB modules never increase # their module use counts, so that "rmmod -a" won't unload them. # (And we can't use "modprobe --autoclean" anyway.) rmmod joydev keybdev wacom wmforce >/dev/null 2>&1 rmmod cpia_usb cpia dc2xx rio500 mdc800 scanner >/dev/null 2>&1 rmmod acm audio ibmcam uss720 printer hid >/dev/null 2>&1 rmmod microtek dsbr100 evdev pegasus plusb >/dev/null 2>&1 rmmod usb-serial usb-storage net1080 usbnet kaweth >/dev/null 2>&1 rmmod ov511 videodev belkin_sa digi_acceleport empeg ftdi_sio >/dev/null 2>&1 rmmod keyspan_pda keyspan omninet visor whiteheat usbserial >/dev/null 2>&1 rmmod bluetooth dabusb mct_u232 >/dev/null 2>&1 rmmod usbmouse usbkbd >/dev/null 2>&1 rmmod $STATIC_MODULE_LIST >/dev/null 2>&1 # ok, hope that user mode drivers/managers closed their fds. umount /proc/bus/usb >/dev/null 2>&1 rmmod usbcore >/dev/null 2>&1 # we did everything we could ... return 0; } # See how we were called. case "$1" in start) maybe_start_usb ;; stop) maybe_stop_usb ;; status) echo $"USB Status for kernel: " `uname -srm` echo '' if [ -f /proc/bus/usb/devices ]; then COUNT=`ls /proc/bus/usb | wc -l` if [ $COUNT -gt 2 ]; then COUNT=`expr $COUNT - 2` echo $"USB up; bus count is $COUNT" grep "^[TPSI]:" /proc/bus/usb/devices else echo $"$USB-devfs partially up; no busses" fi echo '' echo $"USB Drivers Loaded: " cat /proc/bus/usb/drivers else echo $"USB-devfs is unavailable. " if [ -f /proc/modules ] && fgrep -q usbcore /proc/modules; then echo $"USB module is loaded. " else echo $"USB may be statically linked. " fi echo $"If khubd is running, that shows USB is available." fi echo '' if [ -f /proc/sys/kernel/hotplug ]; then echo $"khubd/hotplug thread: " else echo $"khubd thread:" fi ps -l | head -1 ps -Al | egrep 'khubd' | grep -v grep echo '' lsmod echo '' # /proc/devices too? "usb", "input", and others ... ;; restart) # always invoke by absolute path, else PATH=$PATH: $0 stop && $0 start ;; *) echo $"Usage: $0 {start|stop|status|restart}" exit 1 esac