# -*- shell-script -*-

# 03adapter_scsi_proc - SCSI adapter support using /proc/scsi.

# This file is part of the Linux lsvpd package.

# (C) Copyright IBM Corp. 2002, 2003, 2004

# Maintained by Martin Schwenke <martins@au.ibm.com>

# 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
    
# $Id: 03adapter_scsi_proc,v 1.10 2004/06/17 05:42:45 martins Exp $

[ -d "/proc/scsi" ] || return 0

######################################################################

# unset -f this function if name lookups can be done dynamically.
adapter_setup_scsi ()
{
    local d info
    local conf="${libdir}/scsihost.conf"
    # Possibly 1 too many loops here, but it lets us handle specific
    # drivers only, and we don't get mixed up by things like "sg".
    for d in $(sed -e '/^#/d' -e 's/:.*$//' "$conf") ; do
	for info in /proc/scsi/${d}/*; do

	    local num="${info##*/}" # basename

	    # Sanity check.
	    [ -n "${num//[0-9]/}" ] && continue

	    IFS=":"
	    set -o noglob
	    set -- $(grep "^${d}:" "$conf")
	    set +o noglob
	    unset IFS
	    local buspat="$2"
	    local devpat="$3"
	    local funpat="$4"
	    local irqpat="$5"
	    local buspref="$6"
	    local devpref="$7"
	    local funpref="$8"
	    local irqpref="$9"

	    local bus=$(scsi_proc_get_host_frag "$info" "$buspat" "$buspref")
	    local dev=$(scsi_proc_get_host_frag "$info" "$devpat" "$devpref")
	    local fun=$(scsi_proc_get_host_frag "$info" "$funpat" "$funpref")
	    local irq=$(scsi_proc_get_host_frag "$info" "$irqpat" "$irqpref")

	    [ -n "$irq" ] || irq="*"

	    # This is a workaround for Linux 2.4, since $bus is only a
	    # u_char in some of the SCSI drivers.
	    local dom
	    local yip=$(printf "%02x:%02x.%x-%s" "$bus" "$dev" "$fun" "$irq")
	    pci_hack_dom_bus_hook "scsi" "$yip"
	    
	    if [ -n "$dom" -a -n "$bus" ] ; then
		    local pci_addr=$(printf "%04x:%02x:%02x.%x" \
			"$dom" "$bus" "$dev" "$fun")
		    local prefix=$(get_adapter_os_prefix "scsi")
		    do_adapter_crosslink \
			"scsi" "pci/${pci_addr}" "${prefix}${num}"
	    fi
	done
    done
}

######################################################################

scsi_proc_get_host_frag ()
{
    local file="$1"
    local sedpat="$2"
    local prefix="$3"

    local tmp=$(sed -n -e "s/${sedpat}/\1/" \
		       -e 's/^\([0-9A-Fa-f][0-9A-Fa-f]*\)$/\1/p' "$file")
    [ -n "$tmp" ] && echo "${prefix}${tmp}"
}
