#!/bin/bash
#*****************************************************************************
# Copyright 2004-2007 LSI Logic Corporation.
#
# 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,  version 2 of the License.
#
# 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.
#*****************************************************************************

#  Script %name:	lsvdev26p %
#  Instance:		WIC_1
#  %version:		4 %
#  Description:		List device mapping of Engenio virtaul devices and sd devices
#  %created_by:		sdachepa %
#  %date_created:	Mon Feb 04 18:20:34 2008 %

if [ "$(ls -l /sys/devices/mppvirtual/mppadapter0/ 2> /dev/null | grep -c host)" != 0 ]
then
	HAS_TARGET_OBJECTS="$(ls -l /sys/devices/mppvirtual/mppadapter0/host*/ 2> /dev/null |grep -c target)"
else
	HAS_TARGET_OBJECTS="-1"
fi

#*****************************************************************************
#  Function:   mppLnx_init_fn
#  Description:  Initialize and export all needed variables
#*****************************************************************************
mppLnx_init_fn()
{
    #get virtual target and array name mapping
    MPPLNX_VTID_NAME_MAP=$(/usr/sbin/mppUtil -a|awk '{ if (/^ *[0-9]/) printf("%s %s\n", $1, $4)}')

    if [ "$HAS_TARGET_OBJECTS" = -1 ]
    then
        MPPLNX_VDEV_BLOCK_DEVS="";
        echo "No MPP Virtual Devices Detected."
        exit 1;
    else
        if [ "$HAS_TARGET_OBJECTS" = 0 ]
        then
            MPPLNX_VDEV_BLOCK_DEVS=$(ls -l -1 /sys/devices/mppvirtual/mppadapter0/host*/*:*/block 2> /dev/null)
        else
            # on a 2.6.16 system, the block device has the format of 
            # /sys/devices/mppvirtual/mppadapter0/host6/target6:0:0/6:0:0:0/block:sdf -> ../../../../../../block/sdf
            # on a 2.6.9 system (AS4), the format is
            #/sys/devices/mppvirtual/mppadapter0/host4/target4:0:1/4:0:1:0/block -> ../../../../../../block/sdb

            MPPLNX_VDEV_BLOCK_DEVS=$(ls -l -1 /sys/devices/mppvirtual/mppadapter0/host*/target*/*:*/block* 2> /dev/null)
        fi
    fi

    export    MPPLNX_MAGIC_LINE="mpplnx_magic_line"
    export    NEWLINE=$'\n'
}
#*****************************************************************************
#  Function:   mppLnx_pre_exec_check_fn
#  Description:  perform pre-execution-check 
#*****************************************************************************
mppLnx_pre_exec_check_fn()
{
    if [ ! -x /usr/sbin/mppUtil ]
    then
        echo "/usr/sbin/mppUtil is not installed. $0 cannot be executed!"
        exit 1
    fi

    MPP_VHBA="168$(lsmod |grep mppVhba)"

    if [ "${MPP_VHBA}" == "168" ]
    then
        echo "mppVhba.ko is not loaded. $0 cannot be executed!"
        exit 1
    fi
}
#*****************************************************************************
#  Function:   mppLnx_report_map_fn
#  Description:  generate device mapping
#*****************************************************************************
mppLnx_report_map_fn()
{
    echo  "${MPPLNX_VTID_NAME_MAP}${NEWLINE}${MPPLNX_MAGIC_LINE}${NEWLINE}${MPPLNX_VDEV_BLOCK_DEVS}"\
   |/usr/bin/awk -F"/"\
   -v MPPLNX_MAGIC_LINE=${MPPLNX_MAGIC_LINE}\
   'BEGIN{
      first_tid = -100
      tid_count = 0
   }
   {
      if( $0 == MPPLNX_MAGIC_LINE )
           {
                  tid_map_done=100
           }else
           {
                  if(tid_map_done == 100)
                  {
	             if ($0 ~ "target")
                     {
                          sddev=$16
                          #$8 is h:c:t:l
                          split($8,hctl,":");
                          tid=  hctl[3]
                          lun = hctl[4]
                     }
                     else
                     {
                          sddev=$14
                          #$7 is h:c:t:l
                          split($7,hctl,":");
                          tid=  hctl[3]
                          lun = hctl[4]
                     }
            hash_index=tid "-" lun
            devices[hash_index]=sddev
                  }else
                  {
            split($0,mappingline," ");

            if( first_tid == -100)
            {
               first_tid = mappingline[1]
            }

                      tid_mappings[mappingline[1]] = mappingline[2]
            tid_count=mappingline[1]
                  }
           }
       }END{
      printf("\t%-15s %-5s  %s\n","Array Name","Lun","sd device");
      printf("\t-------------------------------------\n")
      for(tid=first_tid; tid<=tid_count; tid++)
      {
         for(lun=0; lun<256; lun++)
         {
            hash_index=tid "-" lun
            #printf("hash_index %s device %s\n",hash_index, devices[hash_index])
            if(devices[hash_index])
            {
               printf("\t%-15s %-5s -> /dev/%s\n",tid_mappings[tid],lun,devices[hash_index]);
            }
         }
      }
   }'
}
#*****************************************************************************
#  Function:   mppLnx_main_fn
#  Description:  Put everything together
#*****************************************************************************
mppLnx_main_fn()
{
    mppLnx_pre_exec_check_fn
    mppLnx_init_fn
    mppLnx_report_map_fn
}

mppLnx_main_fn
