My first attachment did not pass.

amrstat.c :

/* amrstat.c 2002/04/10
 *
 * Author: Pierre David <[EMAIL PROTECTED]>
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

#include <machine/param.h>

#include "/usr/src/sys/dev/amr/amr_compat.h"
#include "/usr/src/sys/dev/amr/amrreg.h"
#include "/usr/src/sys/dev/amr/amrio.h"

#define NATTEMPTS       5
#define SLEEPTIME       100000          /* microseconds */

int nattempts = NATTEMPTS ;             /* # of attempts before giving up */
int sleeptime = SLEEPTIME ;             /* between attempts, in ms */

/*
 * Include lookup tables, and a function to match a code to a string.
 *
 * XXX
 * Lookup tables cannot be included, since they require symbols from
 * amrreg.h which need in turn the _KERNEL define.
 */

/* #define AMR_DEFINE_TABLES */
/* #include "/usr/src/sys/dev/amr/amr_tables.h" */

/*
 * Offsets in an amr_user_ioctl.au_cmd [] array
 * See amrio.h
 */

#define MB_COMMAND      0
#define MB_CHANNEL      1
#define MB_PARAM        2
#define MB_PAD          3
#define MB_DRIVE        4

#define FIRMWARE_40LD   1
#define FIRMWARE_8LD    2

#define NTAB(tab)       (sizeof tab / sizeof tab [0])

int amr_enquiry (int fd, size_t bufsize, void *buffer, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual)
{
struct amr_user_ioctl am ;
int r, i ;


    am.au_cmd [MB_COMMAND] = cmd ;
    am.au_cmd [MB_CHANNEL] = cmdsub ;
    am.au_cmd [MB_PARAM] = cmdqual ;
    am.au_cmd [MB_PAD] = 0 ;
    am.au_cmd [MB_DRIVE] = 0 ;

    am.au_buffer = buffer ;
    am.au_length = bufsize ;
    am.au_direction = AMR_IO_READ ;
    am.au_status = 0 ;

    i = 0 ;
    r = -1 ;
    while (i < nattempts && r == -1)
    {
        r = ioctl (fd, AMR_IO_COMMAND, &am) ;
        if (r == -1)
        {
            if (errno != EBUSY)
            {
                perror ("ioctl enquiry") ;
                exit (1) ;
            }
            else usleep (sleeptime) ;
        }
        i++ ;
    }
    return am.au_status ;
}

void usage (void)
{
fprintf (stderr, "usage: amstat [-v][-f spec][-a #attempts][-t time][-g][-l lvol]\n") ;
exit (1) ;
}


/******************************************************************************
 * Card description
 */

