> > alsasound script calls alsactl and card-specific scripts (if any).
> > this should be avoided in the case of partial load.
> 
> Yes, I took care of executing them just for the cards that had been
> loaded. 
> 
> > IIRC, modprobe returns 0 even if called with the existing module.
> > (if the load failed, it returns 255, btw).
> > thus, we cannot check this only from the return value of modprobe.
> > instead we need to grep /proc/asound/modules for that module.
> 
> That's what I'm doing, more or less. I'm including a copy of the
> modified alsasound script I'm testing. Seems to be working fine so far. 
> 
> I think the sequencer driver part is wrong. I don't know what is
> expected there (ie: multiple drivers?). I suspect I have to turn that
> part of the code into a loop iterating over all sequencer drivers. 

It was wrong, of course... I'm including an updated script that is
apparently working fine. Takes into account multiple sequencer drivers
and executes scripts only for devices loaded while it runs. 

-- Fernando

#!/bin/bash
#
# alsasound     This shell script takes care of starting and stopping
#               the ALSA sound driver.
#
# This script requires /usr/sbin/alsactl and /usr/bin/aconnect programs
# from the alsa-utils package.
#
# Copyright (c) by Jaroslav Kysela <[EMAIL PROTECTED]> 
#
#
#  This program is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
#
#
# For RedHat 5.0+:
# chkconfig: 2345 87 14
# description: ALSA driver
#
# modified to visually fit into SuSE 6.0+ by Philipp Thomas <[EMAIL PROTECTED]>
# further improvements by Bernd Kaindl, Olaf Hering and Takashi Iwai.
# 
### BEGIN INIT INFO
# Provides:       alsasound
# Required-Start: $remote_fs
# Required-Stop: $remote_fs
# Default-Start:  2 3 5
# Default-Stop:
# Description:    Loading ALSA drivers and store/restore the current setting
### END INIT INFO

if [ -e /etc/rc.d/init.d/functions ] ; then
  # redhat function library
  redhat=1
  . /etc/rc.d/init.d/functions
fi

if [ -r /etc/rc.config ]; then
  . /etc/rc.config
  rc_warning="\033[33m\033[1m"
else
  rc_done="done"
  rc_warning=""
  rc_reset=""
fi

if [ x$START_ALSA != xno ]; then
  START_ALSA=yes
fi
if [ x$START_ALSA_SEQ != xno ]; then
  START_ALSA_SEQ=yes
fi

