My first attachment did not pass. amrstat.c : /* amrstat.c 2002/04/10 * * Author: Pierre David <Pierre.David_at_crc.u-strasbg.fr> */ #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) ; }Received on Sat Mar 12 2005 - 09:51:30 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:29 UTC