int describe_card (int fd, int verbosity, int globalparam)
{
    int r ;
    char buffer [2048] ;
    struct amr_enquiry *ae ;
    int cardtype ;

    /*
     * Try the 40LD firmware interface
     */

    r = amr_enquiry (fd, sizeof buffer, buffer,
                        AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0) ;
    if (r == AMR_STATUS_SUCCESS)
    {
        struct amr_prodinfo *ap ;

        if (globalparam)
        {
            ap = (struct amr_prodinfo *) buffer ;
            printf ("Product =\t<%.80s>\n",     ap->ap_product) ;
            printf ("Firmware =\t%.16s\n",      ap->ap_firmware) ;
            printf ("BIOS =\t%.16s\n",          ap->ap_bios) ;
            printf ("SCSI Channels =\t%d\n",    ap->ap_nschan) ;
            printf ("Fibre Loops =\t%d\n",      ap->ap_fcloops) ;
            printf ("Memory size =\t%d MB\n",   ap->ap_memsize) ;
            if (verbosity >= 1)
            {
                printf ("Ioctl = %d (%s)\n",    FIRMWARE_40LD, "40LD") ;
                printf ("Signature =\t0x%08x\n", ap->ap_signature) ;
                printf ("Configsig =\t0x%08x\n", ap->ap_configsig) ;
                printf ("Subsystem =\t0x%04x\n", ap->ap_subsystem) ;
                printf ("Subvendor =\t0x%04x\n", ap->ap_subvendor) ;
                printf ("Notify counters =\t%d\n", ap->ap_numnotifyctr) ;
            }
        }

        return FIRMWARE_40LD ;
    }

    /*
     * Try the 8LD firmware interface
     */

r = amr_enquiry (fd, sizeof buffer, buffer, AMR_CMD_EXT_ENQUIRY2, 0, 0) ;
ae = (struct amr_enquiry *) buffer ;
if (r == AMR_STATUS_SUCCESS)
{
cardtype = ae->ae_signature ;
}
else
{
r = amr_enquiry (fd, 2048, buffer, AMR_CMD_ENQUIRY, 0, 0) ;
cardtype = 0 ;
}


    if (r == AMR_STATUS_SUCCESS)
    {
        if (globalparam)
        {
            char *product ;
            char bios [100], firmware [100] ;
            int i ;

            static struct {
                char *product ;
                int signature ;
            } prodtable [] = {
                "Series 431",                   AMR_SIG_431,
                "Series 438",                   AMR_SIG_438,
                "Series 762",                   AMR_SIG_762,
                "Integrated HP NetRAID (T5)",   AMR_SIG_T5,
                "Series 466",                   AMR_SIG_466,
                "Series 467",                   AMR_SIG_467,
                "Integrated HP NetRAID (T7)",   AMR_SIG_T7,
                "Series 490",                   AMR_SIG_490,
            } ;

            for (i = 0 ; i < NTAB (prodtable) ; i++)
            {
                if (cardtype == prodtable [i].signature)
                {
                    product = prodtable [i].product ;
                    break ;
                }
            }
            if (product == NULL)
                product = "unknown card signature" ;

/*
* HP NetRaid controllers have a special encoding of the firmware and
* BIOS versions. The AMI version seems to have it as strings whereas
* the HP version does it with a leading uppercase character and two
* binary numbers.
*/


            if(ae->ae_adapter.aa_firmware[2] >= 'A' &&
               ae->ae_adapter.aa_firmware[2] <= 'Z' &&
               ae->ae_adapter.aa_firmware[1] <  ' ' &&
               ae->ae_adapter.aa_firmware[0] <  ' ' &&
               ae->ae_adapter.aa_bios[2] >= 'A'     &&
               ae->ae_adapter.aa_bios[2] <= 'Z'     &&
               ae->ae_adapter.aa_bios[1] <  ' '     &&
               ae->ae_adapter.aa_bios[0] <  ' ') {

/* looks like we have an HP NetRaid version of the MegaRaid */

                if(cardtype == AMR_SIG_438)
                {
                    /* the AMI 438 is a NetRaid 3si in HP-land */
                    product = "HP NetRaid 3si";
                }

                sprintf (firmware, "%c.%02d.%02d",
                              ae->ae_adapter.aa_firmware[2],
                              ae->ae_adapter.aa_firmware[1],
                              ae->ae_adapter.aa_firmware[0]) ;
                sprintf (bios, "%c.%02d.%02d",
                              ae->ae_adapter.aa_bios[2],
                              ae->ae_adapter.aa_bios[1],
                              ae->ae_adapter.aa_bios[0]) ;
            } else {
                sprintf (firmware, "%.4s", ae->ae_adapter.aa_firmware) ;
                sprintf (bios, "%.4s", ae->ae_adapter.aa_bios) ;
            }

printf ("Ioctl = %d (%s)\n", FIRMWARE_8LD, "8LD") ;
printf ("Product =\t<%s>\n", product) ;
printf ("Firmware =\t%s\n", firmware) ;
printf ("BIOS =\t%s\n", bios) ;
/* printf ("SCSI Channels =\t%d\n", ae->ae_nschan) ; */
/* printf ("Fibre Loops =\t%d\n", ae->ae_fcloops) ; */
printf ("Memory size =\t%d MB\n", ae->ae_adapter.aa_memorysize) ;
/* printf ("Notify counters =\t%d\n", ae->ae_numnotifyctr) ; */
}
return FIRMWARE_8LD ;
}


    /*
     * Neither firmware interface succeeded. Abort.
     */

    fprintf (stderr, "Firmware interface not supported\n") ;
    exit (1) ;

}

/******************************************************************************
 * Logical volumes
 */