# Determine the base and follow a runlevel link name.
base=${0##*/}
link=${base#*[SK][0-9][0-9]}

# Force execution if not called by a runlevel directory.
test $link = $base && START_ALSA=yes
test "$START_ALSA" = yes || exit 0

alsactl=/usr/sbin/alsactl
asoundcfg=/etc/asound.state
aconnect=/usr/bin/aconnect
alsascrdir=/etc/alsa.d

function start() {
  #
  # insert all sound modules that are not already loaded
  #
  drivers=`/sbin/modprobe -c | \
    grep -E "^[[:space:]]*alias[[:space:]]+snd-card-[[:digit:]]" | \
    awk '{print $3}'`
  loaded=""
  for i in $drivers; do
    if [ "$i" != off ]; then
	is_loaded=`grep -c ^$i /proc/modules`
	if [ "$is_loaded" == "0" ]; then
	    if [ $redhat ] ; then
		action "Starting sound driver $i" /sbin/modprobe $i
		if [ "$?" == "0" ]; then loaded="$loaded $i" ; fi
	    else
		echo -n "Starting sound driver: $i "
		/sbin/modprobe $i
		if [ "$?" == "0" ]; then loaded="$loaded $i" ; fi
		echo -e "$rc_done"
	    fi
	else
	    if [ $redhat ] ; then
		echo "Sound driver $i is already loaded"
	    fi
	fi
    fi
  done
  #
  # insert sequencer modules that are not already loaded
  #
  if [ x"$START_ALSA_SEQ" = xyes -a -r /proc/asound/seq/drivers ]; then
    seq_drivers=`cut -d , -f 1 /proc/asound/seq/drivers`
    for i in $seq_drivers; do
	is_loaded=`grep -c ^$i /proc/modules`
	if [ "$is_loaded" == "0" ]; then
	    if [ $redhat ] ; then
		action "Starting sequencer driver $i" /sbin/modprobe $i
	    else
		/sbin/modprobe $i
	    fi
	else
	    if [ $redhat ] ; then
		echo "Sequencer driver $i is already loaded"
	    fi
	fi
    done
  fi
  #
  # restore driver settings
  #
  if [ -d /proc/asound ]; then
    if [ ! -r $asoundcfg ]; then
      echo "No mixer config in $asoundcfg, you have to unmute your card!"
    else
      if [ -x $alsactl ]; then
	if [ $redhat ] ; then
	    action "Restoring sound driver settings" $alsactl -f $asoundcfg restore
	else
	    $alsactl -f $asoundcfg restore
	fi
      else
	if [ $redhat ] ; then
	    echo -n "Sound driver: could not find alsactl"
	    failure "Finding alsactl" && echo
	else
	    echo -e "${rc_warning}ERROR: alsactl not found${rc_reset}"
	fi
      fi
    fi
  fi
  #
  # run card-dependent scripts only for drivers we loaded
  #
  for i in $loaded; do
    t=${i##snd-}
    if [ -x $alsascrdir/$t ]; then
	if [ $redhat ] ; then
	    action "Running $t script" $alsascrdir/$t
	else
	    $alsascrdir/$t
	fi
    fi
  done
  #
  # touch lockfile if lockdir exists
  #
  if [ -d /var/lock/subsys ] ; then
    touch /var/lock/subsys/alsasound
  fi
}

function terminate() {
  #
  # Kill processes holding open sound devices
  #
  # DEVS=`find /dev/ -follow -type c -maxdepth 1 -print 2>/dev/null | xargs ls -dils | grep "1*1[46]," | cut -d: -f2 | cut -d" " -f2; echo /proc/asound/dev/*`
  ossdevs="/dev/admmidi? /dev/adsp? /dev/amidi? /dev/audio* /dev/dmfm* \
     /dev/dmmidi? /dev/dsp* /dev/dspW* /dev/midi0? /dev/mixer? /dev/music \
     /dev/patmgr? /dev/sequencer* /dev/sndstat"
  alsadevs="/proc/asound/dev/*"
  fuser -k $ossdevs $alsadevs 2> /dev/null 1>/dev/null
  #
  # remove all sequencer connections if any
  #
  if [ -f /proc/asound/seq/clients -a -x $aconnect ]; then
    $aconnect --removeall
  fi
}

function stop() {
  #
  # store driver settings
  # [nando: we always initialize the driver to the default settings]
  #
  # if [ -x $alsactl ]; then
  #   $alsactl -f $asoundcfg store
  # else
  #   echo -n -e "${rc_warning}!!!alsactl not found!!!${rc_reset} "
  # fi
  #
  # remove all sound modules
  #
  /sbin/lsmod | grep -E "^snd" | grep -Ev "^(snd-page-alloc|snd-hammerfall-mem)" | while read line; do \
     /sbin/rmmod `echo $line | cut -d ' ' -f 1`; \
  done
  # remove the 2.2 soundcore module (if possible)
  /sbin/rmmod soundcore 2> /dev/null
  /sbin/rmmod gameport 2> /dev/null

  #
  # remove lockfile if lockdir exists
  #
  if [ -d /var/lock/subsys ] ; then
    rm -f /var/lock/subsys/alsasound
  fi
}

# See how we were called.
case "$1" in
  start)
        # Start driver if it isn't already up.
	if [ -d /proc/asound ]; then
	    echo "ALSA driver already running"
	fi
	start
	if [ $redhat ] ; then
	    if [ -d /proc/asound -a -d /var/lock/subsys ]; then
		touch /var/lock/subsys/alsasound
	    fi
	fi
        ;;
  stop)
        # Stop daemons.
	if [ -d /proc/asound ]; then
          echo -n "Shutting down sound driver"
	  terminate
	  stop
	  if [ $redhat ] ; then
	    if [ -d /var/lock/subsys ]; then
		rm -f /var/lock/subsys/alsasound
	    fi
	    success "sound driver stop" && echo
	  else
	    echo -e "$rc_done"
	  fi
	fi
        ;;
  restart|reload)
	$0 stop
	$0 start
	;;
  status)
        if [ -d /proc/asound ]; then
          echo -n "ALSA sound driver loaded."
        else
          echo -n "ALSA sound driver not loaded."
        fi
        echo
        ;;
  *)
        echo "Usage: alsasound {start|stop|restart|status}"
        exit 1
esac

exit 0

Reply via email to