#!/bin/sh
#
# rc.usb       This brings the USB subsystem up and down safely
#
# chkconfig: 2345 9 91
# description: All USB system components that can get shut down
#	will get shut down; they're currently started on demand.
#	Best invoked via /etc/rc.d/rc.sysinit or equivalent, after
#	"depmod -a" has been run.  USB-only systems (iMacs, Aero,
#	and so on) likely will statically link USB keyboard support,
#	which this mustn't be able to shut down.
#
# $Id: rc.usb,v 1.3 2000/06/12 18:58:46 mojojojo Exp $

# see comments later; XFree86 3.3.6 (at least) needs this
X11_USBMICE_HACK=true

if [ -f /etc/sysconfig/usb ]; then
    . /etc/sysconfig/usb
fi

PATH=/sbin:/bin:/usr/sbin:/usr/bin

start_usbd ()
{
    # XXX first version of kusbd will have started already.
    # it should be OK to have another usbd also run, since
    # the policy script invocations should be idempotent.

    # if jusbd (or a later kusbd) can be run, do so
    if [ -x /etc/usb/usbd ]; then
	/etc/usb/usbd start > jUSBD.log 2>&1 &
    # else
    #   warn that no Plug'nPlay will be done here
    #   ... can't, given no kusbd indicators (yet)
    fi

}

stop_usbd ()
{
    # if jusbd (or kusbd ...) is running, stop it
    if [ -x /etc/usb/usbd ]; then
	/etc/usb/usbd stop
    fi
}


maybe_start_usb ()
{
    modprobe -q usb-ohci >/dev/null 2>&1
    # usb-uhci leaves evident debris; try uhci
    # 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

    # no /etc/fstab entry wanted; if you have one, use "noauto"
    # 1-user workstations may want usbdevfs option "devmode=0666"
    # XXX "mount /proc/bus/usb || mount -t ..."
    if mount -t usbdevfs none /proc/bus/usb
    then
	COUNT=`ls /proc/bus/usb | wc -l`
	if [ $COUNT -gt 2 ]; then
	    start_usbd				# busses exist
	    # USBD is now configuring existing devices in the background
	else
	    rmmod usbcore >/dev/null 2>&1	# no busses, clean up asap
	    return 1
	fi
    else
	start_usbd
    fi

    # In its currently-recommended configuration, XFree86 3.3.6 insists on
    # opening /dev/input/mice, so mousedev and input must be loaded before the
    # X11 server can start.  We can't wait for USBD to see such a mouse before
    # letting X start ...
    if [ $X11_USBMICE_HACK = true ]; then
	modprobe mousedev
    fi
}

maybe_stop_usb ()
{
    # call this multiple times if you had to take down components of the
    # USB subsystem by hand (e.g. kill usbd); it cleans up whatever it can.

    stop_usbd
    rmmod usb-ohci usb-uhci uhci >/dev/null 2>&1
    umount /proc/bus/usb >/dev/null 2>&1

    # 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 -a

    # XXX since "rmmod -a" is evidently a NOP ...
    rmmod joydev keybdev wacom wmforce >/dev/null 2>&1
    rmmod cpia_usb 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 >/dev/null 2>&1

    rmmod usbcore >/dev/null 2>&1

    # we clean up after ourselves
    if [ $X11_USBMICE_HACK = true ]; then
	rmmod mousedev input >/dev/null 2>&1
    fi
}

# See how we were called.
case "$1" in
  start)
	maybe_start_usb
        ;;
  stop)
	maybe_stop_usb
        ;;
  status)
	echo uname reports:  `uname -sr`
	echo ''

	if [ -x /etc/usb/usbd ]; then
	    /etc/usb/usbd status
	    echo ''
	fi

	echo "khubd thread:"
	ps -l | head -1
	ps -Al | grep khubd | grep -v grep
	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"
		cat /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."
	fi
	echo ''

	lsmod
	echo ''

	# /proc/devices too? "usb", "input", and others ...

	;;
  restart)
        cd $CWD
	$0 stop
	$0 start
	;;
  *)
        echo "Usage: usb {start|stop|status|restart}"
        exit 1
esac