void describe_one_volume (int ldrv, int verbosity,
                        u_int32_t size, u_int8_t state, u_int8_t prop)
{
    float szgb ;
    int i ;
    int raid_level ;
    char propstr [2000] ;
    char *statestr ;

    static struct {
        int code ;
        char *ifyes, *ifno ;
    } proptable [] = {
        AMR_DRV_WRITEBACK, "writeback", "write-through",
        AMR_DRV_READHEAD, "read-ahead", "no-read-ahead",
        AMR_DRV_ADAPTIVE, "adaptative-io", "no-adaptative-io",
    } ;

    static struct {
        int code ;
        char *status ;
    } statetable [] = {
        AMR_DRV_OFFLINE,        "offline",
        AMR_DRV_DEGRADED,       "degraded",
        AMR_DRV_OPTIMAL,        "optimal",
        AMR_DRV_ONLINE,         "online",
        AMR_DRV_FAILED,         "failed",
        AMR_DRV_REBUILD,        "rebuild",
        AMR_DRV_HOTSPARE,       "hotspare",
    } ;

    szgb = ((float) size) / (1024 * 1024 * 2) ;         /* size in GB */

    raid_level = prop & AMR_DRV_RAID_MASK ;

    strcpy (propstr, "<") ;
    for (i = 0 ; i < NTAB (proptable) ; i++)
    {
        if (i > 0) strcat (propstr, ",") ;
        if (prop & proptable [i].code)
            strcat (propstr, proptable [i].ifyes) ;
        else
            strcat (propstr, proptable [i].ifno) ;
    }
    strcat (propstr, ">") ;

    statestr = NULL ;
    for (i = 0 ; i < NTAB (statetable) && statestr == NULL ; i++)
        if (AMR_DRV_CURSTATE (state) == statetable [i].code)
            statestr = statetable [i].status ;

    printf ("Drive %d: %8.2f GB, RAID%d %s %s\n",
                        ldrv, szgb, raid_level, propstr, statestr) ;
}

void describe_logical_volume (int fd, int verbosity, int fwint, int lvolno)
{
    int r ;
    char buffer [2048] ;
    int ldrv ;

    if (fwint == FIRMWARE_40LD)
    {
        r = amr_enquiry (fd, sizeof buffer, buffer,
                            AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
                            AMR_CONFIG_ENQ3_SOLICITED_FULL) ;
        if (r == AMR_STATUS_SUCCESS)
        {
            struct amr_enquiry3 *ae3 ;

            ae3 = (struct amr_enquiry3 *) buffer ;
            for (ldrv = 0 ; ldrv < ae3->ae_numldrives ; ldrv++)
            {
                if (lvolno < 0 || lvolno == ldrv)
                    describe_one_volume (ldrv, verbosity,
                                                ae3->ae_drivesize [ldrv],
                                                ae3->ae_drivestate [ldrv],
                                                ae3->ae_driveprop [ldrv]) ;
            }
        }
    }
    else if (fwint == FIRMWARE_8LD)
    {
    }
    else
    {
        fprintf (stderr, "Firmware interface not supported\n") ;
        exit (1) ;
    }
}

/******************************************************************************
 * Main function
 */

int main (int argc, char *argv [])
{
    int fd ;
    int version ;
    int r ;
    int fwint ;
    int verbosity ;

    char *filename ;
    int lvolno ;
    int globalparam ;

    int o ;
    extern char *optarg ;
    extern int optind ;

    /*
     * Parse arguments
     */

    filename = "/dev/amr0" ;
    lvolno = -1 ;
    globalparam = 0 ;
    verbosity = 0 ;

    while ((o = getopt (argc, argv, "vga:t:f:l:")) != -1)
        switch (o)
        {
            case 'v' :
                verbosity++ ;
                break ;
            case 'g' :
                globalparam = 1 ;
                break ;
            case 'f' :
                filename = optarg ;
                break ;
            case 'a' :
                nattempts = atoi (optarg) ;
                break ;
            case 't' :
                sleeptime = atoi (optarg) ;
                break ;
            case 'l' :
                lvolno = atoi (optarg) ;
                break ;
            case '?' :
            default :
                usage () ;
        }
    argc -= optind ;
    argv += optind ;

    if (argc != 0)
        usage () ;

    /*
     * Access to the driver
     */

    fd = open (filename, O_RDONLY) ;
    if (fd == -1)
    {
        perror ("open") ;
        exit (1) ;
    }

    r = ioctl (fd, AMR_IO_VERSION, &version) ;
    if (r == -1)
    {
        perror ("ioctl version") ;
        exit (1) ;
    }
    if (globalparam && verbosity >= 1)
        printf ("Version =\t%d\n", version) ;
    if (version != 1)
    {
        fprintf (stderr, "Driver version (%d) not supported\n", version) ;
        exit (1) ;
    }

    fwint = describe_card (fd, verbosity, globalparam) ;

    describe_logical_volume (fd, verbosity, fwint, lvolno) ;


} _______________________________________________ [email protected] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to