openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

shell.c (406834B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:     shell.c
      8  * Purpose:     Command parsing and dispatch.
      9  */
     10 
     11 
     12 #include <shared/bsl.h>
     13 
     14 #include <sal/types.h>
     15 #ifndef NO_SAL_APPL
     16 
     17 #ifndef __KERNEL__
     18 #include <stdio.h>
     19 #include <time.h>
     20 #endif
     21 
     22 #ifndef NO_CTRL_C
     23 #include <setjmp.h>
     24 #include <signal.h>
     25 #endif
     26 
     27 #endif /* NO_SAL_APPL */
     28 
     29 #include <assert.h>
     30 
     31 #include <sal/core/libc.h>
     32 #include <sal/core/boot.h>
     33 #include <sal/appl/sal.h>
     34 #include <sal/appl/io.h>
     35 #include <sal/appl/config.h>
     36 
     37 #include <soc/debug.h>
     38 #include <soc/defs.h>
     39 #include <soc/drv.h>
     40 #include <soc/scache.h>
     41 #if defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)
     42 #include <soc/mcm/driver.h>
     43 #endif
     44 #if defined(BCM_TRIUMPH_SUPPORT)
     45 #include <soc/er_tcam.h>
     46 #endif
     47 #if defined (BCM_KATANA2_SUPPORT)
     48 #include <soc/katana2.h>
     49 #endif
     50 
     51 #include <bcm/init.h>
     52 #include <bcm/error.h>
     53 #include <bcm/port.h>
     54 #include <bcm/debug.h>
     55 #include <bcm/vlan.h>
     56 #include <bcm/types.h>
     57 #include <bcm/stg.h>
     58 #include <bcm/link.h>
     59 #include <bcm/switch.h>
     60 #include <bcm/rx.h>
     61 #include <bcm_int/control.h>
     62 #ifdef INCLUDE_MACSEC
     63 #include <bcm/macsec.h>
     64 #include <bcm_int/common/macsec_cmn.h>
     65 #endif /* INCLUDE_MACSEC */
     66 
     67 #include <soc/feature.h>
     68 
     69 #include <appl/diag/shell.h>
     70 #include <appl/diag/system.h>
     71 #include <appl/diag/sysconf.h>
     72 #include <shared/bslnames.h>
     73 #include <appl/diag/bslenable.h>
     74 #include <appl/diag/bslsink.h>
     75 #include <appl/diag/bslcons.h>
     76 #include <appl/diag/bslfile.h>
     77 #include <appl/diag/bsltrace.h>
     78 #include <appl/diag/bsltest.h>
     79 #ifdef BCM_WARM_BOOT_SUPPORT
     80 #include <appl/diag/warmboot.h>
     81 #endif /* BCM_WARM_BOOT_SUPPORT */
     82 
     83 #if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) && defined(BCM_WARM_BOOT_SUPPORT)
     84 #include <soc/dcmn/dcmn_wb.h>
     85 #include <shared/swstate/sw_state.h>
     86 #endif /* (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)) && defined(BCM_WARM_BOOT_SUPPORT)) */
     87 
     88 #if defined(INCLUDE_BCMX)
     89 #include <bcmx/debug.h>
     90 #endif
     91 
     92 #if defined(INCLUDE_APIMODE)
     93 #include <appl/diag/api_mode.h>
     94 #endif
     95 
     96 #if defined(BCM_DFE_SUPPORT)
     97 #include <soc/dfe/cmn/dfe_drv.h>
     98 #include <soc/dfe/fe1600/fe1600_interrupts.h>
     99 #endif
    100 #if defined(BCM_PETRA_SUPPORT)
    101 #include <soc/dpp/drv.h>
    102 #include <soc/dpp/ARAD/arad_interrupts.h>
    103 #endif
    104 #if defined(BCM_JERICHO_SUPPORT) && defined(INCLUDE_KBP) && !defined(BCM_88030)
    105 #include <appl/diag/dpp/kbp.h>
    106 #endif
    107 
    108 #if defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)
    109 #if defined(INCLUDE_INTR)
    110 #include <appl/dcmn/interrupts/interrupt_handler.h>
    111 #include <appl/dcmn/interrupts/dcmn_intr.h>
    112 #include <appl/dcmn/rx_los/rx_los.h>
    113 #endif /* INCLUDE_INTR */
    114 #endif /* defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT) */
    115 #if defined(BCM_PETRA_SUPPORT)
    116 #include <appl/diag/dcmn/init.h>
    117 #include <appl/diag/dcmn/init_deinit.h>
    118 #ifdef BCM_JERICHO_SUPPORT
    119 #include <soc/dpp/JER/jer_mgmt.h>
    120 #endif
    121 #ifdef BCM_FLAIR_SUPPORT
    122 #include <appl/dpp/fabric_fgl/fgl_configuration.h>
    123 #endif
    124 #endif
    125 
    126 #if (defined(LINUX) || defined(UNIX))
    127 #if defined(BCM_SAND_SUPPORT)
    128 #ifndef NO_FILEIO
    129 #include <unistd.h>
    130 #endif
    131 #endif
    132 #endif
    133 
    134 
    135 #include <soc/phy/phyctrl.h>
    136 #include <soc/cm.h>
    137 
    138 #include <appl/diag/infix.h>
    139 #include <appl/diag/diag.h>
    140 
    141 #include <shared/shr_resmgr.h>
    142 #include <sal/core/time.h>
    143 #include <shared/shr_bprof.h>
    144 
    145 #if defined(BCM_WARM_BOOT_API_TEST) 
    146 #include <shared/swstate/sw_state_dump.h>
    147 #include <shared/swstate/diagnostic/sw_state_diagnostic.h>
    148 #endif
    149 
    150 #define MIN(a,b) ((a) < (b) ? (a) : (b))
    151 
    152 int     sh_rcload_depth = 0;
    153 
    154 /*
    155  * Variables manipulated by the shell 'set' command
    156  *
    157  * NOTE ON ADDING VARIABLES:
    158  *    (1) Add sh_set_xxx variable (below)
    159  *    (2) Add extern for sh_set_xxx (in shell.h)
    160  *    (3) Add parse_table_add() call in sh_set()
    161  */
    162 
    163 int    sh_set_rcload       = TRUE;    /* TRUE --> alias to rcload */
    164 int    sh_set_rcerror      = TRUE;    /* TRUE --> Stop rcload on error */
    165 int    sh_set_lperror      = TRUE;    /* TRUE --> Stop loop on error */
    166 int    sh_set_iferror      = TRUE;    /* TRUE --> Stop if on error */
    167 int    sh_set_more_lines   = 20;     /* # lines for MORE */
    168 int    sh_set_report_time  = 5;     /* Test status report interval (sec) */
    169 int    sh_set_report_status = TRUE;     /* Allows disabling reporting */
    170 #ifdef __KERNEL__
    171 int    sh_set_rctest       = FALSE;    /* FALSE--> No Auto RC */
    172 #else
    173 int    sh_set_rctest       = TRUE;    /* TRUE --> tr tests load */
    174 #endif
    175 
    176 
    177 static volatile int override_unit = FALSE;
    178 
    179 /*
    180  * Set environment variables pertinent to a new current unit, such as
    181  * chip name.  Removes those pertaining to an old unit.
    182  */
    183 
    184 void
    185 sh_swap_unit_vars(int new_unit)
    186 {
    187     static int old_unit = -1;
    188     char tmp[16];
    189 #ifdef INCLUDE_EDITLINE
    190     extern int diag_list_possib_unit;
    191 #endif
    192     extern int diag_user_var_unit;
    193 
    194     char uc_image_name_prefix[64];
    195 
    196     if (new_unit != old_unit) {
    197     if (old_unit >= 0) {
    198         sal_sprintf(tmp, "unit%d", old_unit);
    199         if (NULL != SOC_CONTROL(old_unit)) {
    200             var_unset(SOC_CHIP_STRING(old_unit), FALSE, TRUE, FALSE);
    201             var_unset(soc_dev_name(old_unit), FALSE, TRUE, FALSE);
    202             if (SOC_IS_DNX(old_unit)) {
    203                 var_unset("BCM_DNX_DEV", FALSE, TRUE, FALSE);
    204                 if (SOC_IS_JERICHO_2_ONLY(old_unit)) {
    205                     var_unset("BCM_JR2_DEV", FALSE, TRUE, FALSE);
    206                 }
    207                 if (SOC_IS_J2C(old_unit)) {
    208                     var_unset("BCM_J2C_DEV", FALSE, TRUE, FALSE);
    209                 }
    210             }
    211 #if defined(BCM_DNXF_SUPPORT)
    212             if (SOC_IS_DNXF(old_unit)) {
    213                 var_unset("BCM_DNXF_DEV", FALSE, TRUE, FALSE);
    214                 if (SOC_IS_RAMON(old_unit)) {
    215                     var_unset("BCM_8879X_DEV", FALSE, TRUE, FALSE);
    216                 }
    217             }
    218 #endif
    219         }
    220         var_unset(tmp, FALSE, TRUE, FALSE);
    221         var_unset("devname", FALSE, TRUE, FALSE);
    222         var_unset("fw_prefix", FALSE, TRUE, FALSE);
    223         var_unset("pcidev", FALSE, TRUE, FALSE);
    224         var_unset("pcirev", FALSE, TRUE, FALSE);
    225         var_unset("rcpu_only", FALSE, TRUE, FALSE);
    226         var_unset("ihost_mode", FALSE, TRUE, FALSE);
    227         var_unset("num_ucs", FALSE, TRUE, FALSE);
    228     }
    229 
    230     if (new_unit >= 0) {
    231 	    uint16 dev_id;
    232 	    uint8 rev_id;
    233         char *chip_string;
    234         uint16 dev_id_driver;
    235         uint8 rev_id_driver;
    236         const char *driver_name = "UNKNOWN";
    237 
    238         chip_string = SOC_CHIP_STRING(new_unit);
    239         if (soc_cm_get_id(new_unit, &dev_id, &rev_id) >= 0) {
    240             sal_sprintf(tmp, "0x%04x", dev_id);
    241             var_set("pcidev", tmp, FALSE, FALSE);
    242             sal_sprintf(tmp, "0x%02x", rev_id);
    243             var_set("pcirev", tmp, FALSE, FALSE);
    244             if (dev_id == BCM56620_DEVICE_ID) {
    245                 chip_string = "triumph"; /* SOC_CHIP_STRING is valkyrie */
    246             }
    247             if (dev_id == BCM56630_DEVICE_ID) {
    248                 chip_string = "triumph2"; /* SOC_CHIP_STRING is apollo */
    249             }
    250             if (dev_id == BCM56526_DEVICE_ID) {
    251                 chip_string = "apollo"; /* SOC_CHIP_STRING is triumph2 */
    252             }
    253             if (dev_id == BCM56538_DEVICE_ID) {
    254                 chip_string = "firebolt3"; /* SOC_CHIP_STRING is triumph2 */
    255             }
    256             if (dev_id == BCM56534_DEVICE_ID) {
    257                 chip_string = "firebolt3"; /* SOC_CHIP_STRING is apollo */
    258             }
    259         }
    260 
    261         if (SOC_SUCCESS
    262             (soc_cm_get_id_driver(dev_id, rev_id,
    263                                   &dev_id_driver, &rev_id_driver))) {
    264             driver_name = soc_cm_get_device_name(dev_id_driver, rev_id_driver);
    265         }
    266 
    267         var_set_integer(chip_string, 1, FALSE, FALSE);
    268         var_set_integer(soc_dev_name(new_unit), 1, FALSE, FALSE);
    269         sal_sprintf(tmp, "unit%d", new_unit);
    270         var_set_integer(tmp, 1, FALSE, FALSE);
    271         var_set("devname", (char *)soc_dev_name(new_unit), FALSE, FALSE);
    272         var_set("fw_prefix", (char *)driver_name, FALSE, FALSE);
    273 
    274         /* fw_prefix will be same as the driver_name in general */
    275         if (soc_feature(new_unit, soc_feature_uc_image_name_with_no_chip_rev)) {
    276             sal_memset(uc_image_name_prefix, 0x0, sizeof(uc_image_name_prefix));
    277             if (SOC_IS_METROLITE(new_unit)) {
    278                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56270_A0");
    279             } else if (SOC_IS_SABER2(new_unit)) {
    280                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56260_A0");
    281             } else if (SOC_IS_MONTEREY(new_unit)) {
    282                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56670_A0");
    283             } else if (SOC_IS_APACHE(new_unit)) {
    284                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56560_A0");
    285             } else if (SOC_IS_TOMAHAWK(new_unit)) {
    286                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56960_A0");
    287             } else if (SOC_IS_TOMAHAWK2(new_unit)) {
    288                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56970_A0");
    289             } else if (SOC_IS_TRIDENT3(new_unit)) {
    290                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56870_A0");
    291             } else if (SOC_IS_HELIX4(new_unit)) {
    292                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56340_A0");
    293             } else if (SOC_IS_GREYHOUND(new_unit)) {
    294                 sal_strcpy(uc_image_name_prefix, (char *)"BCM53400_A0");
    295             } else if (SOC_IS_TRIDENT2PLUS(new_unit)) {
    296                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56860_A0");
    297             } else if (SOC_IS_MAVERICK2(new_unit)) {
    298                 sal_strcpy(uc_image_name_prefix, (char *)"BCM56770_A0");
    299             } else {
    300                 sal_strncpy(uc_image_name_prefix, (char *)soc_dev_name(new_unit),
    301                     MIN( sizeof(uc_image_name_prefix), strlen((char *)soc_dev_name(new_unit))));
    302             }
    303 
    304             /* last 3 characters are chip revisions _A0, _B0, _B1 etc. needs to be
    305              * removed
    306              */
    307             uc_image_name_prefix[sal_strlen(uc_image_name_prefix) - 3]= '\0';
    308             var_set("fw_prefix", (char *)uc_image_name_prefix, FALSE, FALSE);
    309         }
    310 
    311         if (SOC_IS_RCPU_ONLY(new_unit)) {
    312             var_set_integer("rcpu_only", 1, FALSE, FALSE);
    313         }
    314         if (soc_feature(new_unit, soc_feature_iproc)) {
    315             if (soc_cm_get_bus_type(new_unit) & SOC_AXI_DEV_TYPE) {
    316                 var_set_integer("ihost_mode", 1, FALSE, FALSE);
    317             }
    318         }
    319         if (soc_feature(new_unit, soc_feature_uc)) {
    320             var_set_integer(
    321                 "num_ucs", SOC_INFO(new_unit).num_ucs, FALSE, FALSE);
    322         }
    323     }
    324 
    325     if (new_unit >= 0) {
    326         var_set_integer("unit", new_unit, 0, 0);
    327 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) 
    328         if (SOC_IS_DPP(new_unit) || SOC_IS_DFE(new_unit)) {
    329             command_mode_set(new_unit, DPP_CMD_MODE);
    330         } else
    331 #endif
    332 #if defined(BCM_DNX_SUPPORT)
    333         if (SOC_IS_DNX(new_unit)) {
    334             var_set_integer("BCM_DNX_DEV", 1, FALSE, FALSE);
    335             if (SOC_IS_JERICHO_2_ONLY(new_unit)) {
    336                 var_set_integer("BCM_JR2_DEV", 1, FALSE, FALSE);
    337             }
    338             if (SOC_IS_J2C(new_unit)) {
    339                 var_set_integer("BCM_J2C_DEV", 1, FALSE, FALSE);
    340             }
    341             command_mode_set(new_unit, DNX_CMD_MODE);
    342         } else
    343 #endif
    344 #if defined(BCM_DNXF_SUPPORT)
    345         if (SOC_IS_DNXF(new_unit)) {
    346             var_set_integer("BCM_DNXF_DEV", 1, FALSE, FALSE);
    347             if (SOC_IS_RAMON(new_unit)) {
    348                 var_set_integer("BCM_8879X_DEV", 1, FALSE, FALSE);
    349             }
    350             command_mode_set(new_unit, DNXF_CMD_MODE);
    351         } else
    352 #endif
    353         {
    354             command_mode_set(new_unit, ESW_CMD_MODE);
    355         }
    356     } else {
    357         var_unset("unit", FALSE, TRUE, FALSE);
    358     }
    359 
    360     old_unit = new_unit;
    361     }
    362 
    363 #ifdef INCLUDE_EDITLINE
    364     diag_list_possib_unit = new_unit;
    365 #endif
    366     diag_user_var_unit = new_unit;
    367 }
    368 
    369 /*
    370  * Variable:    sh_ctrl_c_cnt
    371  * Purpose: Index indicating current top of stack for pushed
    372  *  Control-C handlers. "-1" Indicates no handlers pushed.
    373  */
    374 #ifndef NO_CTRL_C
    375 static volatile int sh_ctrl_c_cnt = -1;
    376 #endif
    377 
    378 /*
    379  * Variable:    sh_ctrl_c_stack
    380  * Purpose: Tracks pushed control-C handlers. Both the jmpbuf and the
    381  *  the setting thread is tracked.
    382  */
    383 #ifndef NO_CTRL_C
    384 static volatile struct {
    385     jmp_buf *pc_jmpbuf; /* Pointer to jmpbuf for longjmp */
    386     sal_thread_t    pc_thread;  /* Thread that pushed the entry */
    387 } sh_ctrl_c_stack[PUSH_CTRL_C_CNT] = {{0}, {0}};
    388 #endif
    389 
    390 /* ARGSUSED */
    391 void
    392 sh_ctrl_c_handler(int sig)
    393 /*
    394  * Function:    sh_ctrl_c_handler
    395  * Purpose: Actual handler called when Control-C occurs.
    396  * Parameters:  sig - not used.
    397  * Returns: Nothing.
    398  */
    399 {
    400 #ifndef NO_CTRL_C
    401     COMPILER_REFERENCE(sig);
    402     /* coverity[assert_side_effect] */
    403     assert(sh_ctrl_c_cnt >= 0);
    404 
    405     if (sal_thread_self() != sh_ctrl_c_stack[sh_ctrl_c_cnt].pc_thread) {
    406         cli_out("ERROR: thread 0x%lx took my Control-C!!\n",(unsigned long) sal_thread_self());
    407         return;
    408     }
    409     signal(SIGINT, sh_ctrl_c_handler); /* Enable now */
    410 
    411     cli_out("\nInterrupt:SIGINT \n");
    412 
    413     longjmp(*sh_ctrl_c_stack[sh_ctrl_c_cnt].pc_jmpbuf, 1);
    414 #endif
    415 }
    416 
    417 void
    418 sh_ctrl_c_take(void)
    419 /*
    420  * Function:    sh_ctrl_c_take
    421  * Purpose: Fake a control-C exception (useful for assert).
    422  * Parameters:  none.
    423  * Returns: Does not return.
    424  */
    425 {
    426 #ifndef NO_CTRL_C
    427     cli_out("\n");
    428     if (sh_ctrl_c_cnt >= 0) {
    429         longjmp(*sh_ctrl_c_stack[sh_ctrl_c_cnt].pc_jmpbuf, 1);
    430     }
    431     exit(1);
    432 #endif
    433 }
    434 
    435 void
    436 sh_push_ctrl_c(jmp_buf *jb)
    437 /*
    438  * Function:     sh_push_ctrl_c
    439  * Purpose:    Push a control C long jump buffer onto the handler stack.
    440  * Parameters:    jb - pointer to long jump buffer (jmp_buf).
    441  * Returns:    Nothing
    442  */
    443 {
    444 #ifndef NO_CTRL_C
    445     if (sal_thread_self() == sal_thread_main_get()) {
    446         signal(SIGINT, SIG_IGN);
    447         /* coverity[assert_side_effect] */
    448         assert(sh_ctrl_c_cnt < (PUSH_CTRL_C_CNT - 1));
    449         sh_ctrl_c_cnt++;
    450 
    451         sh_ctrl_c_stack[sh_ctrl_c_cnt].pc_jmpbuf = jb;
    452         sh_ctrl_c_stack[sh_ctrl_c_cnt].pc_thread = sal_thread_self();
    453 
    454         signal(SIGINT, sh_ctrl_c_handler); /* Enable now */
    455     }
    456 #endif
    457 }
    458 
    459 void
    460 sh_pop_ctrl_c(void)
    461 /*
    462  * Function:     sh_pop_ctrl_c
    463  * Purpose:    Pop an control-c entry off the handler stack.
    464  * Parameters:    None.
    465  * Returns:    Nothing.
    466  */
    467 {
    468 #ifndef NO_CTRL_C
    469     if (sal_thread_self() == sal_thread_main_get()) {
    470         signal(SIGINT, SIG_IGN);
    471 
    472         /*XXXTTT Put in after testXXX assert(sh_ctrl_c_cnt >= 0);*/
    473         sh_ctrl_c_cnt--;
    474 
    475         if (sh_ctrl_c_cnt < 0) {
    476             signal(SIGINT, SIG_DFL);
    477         } else {
    478             signal(SIGINT, sh_ctrl_c_handler); /* Enable now */
    479         }
    480     }
    481 #endif
    482 }
    483 
    484 void
    485 sh_block_ctrl_c(int tf)
    486 {
    487 #ifndef NO_CTRL_C
    488     signal(SIGINT, tf ? SIG_IGN : sh_ctrl_c_handler);
    489 #endif
    490 }
    491 
    492 int
    493 sh_check_attached(const char *pfx, const int u)
    494 /*
    495  * Function:    sh_check_attached
    496  * Purpose: Check if a unit is attached, and print error if not.
    497  * Parameters:  pfx - Prefix to error message.
    498  *  u - unit #.
    499  * Returns: FALSE - not attached, TRUE - attached.
    500  */
    501 {
    502     if (0 > u) {    /* No unit set */
    503         cli_out("%s: Error: No default unit\n", pfx);
    504         return(FALSE);
    505     } else if (!soc_attached(u)) {
    506         /* Not attached, print out error */
    507         if (override_unit)
    508             return TRUE;
    509         cli_out("%s: Error: Unit %d not attached\n", pfx, u);
    510         return(FALSE);
    511     }
    512     return(TRUE);
    513 }
    514 
    515 #ifndef NO_FILEIO
    516 typedef struct rccache_s {
    517     char    *name;
    518     char    *value;
    519     struct rccache_s    *next;
    520 } rccache_t;
    521 
    522 static rccache_t    *rccache_head;
    523 
    524 static char *
    525 rccache_lookup(char *fname)
    526 {
    527     rccache_t   *r;
    528 
    529     for (r = rccache_head; r != NULL; r = r->next) {
    530         if (sal_strcmp(fname, r->name) == 0) {
    531             return r->value;
    532         }
    533     }
    534     return NULL;
    535 }
    536 #endif  /* NO_FILEIO */
    537 
    538 
    539 #ifndef NO_SAL_APPL
    540 
    541 char sh_rccache_usage[] =
    542     "Usage:\n"
    543     "\trccache show [name]   - show cached rc files or contents of name\n"
    544     "\trccache add name      - add rc file 'name' to cached files\n"
    545     "\trccache addq name     - like add but only if not already cached\n"
    546     "\trccache update name   - reload rc file 'name' into the cache\n"
    547     "\trccache delete name   - delete cached rc file 'name'\n"
    548     "\trccache clear         - delete all cached rc files\n";
    549 
    550 cmd_result_t
    551 sh_rccache(int u, args_t *a)
    552 {
    553 #ifdef    NO_FILEIO
    554     cli_out("%s: not supported without file I/O\n", ARG_CMD(a));
    555     return CMD_FAIL;
    556 #else
    557     char    *subcmd;
    558     rccache_t    *r, *prevr;
    559     char    *name, *s, *s2;
    560     FILE    *fp;
    561     char    buf[1024];
    562     int     fb, sb, upd;
    563 
    564     subcmd = ARG_GET(a);
    565     if (subcmd == NULL) {
    566         subcmd = "show";
    567     }
    568     if (sal_strcasecmp(subcmd, "show") == 0) {
    569         name = ARG_GET(a);
    570         if (name == NULL) {
    571             for (r = rccache_head; r != NULL; r = r->next) {
    572             cli_out("cached %s (%d bytes)\n", r->name,
    573                     (int)sal_strlen(r->value));
    574             }
    575             return CMD_OK;
    576         }
    577         s = rccache_lookup(name);
    578         if (s == NULL) {
    579             cli_out("%s: ERROR: %s is not cached\n", ARG_CMD(a), name);
    580             return CMD_FAIL;
    581         }
    582         cli_out("%s: cached %s (%d bytes)\n%s\n",
    583                 ARG_CMD(a), name, (int)sal_strlen(s), s);
    584         return CMD_OK;
    585     }
    586     upd = 0;
    587     if (sal_strcasecmp(subcmd, "update") == 0 ||
    588         sal_strcasecmp(subcmd, "upd") == 0) {
    589         upd = 1;
    590         subcmd = "add";
    591     }
    592     if (sal_strcasecmp(subcmd, "add") == 0 ||
    593         sal_strcasecmp(subcmd, "addq") == 0) {
    594         char *path;
    595         char *fn = NULL;
    596         int  fn_size = ARGS_BUFFER + 8;
    597 
    598         name = ARG_GET(a);
    599         if (name == NULL) {
    600             cli_out("%s: ERROR: missing file name\n", ARG_CMD(a));
    601             return CMD_USAGE;
    602         }
    603 
    604         for (r = rccache_head; r != NULL; r = r->next) {
    605             if (sal_strcmp(r->name, name) == 0) {
    606                 break;
    607             }
    608         }
    609 
    610         if (upd == 0 && r != NULL) {
    611             if (sal_strcasecmp(subcmd, "addq") == 0) {
    612                 return CMD_OK;
    613             }
    614             cli_out("%s: ERROR: %s already cached\n", ARG_CMD(a), name);
    615             return CMD_FAIL;
    616         }
    617 
    618         if (r == NULL) {
    619             r = sal_alloc(sizeof(*r), "rccache");
    620             if (r == NULL) {
    621                 cli_out("%s: ERROR: out of memory\n", ARG_CMD(a));
    622                 return CMD_FAIL;
    623             }
    624             r->name = NULL;
    625             r->value = NULL;
    626             r->next = NULL;
    627         }
    628 
    629         if ((path = var_get("path")) == NULL) {
    630             path = ".";
    631         }
    632 
    633         fn = sal_alloc(sizeof(char) * fn_size, "file name buffer");
    634         if (NULL == fn) {
    635             if (r->name == NULL) {
    636                 sal_free(r);
    637             }
    638             return CMD_FAIL;
    639         }
    640         sal_memset(fn, 0, sizeof(char) * fn_size);
    641 
    642         fp = NULL;
    643         if (*name == '/') {
    644             sal_strncpy(fn, name, fn_size - 1);
    645             if ((fp = sal_fopen(fn, "r")) == NULL) {
    646                 if (fn != NULL) {
    647                     sal_free(fn);
    648                 }
    649                 if (r->name == NULL) {
    650                     sal_free(r);
    651                 }
    652                 return CMD_FAIL;
    653             }
    654         } else {
    655             while (*path != 0) {
    656                 int character_count = 0;
    657                 char *p;
    658 
    659                 p = fn;
    660 
    661                 while (*path != ' ' && *path != 0) {
    662                     *p++ = *path++;
    663                     ++character_count;
    664                 }
    665 
    666                 if (p > fn) {
    667                     *p++ = '/';
    668                     ++character_count;
    669                 }
    670 
    671                 sal_strncpy(p, name, fn_size - character_count - 1);
    672                 p[fn_size - character_count - 1] = 0;
    673 
    674                 if ((fp = sal_fopen(fn, "r")) != NULL) {
    675                     break;
    676                 }
    677 
    678                 while (*path == ' ') {
    679                     path++;
    680                 }
    681             }
    682         }
    683         if (fn != NULL) {
    684             sal_free(fn);
    685         }
    686 
    687         if (fp == NULL) {
    688             cli_out("%s: ERROR: %s: file not found\n", ARG_CMD(a), name);
    689             if (r->name == NULL) {
    690                 sal_free(r);
    691             }
    692             return CMD_FAIL;
    693         }
    694         s = NULL;
    695         sb = 0;
    696         while ((fb = sal_fread(buf, 1, sizeof(buf), fp)) > 0) {
    697             s2 = sal_alloc(sb + fb + 1, "rccache-read");
    698             if (s2 == NULL) {
    699                 cli_out("%s: ERROR: out of memory\n", ARG_CMD(a));
    700                 sal_free(r);
    701                 if (s != NULL) {
    702                     /* coverity[tainted_data] */
    703                     sal_free(s);
    704                 }
    705                 sal_fclose(fp);
    706                 return CMD_FAIL;
    707             }
    708             if (sb) {
    709                 sal_memcpy(s2, s, sb);
    710             }
    711             sal_memcpy(&s2[sb], buf, fb);
    712             s2[sb+fb] = '\0';
    713             if (s != NULL) {
    714                 sal_free(s);
    715             }
    716             s = s2;
    717             sb += fb;
    718         }
    719         sal_fclose(fp);
    720         if (sb == 0) {
    721             cli_out("%s: ERROR: %s: file is empty\n", ARG_CMD(a), name);
    722             if (r->name == NULL) {
    723                 sal_free(r);
    724             }
    725             if (s != NULL) {
    726                 sal_free(s);
    727             }
    728             return CMD_FAIL;
    729         }
    730         if (r->name == NULL) {        /* new entry */
    731             r->name = sal_strdup(name);
    732             r->value = sal_strdup(s);
    733             r->next = rccache_head;
    734             rccache_head = r;
    735         } else {            /* update */
    736             sal_free(r->value);
    737             r->value = sal_strdup(s);
    738         }
    739         /* coverity[tainted_data] */
    740         sal_free(s);
    741         return CMD_OK;
    742     }
    743     if (sal_strcasecmp(subcmd, "delete") == 0 ||
    744         sal_strcasecmp(subcmd, "del") == 0) {
    745         name = ARG_GET(a);
    746         if (name == NULL) {
    747             cli_out("%s: ERROR: missing cached name\n", ARG_CMD(a));
    748             return CMD_USAGE;
    749         }
    750         prevr = NULL;
    751         for (r = rccache_head; r != NULL; prevr = r, r = r->next) {
    752             if (sal_strcmp(r->name, name) != 0) {
    753                 continue;
    754             }
    755             if (prevr == NULL) {
    756                 rccache_head = r->next;
    757             } else {
    758                 prevr->next = r->next;
    759             }
    760             sal_free(r->name);
    761             sal_free(r->value);
    762             sal_free(r);
    763             return CMD_OK;
    764         }
    765         cli_out("%s: ERROR: %s is not cached\n", ARG_CMD(a), name);
    766         return CMD_FAIL;
    767     }
    768     if (sal_strcasecmp(subcmd, "clear") == 0) {
    769         name = ARG_GET(a);
    770         if (name != NULL) {
    771             cli_out("%s: ERROR: clear takes no arguments\n", ARG_CMD(a));
    772             return CMD_USAGE;
    773         }
    774         while (rccache_head != NULL) {
    775             r = rccache_head;
    776             rccache_head = r->next;
    777             sal_free(r->name);
    778             sal_free(r->value);
    779             sal_free(r);
    780         }
    781         return CMD_OK;
    782     }
    783     return CMD_USAGE;
    784 #endif    /* NO_FILEIO */
    785 }
    786 
    787 cmd_result_t
    788 sh_rcload_file(int u, args_t *a, char *f, int add_rc)
    789 /*
    790  * Function:     sh_rcload_file
    791  * Purpose:    Load and execute commands from a file.
    792  * Parameters:    u - default unit number for commands, may be -1 if none
    793  *        a - Pointer to args, IF non-null, remaining args
    794  *            in a are pushed in a local scope as $1, $2 etc.
    795  *        f - file name to load
    796  *        add_rc - if true, filename must end in ".soc", appended
    797  *            if not there.
    798  * Returns:    CMD_OK - all commands executed.
    799  *        CMD_FAIL- some command failed and aborted file processing.
    800  */
    801 {
    802 #ifdef NO_FILEIO
    803     if(sal_strstr(f, ".soc")) {
    804         cli_out("proxyecho rcload %s\n", f);
    805     }
    806     return 0;
    807 #else
    808 
    809     /*char fn[ARGS_BUFFER + 8];*/
    810     char *fn = NULL;
    811     char *path, *p, *add_ext;
    812     static char line[ARGS_BUFFER], *s, *t;
    813     void * volatile scope = NULL;
    814 #ifndef NO_CTRL_C
    815     jmp_buf ctrl_c;
    816 #endif
    817 
    818     /* These guys volatile because of long jump */
    819 
    820     volatile cmd_result_t rv = CMD_OK;
    821     FILE * volatile       fp = NULL;
    822     char * volatile      fstr = NULL;
    823     volatile int        lineNum = 0;
    824 
    825     scope = var_push_scope(); /* Push current scope */
    826 
    827 #ifndef NO_CTRL_C
    828     if (!setjmp(ctrl_c)) {
    829         sh_push_ctrl_c(&ctrl_c);
    830         rv = CMD_OK;
    831     } else {
    832         rv = CMD_INTR;
    833         goto done;
    834     }
    835 #else
    836     rv = CMD_OK;
    837 #endif
    838     if (++sh_rcload_depth == RCLOAD_DEPTH_MAX) {
    839         cli_out("rcload: recursion too deep\n");
    840         goto done;
    841     }
    842 
    843     (void)var_set_integer("?", CMD_OK, TRUE, FALSE);
    844 
    845     /* If arguments - add to local scope */
    846 
    847     if (a) {
    848         int    v_num;
    849         char    v_str[12];
    850         char    *v_val;
    851         
    852         for (v_num = 1,v_val = ARG_GET(a); v_val; v_val=ARG_GET(a),v_num++){
    853             sal_sprintf(v_str, "%d", v_num);
    854             var_set(v_str, v_val, TRUE, FALSE);
    855         }
    856     }
    857 
    858     /*
    859      * Determine suffix (extension SOC_SCRIPT_EXT = .soc) to add to file name
    860      */
    861 
    862     add_ext = "";
    863 
    864     if (add_rc &&
    865         (sal_strlen(f) <= sal_strlen(SOC_SCRIPT_EXT) ||
    866          sal_strcmp(f + sal_strlen(f) - sal_strlen(SOC_SCRIPT_EXT),
    867              SOC_SCRIPT_EXT))) {
    868 
    869         add_ext = SOC_SCRIPT_EXT;
    870     }
    871 
    872     /*
    873      * If name of script has a colon or slash, open it as-is.
    874      * Otherwise search for script in $path.
    875      */
    876     /* coverity[secure_coding] */
    877     fn = sal_alloc(sizeof(char) * (ARGS_BUFFER + 8), "file name buffer");
    878     if (NULL == fn) {
    879         rv = CMD_FAIL;
    880         goto done;
    881     }
    882 
    883     sal_strcpy(fn, f);
    884     /* coverity[secure_coding] */
    885     sal_strcat(fn, add_ext);
    886 
    887 
    888     if (sal_strchr(fn, '/') != NULL || sal_strchr(fn, ':') != NULL) {
    889         fp = sal_fopen(fn, "r");
    890     } else if ((fstr = rccache_lookup(fn)) == NULL) {
    891         if ((path = var_get("path")) == NULL) {
    892             path = ".";
    893         }
    894 
    895         while (*path != 0) {
    896             p = fn;
    897             
    898             while (*path != ' ' && *path != 0) {
    899                 *p++ = *path++;
    900             }
    901             
    902             if (p > fn) {
    903                 *p++ = '/';
    904             }
    905             
    906             /* coverity[secure_coding] */
    907             sal_strcpy(p, f);
    908             /* coverity[secure_coding] */        
    909             sal_strcat(fn, add_ext);
    910             
    911             if ((fp = sal_fopen(fn, "r")) != NULL) {
    912                 break;
    913             }
    914             
    915             while (*path == ' ') {
    916                 path++;
    917             }
    918         }
    919     }
    920     
    921     if (fp == NULL && fstr == NULL) {
    922         rv = CMD_NFND;
    923         goto done;
    924     }
    925 
    926     for (;;) {
    927         s = line;
    928         for (;;) {
    929             lineNum++;
    930             if (fp != NULL) {
    931                 if (sal_fgets(s, line + sizeof (line) - s, fp) == 0) {
    932                     goto done;
    933                 }
    934             } else {
    935                 int left = line + sizeof(line) - s;
    936                 char c;
    937                 char *s2 = s;
    938 
    939                 if (fstr == NULL || *fstr == '\0') {
    940                     goto done;
    941                 }
    942                 while (left--) {
    943                     c = *fstr++;
    944                     *s2++ = c;
    945                     if (c == '\n' || c == '\0') {
    946                         if (left) {
    947                             *s2 = '\0';
    948                         }
    949                         break;
    950                     }
    951                 }
    952             }
    953             line[sizeof (line) - 1] = 0;    /* Make sure NUL-terminated */
    954             if ((t = sal_strchr(s, '\r')) != 0)
    955                 strrepl(s, t - s, 1, "");    /* I hate hate hate PCs */
    956             if ((t = sal_strchr(s, '#')) != 0) {     /* Strip out comments */
    957                 *t = 0;
    958             } else if ((t = sal_strchr(s, '\n')) != 0) {
    959                 *t = 0;            /* Remove newline */
    960             }
    961             t = s;            /* Handle backslash continuation */
    962             s += sal_strlen(s);
    963             if (s > t && s[-1] == '\\') {
    964                 s--;
    965                 continue;
    966             }
    967             break;
    968         }
    969 
    970         switch ((rv = sh_process_command(u, line))) {
    971         case CMD_OK:
    972             break;
    973         case CMD_EXIT:
    974         case CMD_INTR:
    975             goto done_exit;
    976         default:
    977             if ((sal_strncasecmp("expr", line, 4) != 0)) {
    978                 cli_out("Error: file %s: line %d (error code %d): script %s\n",
    979                         fn, lineNum, rv,
    980                         sh_set_rcerror ? "terminated" : "continuing");
    981                 rv = CMD_FAIL;        /* Don't return nfnd here */
    982                 if (sh_set_rcerror) {
    983                     goto done;
    984                 }
    985             }
    986         }
    987         (void)var_set_integer("?", rv, TRUE, FALSE);
    988     }
    989 
    990   done:
    991 
    992     if (lineNum == 1) {
    993         cli_out("Error: file %s: empty script\n", fn);
    994         rv = CMD_FAIL;
    995     }
    996 
    997   done_exit:
    998     if (fn != NULL) {
    999         sal_free(fn);
   1000     }
   1001 
   1002     sh_rcload_depth--;
   1003     if (scope) {
   1004         var_pop_scope((void *)scope);
   1005     }
   1006 
   1007     if (fp) {
   1008         sal_fclose((FILE *)fp);
   1009     }
   1010 #ifndef NO_CTRL_C
   1011     sh_pop_ctrl_c();
   1012 #endif
   1013 
   1014     if (rv == CMD_EXIT) {
   1015         /* An 'exit' command in script is normal completion of script. */
   1016         rv = CMD_OK;
   1017     }
   1018 
   1019     return(rv);
   1020 #endif /* NO_FILEIO */
   1021 }
   1022 
   1023 
   1024 #endif /* NO_SAL_APPL */
   1025 
   1026 /*
   1027  * Function:    _sh_parse_units
   1028  * Purpose:    Parse a command prefix specifying which units to use
   1029  * Parameters:    unit - current unit
   1030  *        ustr - input command string with or without prefix
   1031  *        umap - (OUT) bitmap of units to execute on
   1032  *        ulen - (OUT) number of characters to start of command
   1033  * Returns:    cmd_result_t
   1034  */
   1035 
   1036 STATIC int
   1037 _sh_parse_units(int unit, const char *ustr, int *umap_ptr, int *ulen_ptr)
   1038 {
   1039    int i    = 0;
   1040    int umap = 0;
   1041    int ulen = 0;
   1042    int u    = 0;
   1043    int u2   = 0;
   1044    const char *ustr_orig = ustr;
   1045 
   1046     /* See if it looks like a unit specification */
   1047 
   1048    for (i = 0; ustr[i] != ':'; i++) {
   1049        /* Check that specification is not a unit range or * (which means
   1050         * all units) this will allow us to to "BCM.0> 3: l2 show" for example.
   1051         */
   1052        if (ustr[i] != '-' && ustr[i] != ','&&
   1053            ustr[i] != '*' && !isdigit((unsigned)ustr[i]))
   1054        {
   1055          umap = (1 << unit);
   1056          ulen = 0;
   1057          goto done;
   1058       }
   1059    }
   1060 
   1061    /* Parse the unit specification */
   1062    do {
   1063       if (ustr[0] == '*') {
   1064          u = 0;
   1065          u2 = SOC_MAX_NUM_DEVICES;
   1066          ustr++;
   1067       }
   1068       else {
   1069          int cur_pos = 0;
   1070          if (!isdigit((unsigned)ustr[cur_pos])) {
   1071             cli_out("Error: Bad unit specification\n");
   1072             return CMD_FAIL;
   1073          }
   1074 
   1075          u = ustr[cur_pos] - '0';
   1076          if (isdigit((unsigned)ustr[cur_pos+1])) {
   1077             u = 10*(ustr[cur_pos] - '0') + (ustr[cur_pos+1] - '0');
   1078             ++cur_pos;
   1079          }
   1080 
   1081          ++cur_pos;
   1082          if (u >= SOC_MAX_NUM_DEVICES) {
   1083             cli_out("Error: Unit %d out of range\n", u);
   1084             return CMD_FAIL;
   1085          }
   1086 
   1087          if (ustr[cur_pos] == '-' && isdigit((unsigned)ustr[cur_pos+1]))
   1088          {
   1089             /* Range specified */
   1090             u2 = ustr[cur_pos+1] - '0';
   1091             if (isdigit((unsigned)ustr[cur_pos + 2])) {
   1092                 u2 = 10*(ustr[cur_pos + 1] - '0') + (ustr[cur_pos + 2] - '0');
   1093                 ++cur_pos;
   1094             }
   1095 
   1096             cur_pos += 2;
   1097             if (u2 >= SOC_MAX_NUM_DEVICES) {
   1098                cli_out("Error: Unit %d out of range\n", u2);
   1099                return CMD_FAIL;
   1100             }
   1101          } else {
   1102             u2 = u;
   1103          }
   1104 
   1105          /* Update ustr to account for what we have traversed */
   1106          ustr += cur_pos;
   1107       }
   1108       if (u == u2 && !soc_attached(u)) {
   1109          /* Specific unit requested - requires unit to be attached */
   1110          cli_out("Error: Unit %d is not attached\n", u);
   1111          return CMD_FAIL;
   1112       }
   1113       for (i = u; i <= u2; i++) {
   1114          if (soc_attached(i)) {
   1115             umap |= (1 << i);
   1116          }
   1117       }
   1118       if (*ustr != ',' && *ustr != ':') {
   1119          cli_out("Error: Bad unit specification\n");
   1120          return CMD_FAIL;
   1121       }
   1122    } while (*ustr++ == ',');
   1123 
   1124     ulen = ustr - ustr_orig;
   1125 
   1126  done:
   1127 
   1128     *umap_ptr = umap;
   1129     *ulen_ptr = ulen;
   1130 
   1131     return CMD_OK;
   1132 }
   1133 
   1134 cmd_result_t
   1135 sh_process_statement(int u, args_t *a)
   1136 /*
   1137  * Function:    sh_process_statement
   1138  * Purpose:    Evaluate a parsed command statement
   1139  * Parameters:    u - unit number, may be -1 if none
   1140  *        a - Single parsed statement
   1141  * Returns:    cmd_result_t
   1142  */
   1143 {
   1144     /*
   1145      * Variable:    h_args/h_count
   1146      * Purpose:    Parse list to check for help. If a command is issued with
   1147      *        one parameter and it is "help" or "?", the usage line is
   1148      *        printed.
   1149      */
   1150     static const char * const h_args[] = {"HELP", "?"};
   1151     static const int h_cnt = COUNTOF(h_args);
   1152     int        rv, umap, ulen, ualt;
   1153     char    *ac;
   1154     cmd_t    *cmd;
   1155     cmd_t *local_cmd_list = NULL;
   1156     int local_cmd_cnt = 0;
   1157     int i;
   1158 
   1159     ac = ARG_CUR(a);
   1160     if (ac == NULL) {
   1161         return CMD_OK;        /* Ignore empty line */
   1162     }
   1163 
   1164     /*
   1165      * Valid unit should be -1 or < soc_ndev in our system.
   1166      * If a unit is > soc_ndev, it will cause a segment error.
   1167      */
   1168     if (u >= SOC_MAX_NUM_DEVICES) {
   1169             cli_out("Error: Unit %d out of range\n", u);
   1170             return CMD_FAIL;
   1171     }
   1172 
   1173     /*
   1174      * If command is prefixed with "#:", where # is a unit number, or a
   1175      * unit range "#-#:", or a comma-separated list of unit numbers
   1176      * and/or unit ranges, then recursively execute the command on the
   1177      * specified unit(s).
   1178      *
   1179      * If command is prefixed with "*:", then recursively execute
   1180      * the command on all attached units.
   1181      */
   1182 
   1183     if ((rv = _sh_parse_units(u, ac, &umap, &ulen)) != CMD_OK) {
   1184         return rv;
   1185     }
   1186 
   1187     if (ulen > 0) {
   1188 
   1189         /* 
   1190          *  Create a copy of the ndev_idx2dev_map, because it might be changed during device deinit/init called
   1191          *      from this shell command.
   1192          */
   1193         int ndev_idx2dev_map_cpy[SOC_MAX_NUM_DEVICES];
   1194         sal_memcpy(ndev_idx2dev_map_cpy, soc_ndev_idx2dev_map, sizeof(ndev_idx2dev_map_cpy));
   1195 
   1196 
   1197         for (ualt = 0; ualt < soc_ndev && rv == CMD_OK; ualt++) {
   1198             if ((umap & (1 << ndev_idx2dev_map_cpy[ualt])) != 0) {
   1199             args_t        *a_copy;
   1200 
   1201             /* Args structure is too big to replicate on local stack */
   1202 
   1203             if ((a_copy = sal_alloc(sizeof (args_t), "a_copy")) == NULL) {
   1204                 cli_out("Error: out of memory\n");
   1205                 return CMD_FAIL;
   1206             }
   1207 
   1208             sh_swap_unit_vars(ndev_idx2dev_map_cpy[ualt]);
   1209 
   1210                     parse_args_copy(a_copy, a);
   1211 
   1212             a_copy->a_argv[0] += ulen;    /* Skip unit specifier */
   1213 
   1214             if (a_copy->a_argv[0][0] == 0) {
   1215                 /*
   1216                  * If the user put white space after unit specifier,
   1217                  * the command would be in the following word.
   1218                  */
   1219                 ARG_NEXT(a_copy);
   1220             }
   1221 
   1222             rv = sh_process_statement(ndev_idx2dev_map_cpy[ualt], a_copy);
   1223 
   1224             sal_free(a_copy);
   1225             }
   1226         }
   1227 
   1228         sh_swap_unit_vars(u);
   1229 
   1230         return rv;
   1231     }
   1232 
   1233     sh_swap_unit_vars(u);
   1234     ARG_NEXT(a);
   1235 
   1236     /*
   1237      * If it's just an integer, non-zero=success and zero=fail.
   1238      * This is used for "if" conditions.
   1239      */
   1240 
   1241     if (isint(ac) && ARG_CUR(a) == 0) {
   1242         rv = parse_integer(ac) ? CMD_OK : CMD_FAIL;
   1243         return rv;
   1244     }
   1245 
   1246     /* First lookup in dynamic list -- allows redefinition of commands */
   1247     if(u == -1) {
   1248         local_cmd_list = NULL;
   1249         local_cmd_cnt = 0;
   1250         for (i = 0; i < soc_ndev; i++) {
   1251             if(dyn_cmd_list[SOC_NDEV_IDX2DEV(i)] != NULL) {
   1252                 local_cmd_list = dyn_cmd_list[SOC_NDEV_IDX2DEV(i)];
   1253                 local_cmd_cnt = dyn_cmd_cnt[SOC_NDEV_IDX2DEV(i)];
   1254                 break;
   1255             }
   1256         }
   1257     }
   1258     else {
   1259         local_cmd_list = dyn_cmd_list[u];
   1260         local_cmd_cnt = dyn_cmd_cnt[u];
   1261     }
   1262 
   1263     if(local_cmd_list != NULL) {
   1264         cmd = (cmd_t*)parse_lookup(ac, local_cmd_list, sizeof(cmd_t), local_cmd_cnt);
   1265     }
   1266     else {
   1267         cmd = NULL;
   1268     }
   1269 
   1270     if(cmd == NULL) {
   1271         /* Next lookup in common list */
   1272         cmd = (cmd_t *)parse_lookup(ac, bcm_cmd_common,
   1273                                     sizeof(cmd_t), bcm_cmd_common_cnt);
   1274     }
   1275 
   1276     if (cmd == NULL) {      /* Not in common or dynamic list. */
   1277         if(u == -1) {
   1278             local_cmd_list = NULL;
   1279             local_cmd_cnt = 0;
   1280             for (i = 0; i < soc_ndev; i++) {
   1281                 if(cur_cmd_list[SOC_NDEV_IDX2DEV(i)] != NULL) {
   1282                     local_cmd_list = cur_cmd_list[SOC_NDEV_IDX2DEV(i)];
   1283                     local_cmd_cnt = cur_cmd_cnt[SOC_NDEV_IDX2DEV(i)];
   1284                     break;
   1285                 }
   1286             }
   1287         }
   1288         else {
   1289             local_cmd_list = cur_cmd_list[u];
   1290             local_cmd_cnt = cur_cmd_cnt[u];
   1291         }
   1292         if(local_cmd_list == NULL) {
   1293             cli_out("No mode command list for unit:%d\n", u);
   1294             return CMD_NFND;
   1295         }
   1296         cmd = (cmd_t *)parse_lookup(ac, local_cmd_list,
   1297                                     sizeof(cmd_t), local_cmd_cnt);
   1298         if (cmd == NULL) {      /* RC load if not found and enabled */
   1299 
   1300             if (sh_set_rcload) {
   1301 #ifndef NO_SAL_APPL
   1302                 rv = sh_rcload_file(u, a, ac, TRUE);
   1303             } else {
   1304 #endif 
   1305                 rv = CMD_NFND;
   1306             }
   1307 #if 1
   1308     if((rv == CMD_NFND) && (!sal_strcmp(ac, "acc")))
   1309     {
   1310         rv = CMD_OK;
   1311     }
   1312 #endif
   1313             if (rv == CMD_NFND) {
   1314                 cli_out("Unknown command: %s\n", ac);
   1315             }
   1316 
   1317             return rv;
   1318         }
   1319     }
   1320     /* coverity[suspicious_sizeof] */
   1321     if ((ARG_CNT(a) == 1) &&
   1322         parse_lookup(ARG_CUR(a), h_args,
   1323                  sizeof(h_args[0]), h_cnt)) {
   1324         rv = CMD_USAGE;
   1325     } else {
   1326         ARG_CMD(a) = cmd->c_cmd;    /* Set command name */
   1327 
   1328         rv = cmd->c_f(u, a);
   1329     }
   1330 
   1331     if (rv == CMD_USAGE) {  /* Print usage is requested */
   1332         uint32 help_enable = 1;
   1333 
   1334         if (u >= 0) {
   1335             help_enable = soc_property_get(u, spn_HELP_CLI_ENABLE, 1);
   1336         }
   1337         if ((cmd->c_usage) && (help_enable)) {
   1338             cli_out("Usage (%s): %s", cmd->c_cmd, cmd->c_usage);
   1339         } else if (help_enable) {
   1340             cli_out("Usage (%s): %s\n", cmd->c_cmd, cmd->c_help);
   1341         }
   1342     }
   1343 
   1344     if (rv == CMD_NOTIMPL) {
   1345         cli_out("%s: Command not implemented\n", cmd->c_cmd);
   1346         rv = CMD_FAIL;
   1347     }
   1348 
   1349     if (rv == CMD_OK && ARG_CUR(a) != NULL) {
   1350         /*
   1351          * Warn about unconsumed arguments.  If a command doesn't need
   1352          * all its arguments, it should use ARG_DISCARD to eat them.
   1353          */
   1354         cli_out("%s: WARNING: excess arguments ignored "
   1355                 "beginning with '%s'\n",
   1356                 cmd->c_cmd, ARG_CUR(a));
   1357     }
   1358 
   1359     return rv;
   1360 }
   1361 
   1362 cmd_result_t
   1363 sh_process_command(int u, char *c)
   1364 /*
   1365  * Function:     sh_process_command
   1366  * Purpose:    Parse a command, look it up, and dispatch it.
   1367  * Parameters:    u - unit number, may be -1 if none
   1368  *        c - pointer to input line.
   1369  * Returns:    cmd_result_t
   1370  */
   1371 {
   1372     cmd_result_t     rv = CMD_OK;
   1373     args_t        *a;
   1374     char        *c_next;
   1375 
   1376     if (u >= 0) {
   1377         LOG_VERBOSE(BSL_LS_APPL_RCLOAD,
   1378                     (BSL_META_U(u,
   1379                                 "BCM.%d> %s\n"), u, c));
   1380     } else {
   1381         LOG_VERBOSE(BSL_LS_APPL_RCLOAD,
   1382                     (BSL_META_U(u,
   1383                                 "BCM> %s\n"), c));
   1384     }
   1385 
   1386 #if defined(INCLUDE_APIMODE)
   1387     /* Let API mode process the command list first. If it is successful, then
   1388        processing is done. If not, continue command processing. */
   1389     rv = diag_api_mode_process_command(u, c);
   1390     if (rv == CMD_OK) {
   1391         return rv;
   1392     }
   1393 #endif
   1394     c_next = c;
   1395 
   1396     /* Args structure is too big to allocate on local stack */
   1397 
   1398     if ((a = sal_alloc(sizeof (args_t), "args_t")) == NULL) {
   1399         cli_out("sh_process_command: Out of memory\n");
   1400         return CMD_FAIL;
   1401     }
   1402 
   1403     while ((c = c_next) != NULL) {
   1404         while (isspace((unsigned) *c)) {
   1405             c++;
   1406         }
   1407 
   1408         if (diag_parse_args(c, &c_next, a)) {    /* Parses up to ; or EOL */
   1409             rv = CMD_FAIL;
   1410             break;
   1411         }
   1412 
   1413 #if defined(INCLUDE_APIMODE)
   1414         /*
   1415          * Diag shell command may use completion, so turn off API mode
   1416          * completion (if API mode is enabled) before processing, and
   1417          * enable it again afterward.
   1418          */
   1419         (void)diag_api_mode_completion_enable(FALSE);
   1420 #endif
   1421         rv = sh_process_statement(u, a);
   1422 
   1423 #if defined(INCLUDE_APIMODE)
   1424         (void)diag_api_mode_completion_enable(TRUE);
   1425 #endif
   1426 
   1427         (void)var_set_integer("?", rv, TRUE, FALSE);
   1428 
   1429         if (rv == CMD_USAGE || rv == CMD_INTR || rv == CMD_EXIT) {
   1430             break;
   1431         }
   1432     }
   1433 
   1434     sal_free(a);
   1435 
   1436     return(rv);
   1437 }
   1438 
   1439 /*
   1440  * Function:    sh_process_command_check
   1441  * Purpose:
   1442  *      Executes the command if the given unit is available.
   1443  * Parameters:
   1444  *      u - Unit number, may be -1 if none
   1445  *      c - Pointer to input line.
   1446  * Returns:
   1447  *      CMD_XXX
   1448  * Notes:
   1449  *      Routine will return an error if the unit is unavailable when
   1450  *      command is called.
   1451  */
   1452 cmd_result_t
   1453 sh_process_command_check(int u, char *c)
   1454 {
   1455     cmd_result_t rv = CMD_FAIL;
   1456 
   1457     if (BCM_UNIT_CHECK(u)) {
   1458         rv = sh_process_command(u, c);
   1459     }
   1460     BCM_UNIT_IDLE(u);
   1461 
   1462     return rv;
   1463 }
   1464 
   1465 char sh_help_short_usage[] =
   1466     "Parameters: None\n\t"
   1467     "Display a complete list of commands in a concise format.\n";
   1468 
   1469 cmd_result_t
   1470 sh_help_short(int u, args_t *a)
   1471 /*
   1472  * Function:     sh_help_short
   1473  * Purpose:    Print list of all commands in command table.
   1474  * Parameters:    u - unit # (ignored)
   1475  *        a - args, if passed, turns into "??".
   1476  * Returns:    CMD_OK
   1477  */
   1478 {
   1479 #   define    CMD_PER_LINE    5
   1480     int        i, words;
   1481 
   1482     if (0 != ARG_CNT(a)) {
   1483     return(sh_help(u, a));
   1484     }
   1485     cli_out("help: \"??\" or \"help\" for summary\n");
   1486 
   1487     cli_out("Commands common to all modes:\n");
   1488     words = 0;
   1489     for (i = 0; i < bcm_cmd_common_cnt; i++) {
   1490     if (bcm_cmd_common[i].c_help[0] != '.') {
   1491         cli_out("%-15s%s", bcm_cmd_common[i].c_cmd,
   1492                 (words % CMD_PER_LINE) == (CMD_PER_LINE - 1) ? "\n" : "");
   1493         words++;
   1494     }
   1495     }
   1496     if (words % CMD_PER_LINE) {
   1497     cli_out("\n");
   1498     }
   1499 
   1500     cli_out("Commands for current mode:\n");
   1501     words = 0;
   1502     for (i = 0; i < cur_cmd_cnt[u]; i++) {
   1503     if (cur_cmd_list[u][i].c_help[0] != '.') {
   1504         cli_out("%-15s%s", cur_cmd_list[u][i].c_cmd,
   1505                 (words % CMD_PER_LINE) == (CMD_PER_LINE - 1) ? "\n" : "");
   1506         words++;
   1507     }
   1508     }
   1509     if (words % CMD_PER_LINE) {
   1510     cli_out("\n");
   1511     }
   1512 
   1513     if(dyn_cmd_cnt[u] > 0) {
   1514         cli_out("Dynamic commands for all modes:\n");
   1515         words = 0;
   1516         for (i = 0; i < dyn_cmd_cnt[u]; i++) {
   1517             if (dyn_cmd_list[u][i].c_help[0] != '.') {
   1518                 cli_out("%-15s%s", dyn_cmd_list[u][i].c_cmd,
   1519                         (words % CMD_PER_LINE) == (CMD_PER_LINE - 1) ? "\n" : "");
   1520                 words++;
   1521             }
   1522         }
   1523         if (words % CMD_PER_LINE) {
   1524             cli_out("\n");
   1525         }
   1526     }
   1527 
   1528     return(CMD_OK);
   1529 #   undef     CMD_PER_LINE
   1530 }
   1531 
   1532 static void
   1533 print_help_list(cmd_t * cmd_list, int command_count, char *title)
   1534 {
   1535     cmd_t      *cmd;
   1536 
   1537     if (command_count > 0) {
   1538         cli_out("\n%s:\n", title);
   1539         for (cmd = cmd_list; cmd < &cmd_list[command_count]; cmd++) {
   1540             cli_out("\n\nCOMMAND: %s\tDescription: %s\n\n%s",
   1541                     cmd->c_cmd,
   1542                     cmd->c_help[0] == '.' ? &cmd->c_help[1] : cmd->c_help, cmd->c_usage);
   1543         }
   1544     }
   1545 }
   1546 
   1547 char sh_help_usage[] =
   1548     "Parameters: [command] ... \n\t"
   1549     "Display usage information for the listed commands.\n\t"
   1550     "If no parameters given, a list of all commands is printed with\n\t"
   1551     "a short description of the purpose of the command.\n";
   1552 
   1553 /*ARGSUSED*/
   1554 cmd_result_t
   1555 sh_help(int u, args_t *a)
   1556 /*
   1557  * Function:     sh_help
   1558  * Purpose:    Print usage messages for the listed commands
   1559  * Parameters:    u - unit number (not used)
   1560  * Returns:    CMD_XXX
   1561  */
   1562 {
   1563     cmd_t       *cmd;
   1564     char    *c;
   1565     cmd_result_t rv = CMD_OK;
   1566     cmd_t       *clist; /* Current command list */
   1567     int         ccnt;   /* Current count of commands */
   1568 
   1569     /* Input validation */
   1570     if (bcm_attach_check(u) == BCM_E_UNIT) {
   1571         cli_out("WARNING: unit:%d is out of range\n", u);
   1572         return (CMD_OK);
   1573     }
   1574 
   1575     if (!soc_property_get(u, spn_HELP_CLI_ENABLE, 1)) {
   1576         return (CMD_OK);
   1577     }
   1578     /* Provide easy method to print out all commands */
   1579     if (ARG_CNT(a) == 1 && !sal_strcasecmp(_ARG_CUR(a), "print-manual")) {
   1580     ARG_NEXT(a);
   1581         /* Print common commands */
   1582     print_help_list(bcm_cmd_common, bcm_cmd_common_cnt,
   1583         "Commands common to all modes");
   1584     print_help_list(cur_cmd_list[u], cur_cmd_cnt[u],
   1585         "Commands for current mode");
   1586     print_help_list(dyn_cmd_list[u], dyn_cmd_cnt[u],
   1587         "Dynamic commands for all modes");
   1588     return(CMD_OK);
   1589     }
   1590 
   1591     if (ARG_CNT(a) == 0) {        /* Nothing listed */
   1592     int    i;
   1593     cli_out("Help: Type help \"command\" for detailed command usage\n");
   1594     cli_out("Help: Upper case letters signify minimal match\n");
   1595     cli_out("\nCommands common to all modes:\n");
   1596     for (i = 0; i < bcm_cmd_common_cnt; i++) {
   1597         if ((*bcm_cmd_common[i].c_help != '@') &&
   1598         (*bcm_cmd_common[i].c_help != '.')) {
   1599         cli_out("\t%-20s%s\n",
   1600                 bcm_cmd_common[i].c_cmd, bcm_cmd_common[i].c_help);
   1601         }
   1602     }
   1603 
   1604     if (u >= SOC_MAX_NUM_DEVICES) {
   1605         cli_out("WARNING: unit:%d is out of range\n", u);
   1606     } else {
   1607         cli_out("\nCommands for current mode:\n");
   1608         for (i = 0; i < cur_cmd_cnt[u]; i++) {
   1609             if ((*cur_cmd_list[u][i].c_help != '@') &&
   1610                 (*cur_cmd_list[u][i].c_help != '.')) {
   1611                 cli_out("\t%-20s%s\n",
   1612                         cur_cmd_list[u][i].c_cmd, cur_cmd_list[u][i].c_help);
   1613             }
   1614         }
   1615         if (dyn_cmd_cnt[u] > 0) {
   1616             cli_out("\nDynamic commands for all modes:\n");
   1617             for (i = 0; i < dyn_cmd_cnt[u]; i++) {
   1618                 if ((*dyn_cmd_list[u][i].c_help != '@') &&
   1619                     (*dyn_cmd_list[u][i].c_help != '.')) {
   1620                     cli_out("\t%-20s%s\n",
   1621                             dyn_cmd_list[u][i].c_cmd, dyn_cmd_list[u][i].c_help);
   1622                 }
   1623             }
   1624         }
   1625     }
   1626     cli_out("\nNumber Formats:\n"
   1627             "\t[-]0x[0-9|A-F|a-f]+ -hex if number begins with \"0x\"\n"
   1628             "\t[-][0-9]+           -decimal integer\n"
   1629             "\t[-]0[0-7]+          -octal if number begins with \"0\"\n"
   1630             "\t[-]0b[0-1]+         -binary if number begins with \"0b\"\n\n"
   1631             );
   1632     return(CMD_OK);
   1633     }
   1634 
   1635     while ((c = ARG_GET(a)) != NULL) {  /* Look it up */
   1636     /* Try current command list first */
   1637         clist = cur_cmd_list[u];
   1638         ccnt = cur_cmd_cnt[u];
   1639         cmd = (cmd_t *) parse_lookup(c, clist, sizeof(cmd_t), ccnt);
   1640         if (!cmd) {
   1641         /* Next try common command */
   1642             clist = bcm_cmd_common;
   1643             ccnt = bcm_cmd_common_cnt;
   1644             cmd = (cmd_t *) parse_lookup(c, clist, sizeof(cmd_t), ccnt);
   1645             if (!cmd) {
   1646         /* Lastly try dynamic commands */
   1647                 clist = dyn_cmd_list[u];
   1648                 ccnt = dyn_cmd_cnt[u];
   1649                 cmd = (cmd_t *) parse_lookup(c, clist, sizeof(cmd_t), ccnt);
   1650                 if (!cmd) {
   1651                     cli_out("Usage: Command not found: %s\n", c);
   1652                     rv = CMD_FAIL;
   1653                     continue;
   1654                 }
   1655             }
   1656         }
   1657 
   1658         if (*cmd->c_help == '@') {
   1659         cmd = (cmd_t *)parse_lookup(cmd->c_help + 1, clist,
   1660                     sizeof(cmd_t), ccnt);
   1661         if (!cmd) {
   1662         cli_out("%s: Error: Aliased command not found\n", ARG_CMD(a));
   1663         continue;
   1664         }
   1665         cli_out("Usage (%s): is an alias for \"%s\"\n", c, cmd->c_cmd);
   1666     } else {
   1667         c = cmd->c_cmd;
   1668     }
   1669     if (cmd->c_usage) {
   1670         cli_out("Usage (%s): %s", cmd->c_cmd, cmd->c_usage);
   1671     } else {
   1672         cli_out("Usage: Not available for command: %s\n", c);
   1673     }
   1674     }
   1675     return(rv);
   1676 }
   1677 
   1678 STATIC cmd_result_t
   1679 exit_clean(void)
   1680 /*
   1681  * Function:    exit_clean
   1682  * Purpose:     Free up BCM and SOC resources for all attached units
   1683  * Parameters:  None
   1684  * Returns:     CMD_OK/CMD_USAGE/CMD_FAIL
   1685  */
   1686 {
   1687 #ifdef BCM_WARM_BOOT_SUPPORT
   1688     int i = 0;
   1689 
   1690     /*
   1691      * Controlled SOC/BCM tear down: for all units
   1692      * Call clean up routines to free up resources
   1693      * and do not exit BCM shell;
   1694      */
   1695     for (i = 0; i < soc_ndev; i++) {
   1696         if (_bcm_shutdown(SOC_NDEV_IDX2DEV(i)) < 0) {
   1697             return(CMD_FAIL);
   1698         }
   1699 #if defined(BCM_ESW_SUPPORT)
   1700         if (SOC_IS_ESW(SOC_NDEV_IDX2DEV(i))) {
   1701             if (soc_shutdown(SOC_NDEV_IDX2DEV(i)) < 0) {
   1702                 return(CMD_FAIL);
   1703             }
   1704         } else
   1705 #endif /* BCM_ESW_SUPPORT */
   1706         {
   1707             cli_out("Error: warmboot not supported by unit %d\n", SOC_NDEV_IDX2DEV(i));
   1708             return (CMD_FAIL);
   1709         }
   1710 
   1711         cli_out("bcm/soc shut down on unit %d\n", SOC_NDEV_IDX2DEV(i));
   1712    }
   1713 
   1714    return(CMD_OK);
   1715 #else
   1716    return(CMD_USAGE);
   1717 #endif /* BCM_WARM_BOOT_SUPPORT */
   1718 }
   1719 
   1720 char sh_exit_usage[] =
   1721 #ifdef BCM_WARM_BOOT_SUPPORT
   1722     "Parameters: none\n\t"
   1723     "If clean is specified, free up BCM and SOC resources for attached\n\t"
   1724     "units. Device is untouched (for Reload).\n\t"
   1725 #else
   1726     "Parameters: [clean]\n\t"
   1727 #endif /* BCM_WARM_BOOT_SUPPORT */
   1728     "Exit from the current shell, if this is the \"socdiag\" shell\n\t"
   1729     "The system is reset\n";
   1730 
   1731 cmd_result_t
   1732 sh_exit(int u, args_t *a)
   1733 /*
   1734  * Function:     sh_exit
   1735  * Purpose:    Exit from the current level of the shell.
   1736  * Parameters:    None
   1737  * Returns:    CMD_EXIT/CMD_USAGE
   1738  */
   1739 {
   1740     int  arg_count;
   1741     char *arg_str;
   1742     cmd_result_t rv;
   1743 
   1744     COMPILER_REFERENCE(u);
   1745 
   1746     arg_count = ARG_CNT(a);
   1747 
   1748     if (arg_count > 1) {
   1749         return(CMD_USAGE);
   1750     }
   1751 
   1752     if (arg_count == 1) {
   1753         arg_str = ARG_GET(a);
   1754         if (NULL == arg_str) {
   1755             return (CMD_EXIT);
   1756         }
   1757 
   1758 #ifdef BCM_WARM_BOOT_SUPPORT
   1759 #if (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX)
   1760         if (!soc_property_get(u, spn_DIAG_SHELL_EXIT_DO_NOTHING, FALSE)) {
   1761             if (appl_scache_file_close(u) < 0) {
   1762                 cli_out("Unit %d scache file not closed\n", u);
   1763             }
   1764         }
   1765 #endif /* (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX) */
   1766 #endif /* BCM_WARM_BOOT_SUPPORT */
   1767 
   1768         if (!sal_strcasecmp(arg_str, "clean")) {
   1769 #ifdef BCM_WARM_BOOT_SUPPORT
   1770 #if (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX)
   1771             if (soc_property_get(u, spn_DIAG_SHELL_EXIT_DO_NOTHING, FALSE)) {
   1772                 if (appl_scache_file_close(u) < 0) {
   1773                     cli_out("Unit %d scache file not closed\n", u);
   1774                 }
   1775             }
   1776 #endif /* (defined(LINUX) && !defined(__KERNEL__)) || defined(UNIX) */
   1777 #endif /* BCM_WARM_BOOT_SUPPORT */
   1778             rv = exit_clean();
   1779             if (rv != CMD_OK) {
   1780                 return(rv);
   1781             }
   1782         } else {
   1783             return(CMD_USAGE);
   1784         }
   1785     }
   1786     return(CMD_EXIT);
   1787 }
   1788 
   1789 cmd_result_t
   1790 sh_process(int u, const char *pfx, int eof_exit)
   1791 /*
   1792  * Function:     sh_process
   1793  * Purpose:    Process an input stream
   1794  * Parameters:    eof_exit - if true, allow control-d to exit the
   1795  *            command line processing.
   1796  * Returns:    CMD_OK - Processing completed on input stream.
   1797  *        CMD_EXIT - Processing completed on input stream, EXIT
   1798  *        requested
   1799  */
   1800 {
   1801     static char cmd[ARGS_BUFFER];
   1802     static char old_cmd[ARGS_BUFFER] = "";
   1803     char * volatile old_cmd_lw = old_cmd;    /* Pointer to last word */
   1804 
   1805     int    modifier;
   1806     char *tpfx;
   1807     char *t;                /* Tmp buf pointer */
   1808     char *s;                /* cmd buf pointer */
   1809     int    s_len;                /* cmd buf length */
   1810     volatile cmd_result_t rv = CMD_OK;
   1811     volatile int unit = u;
   1812 #ifndef NO_CTRL_C
   1813     jmp_buf ctrl_c;
   1814 #endif
   1815     void * volatile scope = NULL;
   1816     volatile int batchmode = 0;
   1817                                   /* Max batch recursion level */
   1818     void * volatile batchscope[4] = {NULL, NULL, NULL, NULL};
   1819     volatile int bsi = 0;
   1820 #ifdef INCLUDE_EDITLINE
   1821     extern void add_history(char *p);
   1822 #endif
   1823 
   1824 
   1825 #ifndef NO_CTRL_C
   1826     COMPILER_REFERENCE(ctrl_c);
   1827 
   1828     if (!setjmp(ctrl_c)) {
   1829         sh_push_ctrl_c(&ctrl_c);
   1830 
   1831         scope = var_push_scope();
   1832         (void)var_set_integer("?", 0, TRUE, FALSE);
   1833     } else {
   1834         (void)var_set_integer("?", CMD_INTR, TRUE, FALSE);
   1835     }
   1836 #else
   1837     scope = var_push_scope();
   1838     (void)var_set_integer("?", 0, TRUE, FALSE);
   1839 #endif
   1840 
   1841     do {
   1842     /*
   1843      * If we are overriding the current unit, ignore checks.
   1844      */
   1845     if (!override_unit) {
   1846         int        first;
   1847 
   1848         /*
   1849          * If there is no current unit, but some unit is attached,
   1850          * make the first attached unit the current unit.  If no
   1851          * unit is attached, change unit to -1.
   1852          */
   1853 
   1854         for (first = 0; first < soc_ndev; first++) {
   1855             if (soc_attached(SOC_NDEV_IDX2DEV(first))) {
   1856                 break;
   1857             }
   1858         }
   1859 
   1860         if (first == soc_ndev) {
   1861             unit = -1;        /* None attached */
   1862             sh_swap_unit_vars(unit);
   1863         } else if (unit < 0 || !soc_attached(unit)) {
   1864             unit = SOC_NDEV_IDX2DEV(first);
   1865             sh_swap_unit_vars(unit);
   1866         }
   1867     }
   1868 
   1869         /*
   1870          * Batch mode essentially turns off the command prompt and
   1871          * disables local command line substitution.
   1872          *
   1873          * This is a way of emulating the rcload command when file
   1874          * I/O is unavailable in the BCM shell environment.  In this
   1875          * case the commands are entered through the console (e.g.
   1876          * using copy/paste) or through a proxy with file I/O.
   1877          */
   1878 
   1879     if ((s = var_get("proxy_cmd_")) != NULL) {
   1880             if (!sal_strcmp(s, "enter_batchmode")) {
   1881                 batchmode = 1;
   1882             } else if (!sal_strcmp(s, "exit_batchmode")) {
   1883                 batchmode = 0;
   1884             } else if (!sal_strcmp(s, "push_scope")) {
   1885                 batchscope[bsi] = var_push_scope();
   1886                 if (bsi < COUNTOF(batchscope)-1) {
   1887                     bsi++;
   1888                 }
   1889             } else if (!sal_strcmp(s, "pop_scope")) {
   1890                 if (bsi) {
   1891                     bsi--;
   1892                 }
   1893                 var_pop_scope(batchscope[bsi]);
   1894             }
   1895             var_unset("proxy_cmd_", TRUE, FALSE, FALSE);
   1896         }
   1897 
   1898     /*
   1899      * If in debug mode, .debug is appended to the prompt.
   1900      * If the current unit number is non-negative, .UNIT is
   1901      * added to the prompt.
   1902      * The cmd buffer is used for the prompt.
   1903      */
   1904 
   1905     if (batchmode) {
   1906         cmd[0] = 0;        /* No prompt */
   1907     } else if (!bslcons_is_enabled()) {
   1908         cmd[0] = 0;        /* No prompt */
   1909     }
   1910     else if ((s = var_get("prompt")) != NULL)
   1911     {
   1912         sal_strncpy(cmd, s, ARGS_BUFFER - 1);    /* User-defined prompt */
   1913         cmd[ARGS_BUFFER - 1] = 0;
   1914 
   1915         while ((s = (char *) strcaseindex(cmd, "\\n")) != 0)
   1916         {
   1917             strrepl(s, 0, 2, "\n");        /* Allow \n for newline */
   1918         }
   1919     }
   1920     else
   1921     {
   1922         sal_strncpy(cmd, pfx, ARGS_BUFFER - 1);    /* Default prompt */
   1923         cmd[ARGS_BUFFER - 1] = 0;
   1924 
   1925         if (command_mode_get(unit) == BCMX_CMD_MODE) {
   1926 #ifdef    INCLUDE_BCMX
   1927             extern int bcmx_unit_count;
   1928             sal_sprintf(cmd + sal_strlen(cmd), "X(%d units)", bcmx_unit_count);
   1929 #else
   1930             sal_strcat(cmd, "X");
   1931 #endif    /* INCLUDE_BCMX */
   1932         } else if (unit >= 0) {
   1933             int enable = 0;
   1934             
   1935             if (SOC_IS_ESW(unit)) {
   1936 #ifdef BCM_ESW_SUPPORT
   1937                 soc_mem_debug_get(unit, &enable);
   1938 #endif
   1939             }
   1940             
   1941             if (enable) {
   1942                 /* coverity[secure_coding] */
   1943                 sal_strcat(cmd, ".debug");
   1944             }
   1945             sal_sprintf(cmd + sal_strlen(cmd), ".%d", unit);
   1946         }
   1947         /* coverity[secure_coding] */
   1948         sal_strcat(cmd, "> ");
   1949     }
   1950 
   1951     tpfx = cmd;
   1952 
   1953     s = cmd;
   1954     s_len = sizeof(cmd);
   1955 
   1956     while (TRUE) {
   1957         s_len = sizeof(cmd) - (s - cmd);
   1958         if (NULL == sal_readline(tpfx, s, s_len, NULL)) {
   1959             if (eof_exit) {
   1960                 cli_out("EOF\n");
   1961 
   1962 #ifndef NO_CTRL_C
   1963                 sh_pop_ctrl_c();
   1964 #endif
   1965 
   1966                 if (scope) {
   1967                     var_pop_scope(scope);
   1968                 }
   1969                 return(CMD_OK);
   1970 
   1971             } else {
   1972                 cli_out("Type \"EXIT\" to exit shell\n");
   1973                 continue;
   1974             }
   1975         }
   1976 
   1977         if(s[0] == '~') {
   1978             cli_out("EOF\n");
   1979 
   1980 #ifndef NO_CTRL_C
   1981             sh_pop_ctrl_c();
   1982 #endif
   1983 
   1984 /*XXXTTT Need to add this?? Investigate            if (scope) {
   1985                 var_pop_scope(scope);
   1986             }
   1987 */
   1988             return CMD_OK;
   1989         }
   1990         t = s;
   1991         s += sal_strlen(s);
   1992 
   1993         if (s > t && s[-1] == '\\') {
   1994             *s++ = ' ';        /* Replace with white space */
   1995             tpfx = "? ";
   1996             continue;
   1997         }
   1998         break;
   1999     }
   2000 
   2001     /*
   2002      * Process each occurrence of !! and !$, unless it would
   2003      * overflow the buffer.
   2004      */
   2005 
   2006     if (!batchmode) {
   2007 
   2008             modifier = FALSE;
   2009 
   2010             while ((s = (char *) strcaseindex(cmd, "!!")) != 0 &&
   2011                   sal_strlen(cmd) - 2 + sal_strlen(old_cmd) + 1 < ARGS_BUFFER) {
   2012                 strrepl(s, 0, 2, old_cmd);
   2013                 modifier = TRUE;
   2014             }
   2015 
   2016             while ((s = (char *) strcaseindex(cmd, "!$")) != 0 &&
   2017                    sal_strlen(cmd) - 2 + sal_strlen((char *)old_cmd_lw) + 1 <
   2018                    ARGS_BUFFER) {
   2019                 strrepl(s, 0, 2, (char *)old_cmd_lw);
   2020                 modifier = TRUE;
   2021             }
   2022 
   2023             if (modifier) {        /* Echo command if modified */
   2024                 cli_out("%s\n", cmd);    /* Logs if enabled */
   2025             }
   2026         }
   2027 
   2028     /*
   2029      * Save command in !! buffer, but only if it doesn't consist of
   2030      * all white space.  Also save in editline history, if active.
   2031      */
   2032 
   2033     if (sal_strspn(cmd, " \t") < sal_strlen(cmd)) {
   2034         /* coverity[secure_coding] */
   2035         sal_strcpy(old_cmd, cmd);
   2036         for (old_cmd_lw = old_cmd; *old_cmd_lw != 0; old_cmd_lw++)
   2037         ;
   2038         while (old_cmd_lw > old_cmd &&
   2039            isspace((unsigned) old_cmd_lw[-1])) {
   2040         old_cmd_lw--;
   2041         }
   2042         while (old_cmd_lw > old_cmd &&
   2043            !isspace((unsigned) old_cmd_lw[-1])) {
   2044         old_cmd_lw--;
   2045         }
   2046 #ifdef INCLUDE_EDITLINE
   2047         add_history(cmd);
   2048 #endif /* INCLUDE_EDITLINE */
   2049     }
   2050 
   2051     /*
   2052      * If the command is "#:" where # is a unit number, change the
   2053      * default unit number.
   2054      *
   2055      * Processing of commands preceded by a "#:" prefix is done in
   2056      * sh_process_command() so that it works from rc scripts.  Rc
   2057      * scripts are not allowed to change the default unit number.
   2058      */
   2059 
   2060     rv = CMD_OK;
   2061 
   2062     if (cur_mode[unit] == BCMX_CMD_MODE) {
   2063         rv = sh_process_command(unit, cmd);
   2064     } else if (isdigit((unsigned) cmd[0]) &&
   2065                cmd[1] == ':' && cmd[2] == ':'&& cmd[3] == 0) {
   2066 
   2067         u = cmd[0] - '0';
   2068         if (!soc_attached(u)) {
   2069             cli_out("Error: Unit %d is not attached\n", u);
   2070             rv = CMD_FAIL;
   2071         } else {
   2072             override_unit = TRUE;
   2073             unit = u;
   2074             cli_out("Override default SOC device set to %d\n", unit);
   2075         }
   2076 
   2077     } else if (isdigit((unsigned) cmd[0]) &&
   2078                isdigit((unsigned) cmd[1]) && cmd[2] == ':' && cmd[3] == ':' &&
   2079                cmd[4] == 0) {
   2080 
   2081         /* Handle 2 digit unit numbers */
   2082         u = 10 * (cmd[0] - '0') + (cmd[1] - '0');
   2083         if (!soc_attached(u)) {
   2084             cli_out("Error: Unit %d is not attached\n", u);
   2085             rv = CMD_FAIL;
   2086         } else {
   2087             override_unit = TRUE;
   2088             unit = u;
   2089             cli_out("Override default SOC device set to %d\n", unit);
   2090         }
   2091 
   2092     } else if (isdigit((unsigned) cmd[0]) &&
   2093                cmd[1] == ':' && cmd[2] == 0) {
   2094 
   2095         u = cmd[0] - '0';
   2096 
   2097         if (!soc_attached(u)) {
   2098             cli_out("Error: Unit %d is not attached\n", u);
   2099             rv = CMD_FAIL;
   2100         } else {
   2101             /* If we were in override mode, turn it off now. */
   2102             override_unit = FALSE;
   2103             unit = u;
   2104             cli_out("Default SOC device set to %d\n", unit);
   2105             sh_swap_unit_vars(unit);
   2106         }
   2107     } else if (isdigit((unsigned) cmd[0]) && isdigit((unsigned) cmd[1]) &&
   2108                cmd[2] == ':' && cmd[3] == 0) {
   2109 
   2110 /* Handle 2 digit unit numbers */
   2111 
   2112         u = 10 * (cmd[0] - '0') + (cmd[1] - '0');
   2113 
   2114         if (!soc_attached(u)) {
   2115             cli_out("Error: Unit %d is not attached\n", u);
   2116             rv = CMD_FAIL;
   2117         } else {
   2118             /* If we were in override mode, turn it off now. */
   2119             override_unit = FALSE;
   2120             unit = u;
   2121             cli_out("Default SOC device set to %d\n", unit);
   2122             sh_swap_unit_vars(unit);
   2123         }
   2124     } else {
   2125         rv = sh_process_command(unit, cmd);
   2126     }
   2127 
   2128         (void)var_set_integer("?", rv, TRUE, FALSE);
   2129     } while (CMD_EXIT != rv);
   2130     
   2131 #ifndef NO_CTRL_C
   2132     sh_pop_ctrl_c();
   2133 #endif
   2134    
   2135     if (scope) {
   2136         var_pop_scope(scope);
   2137     }
   2138 
   2139     return(rv);
   2140 }
   2141 
   2142 
   2143 #ifndef NO_SAL_APPL
   2144 #ifndef SAL_CONFIG_FILE_DISABLE
   2145 #ifndef NO_FILEIO
   2146 
   2147 char sh_import_usage[] =
   2148     "Parameters: <file> \n\t"
   2149     "Load configuration file (<config>.bcm) file\n\t";
   2150 
   2151 cmd_result_t
   2152 sh_import(int unit, args_t *args)
   2153 /*
   2154  * Function:     sh_import
   2155  * Purpose:    Load configuration file
   2156  * Parameters:    unit - unit number
   2157  *        args - arguments.
   2158  * Returns:    CMD_NFND 0 file not found or result of last command
   2159  *        executed.
   2160  */
   2161 {
   2162     char *fname;
   2163     /* make sure that file name is the only input*/
   2164     if (ARG_CNT(args) != 1) {
   2165         return(CMD_USAGE);
   2166     }
   2167     /* extract file name */
   2168     fname = ARG_GET(args);
   2169 
   2170     /* load config file - assume file name relative to 'pwd' */
   2171     if (sal_config_file_process(fname, NULL, NULL, ".", 1) != 0)
   2172     {
   2173         return CMD_FAIL;
   2174     }
   2175     return CMD_OK;
   2176 }
   2177 #endif /* NO_FILEIO */
   2178 #endif /* SAL_CONFIG_FILE_DISABLE */
   2179 
   2180 char sh_rcload_usage[] =
   2181     "Parameters: <file> [parameters] \n\t"
   2182     "Load commands from a file until the file is complete or an error\n\t"
   2183     "occurs. If optional parameters are listed after <file> they are\n\t"
   2184     "pushed as local variables for the file processing. For example:\n\t"
   2185     "\t rcload fred a bc will result in the variables:\n\t"
   2186     "\t\t$1 = a\n\t"
   2187     "\t\t$2 = bc\n\t"
   2188     "\tduring processing of the file.\n\t"
   2189     "For platforms where FTP is used, the user name, password and host\n\t"
   2190     "may be specified as: \"user%password@host:\" as a prefix to the\n\t"
   2191     "file name\n";
   2192 
   2193 cmd_result_t
   2194 sh_rcload(int u, args_t *a)
   2195 /*
   2196  * Function:     sh_rcload
   2197  * Purpose:    Load commands from a file.
   2198  * Parameters:    u - unit number
   2199  *        a - arguments.
   2200  * Returns:    CMD_NFND 0 file not found or result of last command
   2201  *        executed.
   2202  */
   2203 {
   2204     cmd_result_t rv = CMD_OK;
   2205     char *c = NULL;            /* Keep gcc happy */
   2206 
   2207     if (!ARG_CNT(a)) {
   2208     return(CMD_USAGE);
   2209     }
   2210 
   2211     if (NULL != (c = ARG_GET(a))) {    
   2212         if(CMDEV(u).dev.dev_id == BCM56545_DEVICE_ID) {
   2213             if (sal_memcmp (soc_dev_name(u),"BCM56545K_B0",
   2214                             sal_strlen("BCM56545K_B0")) == 0) {
   2215                 var_set_integer("BCM56545K_B0", 1, FALSE, FALSE);
   2216                 cli_out("BCM56545K_B0 set to 1\n");
   2217             }
   2218         }
   2219         rv = sh_rcload_file(u, a, c, FALSE);
   2220     }
   2221     if (CMD_NFND == rv) {
   2222     cli_out("%s: Error: file not found: %s\n", ARG_CMD(a), c);
   2223     }
   2224     return(rv);
   2225 }
   2226 
   2227 #endif /* NO_SAL_APPL */
   2228 
   2229 char sh_set_usage[] =
   2230     "Parameters: [<option>=<value>\n"
   2231 #ifndef COMPILER_STRING_CONST_LIMIT
   2232     "\tSet or display various configuration information, if no arguments\n\t"
   2233     "are given, the current settings are displayed. Otherwise, all of\n\t"
   2234     "the arguments are set. If \"=\" is the sole argument, the user is\n\t"
   2235     "prompted for each settable item. Current allowable options are:\n\n\t"
   2236     "IFError=[on|off]- if set to \"on\" errors on commands processed\n\t"
   2237     "                  terminate the IF command.\n\t"
   2238     "RCLoad=[on|off] - enable or disable looking for RC load file if\n\t"
   2239     "                  command is not found.\n\t"
   2240     "RCError=[on|off]- if set to \"on\", rcload scripts will abort when\n\t"
   2241     "                  a command fails, if off, processing continues\n\t"
   2242     "                  even if an error occurs.\n\t"
   2243     "RCTest=[on|off]-  if set to \"on\", \"testrun\" will load preferred\n\t"
   2244     "                  init scripts before certain tests (for example,\n\t"
   2245     "                  the MAC and PHY loopback tests need rc.soc).\n\t"
   2246     "LoopError=[on|off]- if set to \"on\", loop commands will abort\n\t"
   2247     "                  when a command fails, if off, processing\n\t"
   2248     "                  continues even if an error occurs.\n\t"
   2249     "MoreLines=<#>   - Specify number of lines printed before holding\n\t"
   2250     "                  on a more command\n\t"
   2251     "ReportTime=<#>  - Specify number of seconds between reports printed\n\t"
   2252     "                  by long-running tests\n"
   2253 #endif
   2254     ;
   2255 
   2256 
   2257 cmd_result_t
   2258 sh_set(int u, args_t *a)
   2259 /*
   2260  * Function:     sh_set
   2261  * Purpose:    Set various configuration arguments.
   2262  * Parameters:    u - unit
   2263  *        a - arguments.
   2264  * Returns:    CMD_OK or CMD_FAIL.
   2265  * Notes:    This routine will not free strings properly!
   2266  */
   2267 {
   2268     parse_table_t    pt;
   2269 
   2270     parse_table_init(u, &pt);
   2271     parse_table_add(&pt, "IFError", PQ_DFL|PQ_BOOL, 0,
   2272             &sh_set_iferror, NULL);
   2273     parse_table_add(&pt, "RCLoad", PQ_DFL|PQ_BOOL, 0,
   2274             &sh_set_rcload, NULL);
   2275     parse_table_add(&pt, "RCError", PQ_DFL|PQ_BOOL, 0,
   2276             &sh_set_rcerror, NULL);
   2277     parse_table_add(&pt, "RCTest", PQ_DFL|PQ_BOOL, 0,
   2278             &sh_set_rctest, NULL);
   2279     parse_table_add(&pt, "LoopError", PQ_DFL|PQ_BOOL, 0,
   2280             &sh_set_lperror, NULL);
   2281     parse_table_add(&pt, "MoreLines", PQ_DFL|PQ_INT, 0,
   2282             &sh_set_more_lines, NULL);
   2283     parse_table_add(&pt, "ReportStatus", PQ_DFL|PQ_BOOL, 0,
   2284             &sh_set_report_status, NULL);
   2285     parse_table_add(&pt, "ReportTime", PQ_DFL|PQ_INT, 0,
   2286             &sh_set_report_time, NULL);
   2287 
   2288     if (!ARG_CNT(a)) {            /* Display settings */
   2289     cli_out("Current settings:\n");
   2290     parse_eq_format(&pt);
   2291     parse_arg_eq_done(&pt);
   2292     return(CMD_OK);
   2293     }
   2294 
   2295     if (0 > parse_arg_eq(a, &pt)) {
   2296     cli_out("%s: Error: Unknown option: %s\n", ARG_CMD(a), ARG_CUR(a));
   2297     parse_arg_eq_done(&pt);
   2298     return(CMD_FAIL);
   2299     }
   2300 
   2301     parse_arg_eq_done(&pt);
   2302     return(CMD_OK);
   2303 }
   2304 
   2305 typedef enum {
   2306     shBslOptSet,
   2307     shBslOptSetAll,
   2308     shBslOptClrAll,
   2309     shBslOptRst,
   2310     shBslOptToggle,
   2311     shBslOptShow,
   2312     shBslOptNums
   2313 } sh_bsl_opt_t;
   2314 
   2315 typedef enum {
   2316     shBslOutLayer,
   2317     shBslOutSource,
   2318     shBslOutSeverity,
   2319     shBslOutSeverityEnd,
   2320     shBslOutNums
   2321 } sh_bsl_out_t;
   2322 
   2323 typedef struct {
   2324     uint8 layer_list[bslLayerCount];
   2325     uint8 layer_count;
   2326 } bsl_layer_list_t;
   2327 
   2328 typedef struct {
   2329     uint16 source_list[bslLayerCount][bslSourceCount];
   2330     uint16 source_count[bslLayerCount];
   2331 } bsl_source_list_t;
   2332 
   2333 typedef enum {
   2334     shBslThreadOptDisable,
   2335     shBslThreadOptSet,
   2336     shBslThreadOptClrAll,
   2337     shBslThreadOptNums
   2338 } sh_bsl_thread_opt_t;
   2339 
   2340 typedef struct {
   2341     int thread_list[MAX_BSLENABLE_THREAD_COUNT];
   2342     uint8   thread_count;
   2343 } bsl_thread_list_t;
   2344 
   2345 /*
   2346  * Function:     
   2347  *      sh_bsl_list_next
   2348  * Purpose:    
   2349  *      Find the bsl next list item.
   2350  * Parameters:    
   2351  *      context - list context
   2352  * Returns:    
   2353  *      CMD_OK or CMD_NFND if item not found.
   2354  * Notes:
   2355  */
   2356 STATIC int
   2357 sh_bsl_list_next(char **context)
   2358 {   
   2359     char *delimiter;
   2360     
   2361     if ((delimiter = sal_strchr(*context, ',')) != NULL) {
   2362         *context = delimiter + 1;
   2363         return CMD_OK;
   2364     }    
   2365 
   2366     return CMD_NFND;
   2367 }
   2368 
   2369 /*
   2370  * Function:     
   2371  *      sh_bsl_parse_option
   2372  * Purpose:    
   2373  *      Parse the option from the arguments.
   2374  * Parameters:    
   2375  *      arg - arguments
   2376  *      option - bsl option.
   2377  * Returns:    
   2378  *      CMD_OK or CMD_NFND if option not found.
   2379  * Notes:
   2380  */
   2381 STATIC int 
   2382 sh_bsl_parse_option(char *arg, sh_bsl_opt_t *option) 
   2383 {    
   2384     if (sal_strcasecmp(arg, "+") == 0) {
   2385         *option = shBslOptSetAll;
   2386     } else if (sal_strcasecmp(arg, "-") == 0) {
   2387         *option = shBslOptClrAll;
   2388     } else if (sal_strcasecmp(arg, "=") == 0) {
   2389         *option = shBslOptRst;
   2390     } else {
   2391         return CMD_NFND;
   2392     }
   2393 
   2394     return CMD_OK;
   2395 }
   2396 
   2397 /*
   2398  * Function:     
   2399  *      sh_bsl_parse_severity
   2400  * Purpose:    
   2401  *      Parse the severity from the arguments.
   2402  * Parameters:    
   2403  *      arg - arguments
   2404  *      option - bsl severity.
   2405  * Returns:    
   2406  *      CMD_OK or CMD_NFND if severity not found.
   2407  * Notes:
   2408  */
   2409 STATIC int 
   2410 sh_bsl_parse_severity(char *arg, bsl_severity_t *severity) 
   2411 {
   2412     int i;
   2413 	const char *name;
   2414 
   2415     for (i = 0; i < bslSeverityCount; i++) {
   2416 		name = bsl_severity2str(i);
   2417         if (parse_cmp(name, arg, '\0')) {
   2418             *severity = i;
   2419             return CMD_OK;
   2420         }
   2421     }
   2422 
   2423     return CMD_NFND;
   2424 }
   2425 
   2426 /*
   2427  * Function:     
   2428  *      sh_bsl_parse_layer
   2429  * Purpose:    
   2430  *      Parse the layer from the arguments.
   2431  * Parameters:    
   2432  *      arg - arguments
   2433  *      option - bsl layer.
   2434  * Returns:    
   2435  *      CMD_OK or CMD_NFND if layer not found.
   2436  * Notes:
   2437  */
   2438 STATIC int 
   2439 sh_bsl_parse_layer(char *arg, bsl_layer_list_t *layer) 
   2440 {
   2441     int i;
   2442     int is_found;
   2443     const char *name;
   2444 
   2445     is_found = FALSE;
   2446     do {          
   2447         for (i = 0; i < bslLayerCount; i++) {
   2448             name = bsl_layer2str(i);
   2449             if (parse_cmp(name, arg, ',') ||
   2450                 parse_cmp(name, arg, '\0')) {
   2451                 is_found = TRUE;
   2452                 layer->layer_list[(layer->layer_count)++] = i; 
   2453                 break;
   2454             } 
   2455         }
   2456     } while (sh_bsl_list_next(&arg) == CMD_OK);
   2457     
   2458     /* check whether the layer is found */
   2459     if (!is_found) {
   2460         return CMD_NFND;
   2461     }
   2462 
   2463     return CMD_OK;
   2464 }
   2465 
   2466 /*
   2467  * Function:     
   2468  *      sh_bsl_parse_source
   2469  * Purpose:    
   2470  *      Parse the source from the arguments.
   2471  * Parameters:    
   2472  *      arg - arguments
   2473  *      option - bsl source.
   2474  * Returns:    
   2475  *      CMD_OK or CMD_NFND if source not found.
   2476  * Notes:
   2477  */
   2478 STATIC int 
   2479 sh_bsl_parse_source(char *arg, bsl_layer_list_t *layer, bsl_source_list_t *source)
   2480 {
   2481     int i, j;
   2482     int is_found;
   2483     char *arg_cmp;
   2484     bsl_layer_t lay; 
   2485     const char *name;
   2486     
   2487     is_found = FALSE;
   2488     for (i = 0; i < layer->layer_count; i++) {
   2489         lay = layer->layer_list[i];        
   2490         arg_cmp = arg;
   2491         do {              
   2492             for (j = 0; j < bslSourceCount; j++) {
   2493                 if (!bslmgmt_source_valid(lay, j)) {
   2494                     continue;
   2495                 }
   2496                 name = bsl_source2str(j);
   2497                 if (parse_cmp(name, arg_cmp, ',') ||
   2498                     parse_cmp(name, arg_cmp, '\0')) {
   2499                     is_found = TRUE;
   2500                     source->source_list[lay][source->source_count[lay]] = j;
   2501                     (source->source_count[lay])++;
   2502                     break;
   2503                 }                 
   2504             }
   2505         } while (sh_bsl_list_next(&arg_cmp) == CMD_OK);
   2506     }
   2507     
   2508     /* check whether the source is found */
   2509     if (!is_found) {
   2510         return CMD_NFND;
   2511     }
   2512 
   2513     return CMD_OK;
   2514 }
   2515 
   2516 /*
   2517  * Function:     
   2518  *      sh_bsl_enable_source_all
   2519  * Purpose:    
   2520  *      Enable all source from the layer list.
   2521  * Parameters:    
   2522  *      layer - layer list
   2523  *      source - source list. 
   2524  * Returns:    
   2525  *      CMD_OK. 
   2526  * Notes:
   2527  */
   2528 STATIC int 
   2529 sh_bsl_enable_source_all(bsl_layer_list_t *layer, bsl_source_list_t *source)
   2530 {
   2531     int i, j;
   2532     bsl_layer_t lay;
   2533 
   2534     for (i = 0; i < layer->layer_count; i++) {
   2535         lay = layer->layer_list[i];
   2536         for (j = 0; j < bslSourceCount; j++) {
   2537             if (!bslmgmt_source_valid(lay, j)) {
   2538                 continue;
   2539             }
   2540             source->source_list[lay][source->source_count[lay]] = j;
   2541             (source->source_count[lay])++;
   2542         }
   2543     }
   2544     
   2545     return CMD_OK;
   2546 }
   2547 
   2548 /*
   2549  * Function:     
   2550  *      sh_bsl_enable_layer_all
   2551  * Purpose:    
   2552  *      Enable all layer.
   2553  * Parameters:    
   2554  *      layer - layer list
   2555  * Returns:    
   2556  *      CMD_OK.
   2557  * Notes:
   2558  */
   2559 STATIC int 
   2560 sh_bsl_enable_layer_all(bsl_layer_list_t *layer) 
   2561 {
   2562     int i;
   2563 
   2564     for (i = 0; i < bslLayerCount; i++) {
   2565         layer->layer_list[(layer->layer_count)++] = i;
   2566     }
   2567     
   2568     return CMD_OK;
   2569 }
   2570 
   2571 /*
   2572  * Function:     
   2573  *      sh_bsl_enable_layer_source_all
   2574  * Purpose:    
   2575  *      Enable all source for all layer.
   2576  * Parameters:    
   2577  *      layer - layer list
   2578  *      source - source list.
   2579  * Returns:    
   2580  *      CMD_OK.
   2581  * Notes:
   2582  */
   2583 STATIC int
   2584 sh_bsl_enable_layer_source_all(bsl_layer_list_t *layer, bsl_source_list_t *source)
   2585 {
   2586     sh_bsl_enable_layer_all(layer);
   2587     sh_bsl_enable_source_all(layer, source);
   2588     
   2589     return CMD_OK;
   2590 }
   2591 
   2592 /*
   2593  * Function:     
   2594  *      sh_bsl_parse
   2595  * Purpose:    
   2596  *      Parse the bsl command and save it in option, severity, layer list and source list.
   2597  * Parameters:    
   2598  *      arg1 - first argument
   2599  *      agr2 - second argument
   2600  *      agr3 - third argument
   2601  *      option - bsl option
   2602  *      layer - bsl layer list
   2603  *      source - bsl source list
   2604  *      severity -bsl severity. 
   2605  * Returns:    
   2606  *      CMD_OK or CMD_USAGE if option/layer/source/severity not found.
   2607  * Notes:
   2608  */
   2609 STATIC int 
   2610 sh_bsl_parse(char *arg1, char *arg2, char *arg3, sh_bsl_opt_t *option, 
   2611              bsl_layer_list_t *layer, bsl_source_list_t *source,
   2612              bsl_severity_t *severity) 
   2613 {
   2614     if (arg1 == NULL) {
   2615         sh_bsl_enable_layer_source_all(layer, source);
   2616         return CMD_OK;
   2617     }
   2618     /* Check whether is bsl show */
   2619     if (*option == shBslOptShow) {
   2620         if (sh_bsl_parse_layer(arg1, layer) == CMD_OK) {
   2621             /* Check whether is:  bsl layer  */   
   2622             if (arg2 == NULL) {
   2623                 sh_bsl_enable_source_all(layer, source);
   2624                 return CMD_OK;
   2625             } else if (sh_bsl_parse_source(arg2, layer, source) == CMD_OK) { 
   2626                 /* Check whether is:  bsl layer source */
   2627                 return CMD_OK;
   2628             } else {
   2629                 return CMD_USAGE;
   2630             } 
   2631         } else {
   2632             sh_bsl_enable_layer_all(layer);
   2633             if (sh_bsl_parse_source(arg1, layer, source) == CMD_OK) { 
   2634                 /* Check whether is:  bsl source */
   2635                 if (arg2 == NULL) {
   2636                     return CMD_OK;
   2637                 } else {
   2638                     return CMD_USAGE;
   2639                 }
   2640             } else {
   2641                 return CMD_USAGE;
   2642             }
   2643         }
   2644     } else {
   2645         if ((sh_bsl_parse_option(arg1, option) == CMD_OK) ||  
   2646             (sh_bsl_parse_severity(arg1, severity) == CMD_OK)) { 
   2647             /* Check whether is:  bsl <severity|+|-|=>  */        
   2648             if ((arg2 != NULL) || (arg3 != NULL)) {
   2649                 return CMD_USAGE;        
   2650             }
   2651             sh_bsl_enable_layer_source_all(layer, source);
   2652             return CMD_OK;        
   2653         } else if (sh_bsl_parse_layer(arg1, layer) == CMD_OK) { 
   2654             /* Check whether is:  bsl layer  */   
   2655             if (arg2 == NULL) {
   2656                 /* Show current settings if only layer is specified */
   2657                 *option = shBslOptShow;
   2658                 sh_bsl_enable_source_all(layer, source);
   2659                 return CMD_OK;
   2660             } else if ((sh_bsl_parse_option(arg2, option) == CMD_OK) ||  
   2661                 (sh_bsl_parse_severity(arg2, severity) == CMD_OK)) { 
   2662                 /* Check whether is:  bsl layer <+|-|=> */
   2663                 if (arg3 != NULL) {
   2664                     return CMD_USAGE;
   2665                 }
   2666                 sh_bsl_enable_source_all(layer, source);
   2667                 return CMD_OK;
   2668             } else if (sh_bsl_parse_source(arg2, layer, source) == CMD_OK) { 
   2669                 /* Check whether is:  bsl layer source */
   2670                 if (arg3 == NULL) {
   2671                     *option = shBslOptToggle;
   2672                     return CMD_OK;
   2673                 } else if ((sh_bsl_parse_option(arg3, option) == CMD_OK) ||  
   2674                     (sh_bsl_parse_severity(arg3, severity) == CMD_OK)) {
   2675                     /* Check whether is:  bsl layer source <severity|+|-|=> */
   2676                     return CMD_OK;
   2677                 } else {
   2678                     return CMD_USAGE;
   2679                 } 
   2680             } else {
   2681                 return CMD_USAGE;
   2682             }
   2683         } else {
   2684             sh_bsl_enable_layer_all(layer);
   2685             if (sh_bsl_parse_source(arg1, layer, source) == CMD_OK) { 
   2686                 /* Check whether is:  bsl source */
   2687                 if (arg2 == NULL) {
   2688                     *option = shBslOptToggle;
   2689                     return CMD_OK;
   2690                 } else if ((sh_bsl_parse_option(arg2, option) == CMD_OK) ||  
   2691                     (sh_bsl_parse_severity(arg2, severity) == CMD_OK)) { 
   2692                     /* Check whether is:  bsl source <severity|+|-|=>  */        
   2693                     if (arg3 != NULL) {
   2694                         return CMD_USAGE;        
   2695                     }
   2696                     return CMD_OK;        
   2697                 } else {
   2698                     return CMD_USAGE;
   2699                 }
   2700             }
   2701         }
   2702     }
   2703 
   2704     return CMD_USAGE;
   2705 }
   2706 
   2707 /*
   2708  * Function:     
   2709  *      sh_bsl_config
   2710  * Purpose:    
   2711  *      config the bsl.
   2712  * Parameters:    
   2713  *      unit - unit number
   2714  *      option - bsl option
   2715  *      option - bsl layer
   2716  *      option - bsl source
   2717  *      option - bsl severity
   2718  * Returns:    
   2719  *      CMD_OK or CMD_NFND if option not valid.
   2720  * Notes:
   2721  */
   2722 STATIC int
   2723 sh_bsl_config(int unit, sh_bsl_opt_t option, int layer, int source, int severity)
   2724 {
   2725     int rv = CMD_OK;
   2726     
   2727     switch(option) {
   2728     case shBslOptSet:
   2729         bslmgmt_set(layer, source, severity);
   2730         break;
   2731         
   2732     case shBslOptSetAll:
   2733         severity = bslSeverityVerbose;
   2734         bslmgmt_set(layer, source, severity);
   2735         break;
   2736         
   2737     case shBslOptClrAll:
   2738         severity = bslSeverityOff;
   2739         bslmgmt_set(layer, source, severity);
   2740         break;
   2741 
   2742     case shBslOptRst:
   2743         bslmgmt_reset(layer, source);
   2744         break;
   2745 
   2746     case shBslOptToggle:
   2747         if (bslmgmt_get(layer, source) >= bslSeverityVerbose) {
   2748             bslmgmt_reset(layer, source);
   2749         } else {
   2750             severity = bslSeverityVerbose;
   2751             bslmgmt_set(layer, source, severity);
   2752         } 
   2753         break;
   2754 
   2755     default:
   2756         rv = CMD_NFND;
   2757         break;
   2758     }
   2759     
   2760     return rv;
   2761 }
   2762 
   2763 /*
   2764  * Function:     
   2765  *      sh_bsl_print
   2766  * Purpose:    
   2767  *      Print the bsl configuration.
   2768  * Parameters:    
   2769  *      unit - unit number
   2770  *      out - bsl output type
   2771  *      option - bsl layer
   2772  *      option - bsl source
   2773  *      option - bsl severity
   2774  *      count - source count.
   2775  * Returns:    
   2776  *      CMD_OK or CMD_NFND if output not valid.
   2777  * Notes:
   2778  */
   2779 STATIC int
   2780 sh_bsl_print(int unit, sh_bsl_out_t out, int layer, int source, int severity, int *count)
   2781 {
   2782     int rv = CMD_OK;
   2783     const char *name;
   2784 
   2785     switch(out) {
   2786     case shBslOutLayer:
   2787         name = bsl_layer2str(layer);
   2788         cli_out("-------- %s --------\n", name);
   2789         break;
   2790 
   2791     case shBslOutSource:
   2792         if ((*count) == 0) {
   2793             cli_out("%8s ", " ");
   2794         }
   2795         name = bsl_source2str(source);
   2796         cli_out("%s ", name);
   2797         if (++(*count) >= 8) {
   2798             (*count) = 0;
   2799             cli_out("\n");
   2800         }
   2801         break;
   2802 
   2803     case shBslOutSeverity:       
   2804         severity = bslmgmt_get(layer, source);
   2805         name = bsl_severity2str(severity);
   2806         cli_out("%s\n", name);
   2807         break;
   2808 	
   2809     case shBslOutSeverityEnd:
   2810         cli_out("\n");
   2811         break;
   2812 
   2813     default:
   2814         rv = CMD_NFND;
   2815         break;
   2816     }
   2817     
   2818     return rv;
   2819 }
   2820 
   2821 /*
   2822  * Function:     
   2823  *      sh_bsl_cfg
   2824  * Purpose:    
   2825  *      Config the bsl by the layer list and source list.
   2826  * Parameters:    
   2827  *      unit - unit number
   2828  *      option - bsl option
   2829  *      option - bsl layer list
   2830  *      option - bsl source list
   2831  *      option - bsl severity
   2832  * Returns:    
   2833  *      CMD_OK or CMD_FAIL if configuration failed.
   2834  * Notes:
   2835  */
   2836 STATIC int
   2837 sh_bsl_cfg(int unit, sh_bsl_opt_t option, bsl_layer_list_t *layer,
   2838            bsl_source_list_t *source, bsl_severity_t severity)
   2839 {
   2840     int rv = 0;
   2841     int lay;
   2842     int src;
   2843     int found_lay;
   2844     int found_src;
   2845 
   2846     for (lay = 0; lay < layer->layer_count; lay++) {
   2847         found_lay = layer->layer_list[lay];
   2848         for (src = 0; src < source->source_count[found_lay]; src++) {
   2849             found_src = source->source_list[found_lay][src];
   2850             rv = sh_bsl_config(unit, option, found_lay, found_src, severity);
   2851             if (rv < 0) {
   2852                 return CMD_FAIL;
   2853             }
   2854         }
   2855     }
   2856 
   2857     return CMD_OK;
   2858 }
   2859 
   2860 /*
   2861  * Function:     
   2862  *      sh_bsl_show
   2863  * Purpose:    
   2864  *      Show the bsl configuration by the layer list and source list.
   2865  * Parameters:    
   2866  *      unit - unit number
   2867  *      option - bsl layer
   2868  *      option - bsl source
   2869  *      option - bsl severity.
   2870  * Returns:    
   2871  *      CMD_OK.
   2872  * Notes:
   2873  */
   2874 STATIC int
   2875 sh_bsl_show(int unit, bsl_layer_list_t *layer, bsl_source_list_t *source,
   2876             bsl_severity_t severity)
   2877 {
   2878     int lay;
   2879     int src;
   2880     int sev;
   2881     int found_lay;
   2882     int found_src;
   2883     int count;
   2884     int found_severity;
   2885 
   2886     for (lay = 0; lay < layer->layer_count; lay++) {
   2887         found_lay = layer->layer_list[lay];
   2888         if (source->source_count[found_lay]) {
   2889             sh_bsl_print(unit, shBslOutLayer, found_lay, -1, -1, NULL);
   2890 
   2891             for (sev = 0; sev < bslSeverityCount; sev++) {
   2892                 count = 0;
   2893                 found_severity = FALSE;
   2894 
   2895                 for (src = 0; src < source->source_count[found_lay]; src++) {
   2896                     found_src = source->source_list[found_lay][src];
   2897                     if (bslmgmt_get(found_lay, found_src) == sev) {
   2898                         if (!found_severity) {
   2899                             found_severity = TRUE;
   2900                             sh_bsl_print(unit, shBslOutSeverity, found_lay,
   2901                                          found_src, sev, NULL);
   2902                         }
   2903 
   2904                         sh_bsl_print(unit, shBslOutSource, found_lay,
   2905                                      found_src, -1, &count);
   2906                     }
   2907                 }
   2908                 
   2909                 if (found_severity) {
   2910                     sh_bsl_print(unit, shBslOutSeverityEnd, -1, -1, -1, NULL);
   2911                 }                    
   2912             }
   2913         }
   2914     }
   2915 
   2916     return CMD_OK;
   2917 }
   2918 
   2919 int
   2920 parse_severity_str(int u, const char *sev_str, bsl_severity_t *severity)
   2921 {
   2922     bsl_severity_t sev = bslSeverityCount;
   2923 
   2924     if (sev_str != NULL && *sev_str) {
   2925         for (sev = 0; sev < bslSeverityCount; sev++) {
   2926             if (parse_cmp(bsl_severity2str(sev), sev_str, 0)) {
   2927                 *severity = sev;
   2928                 break;
   2929             }
   2930         }
   2931         if (sev == bslSeverityCount) {
   2932             return -1;
   2933         }
   2934     }
   2935     return 0;
   2936 }
   2937 
   2938 int
   2939 parse_bit_range(int u, const char *bstr,
   2940                 SHR_BITDCL *bit_range, int num_bits)
   2941 {
   2942     int bitnum = 0;
   2943     int bstart = -1;
   2944     char ch;
   2945     const char *cptr = bstr;;
   2946 
   2947     if (bstr == NULL || *bstr == 0) {
   2948         return 0;
   2949     }
   2950     if (sal_strcmp(bstr, "all") == 0) {
   2951         SHR_BITSET_RANGE(bit_range, 0, num_bits);
   2952         return 0;
   2953     }
   2954     SHR_BITCLR_RANGE(bit_range, 0, num_bits);
   2955     do {
   2956         ch = *cptr++;
   2957         if (ch >= '0' && ch <= '9') {
   2958             bitnum = (bitnum * 10) + (ch - '0');
   2959         } else {
   2960             if (bstart >= 0) {
   2961                 while (bstart < bitnum) {
   2962                     if (bstart >= num_bits) {
   2963                         return -1;
   2964                     }
   2965                     SHR_BITSET(bit_range, bstart);
   2966                     bstart++;
   2967                 }
   2968                 bstart = -1;
   2969             }
   2970             if (ch == ',' || ch == 0) {
   2971                 if (bitnum >= num_bits) {
   2972                     return -1;
   2973                 }
   2974                 SHR_BITSET(bit_range, bitnum);
   2975                 bitnum = 0;
   2976             } else if (ch == '-') {
   2977                 bstart = bitnum;
   2978                 bitnum = 0;
   2979             } else {
   2980                 return -1;
   2981             }
   2982         }
   2983     } while (ch != 0);
   2984 
   2985     return 0;
   2986 }
   2987 
   2988 STATIC void
   2989 sh_bsl_show_bit_range(int u, const char *prefix,
   2990                       SHR_BITDCL *bit_range, int num_bits)
   2991 {
   2992     int idx, all;
   2993 
   2994     cli_out("%s", prefix);
   2995     all = 1;
   2996     for (idx = 0; idx < num_bits; idx++) {
   2997         if (SHR_BITGET(bit_range, idx) == 0) {
   2998             all = 0;
   2999             break;
   3000         }
   3001     }
   3002     if (all) {
   3003         cli_out("all\n");
   3004     } else {
   3005         for (idx = 0; idx < num_bits; idx++) {
   3006             if (idx < (num_bits - 1) &&
   3007                 SHR_BITGET(bit_range, idx) &&
   3008                 SHR_BITGET(bit_range, idx + 1)) {
   3009                 cli_out("%d-", idx);
   3010                 idx++;
   3011                 while (idx < (num_bits - 1) &&
   3012                        SHR_BITGET(bit_range, idx) &&
   3013                        SHR_BITGET(bit_range, idx + 1)) {
   3014                     idx++;
   3015                 }
   3016             }
   3017             if (SHR_BITGET(bit_range, idx)) {
   3018                 cli_out("%d ", idx);
   3019             }
   3020         }
   3021         cli_out("\n");
   3022     }
   3023 }
   3024 
   3025 STATIC int
   3026 sh_bsl_thread_show(int unit, bsl_layer_list_t *layer, bsl_source_list_t *source)
   3027 {
   3028     int lay;
   3029     int src;
   3030     int found_lay;
   3031     int found_src;
   3032     int tidx;
   3033     int found_thread;
   3034     int count, layer_match, src_match;
   3035 
   3036     cli_out("======== Thread info ========\n ");
   3037     for (lay = 0; lay < layer->layer_count; lay++) {
   3038         found_lay = layer->layer_list[lay];
   3039         layer_match = 0;
   3040         if (source->source_count[found_lay]) {
   3041             for (src = 0; src < source->source_count[found_lay]; src++) {
   3042                 found_src = source->source_list[found_lay][src];
   3043                 src_match = 0;
   3044                 for (tidx = 0; tidx < MAX_BSLENABLE_THREAD_COUNT; tidx ++) {
   3045                     found_thread = bslenable_thread_get(found_lay, found_src,
   3046                                                         tidx);
   3047                     if (found_thread == 0){
   3048                         break;
   3049                     }
   3050                     if (!layer_match) {
   3051                         sh_bsl_print(unit, shBslOutLayer, found_lay, -1, -1,
   3052                                      NULL);
   3053                         layer_match = 1;
   3054                     }
   3055                     if (!src_match) {
   3056                         count = 1;
   3057                         sh_bsl_print(unit, shBslOutSource, found_lay,
   3058                                      found_src, -1, &count);
   3059                         src_match = 1;
   3060                     }
   3061                     cli_out("\n%8s Thread ID : %d \n", " ", found_thread);
   3062                 }
   3063             }
   3064         }
   3065     }
   3066 
   3067     return CMD_OK;
   3068 }
   3069 
   3070 STATIC int
   3071 sh_bsl_thread_cfg(int unit, bsl_layer_list_t *layer,
   3072                   bsl_source_list_t *source, bsl_thread_list_t *thread)
   3073 {
   3074     int lay;
   3075     int src;
   3076     int thr;
   3077     int found_lay;
   3078     int found_src;
   3079     int found_thr;
   3080 
   3081     for (lay = 0; lay < layer->layer_count; lay++) {
   3082         found_lay = layer->layer_list[lay];
   3083         for (src = 0; src < source->source_count[found_lay]; src++) {
   3084             found_src = source->source_list[found_lay][src];
   3085             for (thr = 0; thr < MAX_BSLENABLE_THREAD_COUNT; thr++){
   3086                 found_thr = thread->thread_list[thr];
   3087                 bslenable_thread_set(found_lay, found_src, thr, found_thr);
   3088             }
   3089         }
   3090     }
   3091 
   3092     return CMD_OK;
   3093 }
   3094 
   3095 STATIC int
   3096 sh_bsl_thread_parse(char *arg, bsl_thread_list_t *thread_list,
   3097                     sh_bsl_thread_opt_t *t_option){
   3098     int i;
   3099     char *tokstr, *tokstra = NULL;
   3100     char *c, *all;
   3101     int p = 0;
   3102 
   3103     if (arg == NULL) {
   3104         cli_out("Please specify thread_list\n");
   3105         return CMD_FAIL;
   3106     }
   3107     *t_option = shBslThreadOptSet;
   3108 
   3109     tokstr = arg;
   3110     i = 0;
   3111     do {
   3112         if (thread_list->thread_count >= MAX_BSLENABLE_THREAD_COUNT) {
   3113             cli_out("Too many thread IDs. Maximum is %d.\n",
   3114                     MAX_BSLENABLE_THREAD_COUNT);
   3115             return CMD_FAIL;
   3116         }
   3117         tokstra = tokstr;
   3118         all = sal_strtok_r(tokstra, "\0", &tokstra);
   3119         if (all == NULL) {
   3120             break;
   3121         }
   3122         c = sal_strtok_r(all, ",", &tokstr);
   3123         if (c == NULL) {
   3124             break;
   3125         }
   3126         if (sal_strcasecmp(c, "OFF") == 0) {
   3127             /* Check whether is: debug thread OFF */
   3128             if (i != 0) {
   3129                 /* debug thread <tid>,OFF */
   3130                 cli_out("Invalid thread ID\n");
   3131                 return CMD_FAIL;
   3132             }
   3133             p = 0;
   3134             *t_option = shBslThreadOptClrAll;
   3135         } else {
   3136             if (i != 0 && p == 0) {
   3137                 /* debug thread OFF,<tid>  */
   3138                 cli_out("Invalid thread ID combination\n");
   3139                 return CMD_FAIL;
   3140             }
   3141             if (isint(c)) {
   3142                 /* Check whether is: debug thread tid1,tid2 */
   3143                 p = parse_integer(c);
   3144             } else {
   3145                 cli_out("Invalid thread ID format\n");
   3146                 return CMD_FAIL;
   3147             }
   3148         }
   3149         thread_list->thread_list[thread_list->thread_count] = p;
   3150         thread_list->thread_count++;
   3151         i++;
   3152     } while (*tokstr != 0);
   3153 
   3154     return CMD_OK;
   3155 }
   3156 
   3157 char sh_debug_usage[] =
   3158     "\n\t"
   3159     "debug [show] [<layer_list>] [<source_list>] [<severity>|+|-|=]\n\t"
   3160     "Options:\n\t"
   3161     "show          display current settings\n\t"
   3162     "<layer_list>  one or more comma-separated layers\n\t"
   3163     "              (if omitted, then all layers)\n\t"
   3164     "<source_list> one or more comma-separated sources\n\t"
   3165     "              (if omitted, then all sources)\n\t"
   3166     "<severity>    Off, Fatal, Error, Warn, Info, Verbose\n\t"
   3167     "+             all messages\n\t"
   3168     "-             no messages\n\t"
   3169     "=             set to defaults\n"
   3170 #ifndef COMPILER_STRING_CONST_LIMIT
   3171     "Thread sensitive debug usage: \n\t"
   3172     "debug thread [off|<thread_list>] [<layer_list>] [<source_list>]\n\t"
   3173     "             [<severity>|+|-|=]\n\t"
   3174     "Options:\n\t"
   3175     "off           disable thread sensitive check\n\t"
   3176     "<thread_list> one or more comma-separated thread IDs\n\t"
   3177     "<layer_list>  one or more comma-separated layers\n\t"
   3178     "              (if omitted, then all layers)\n\t"
   3179     "<source_list> one or more comma-separated sources\n\t"
   3180     "              (if omitted, then all sources)\n\t"
   3181     "<severity>    Off, Fatal, Error, Warn, Info, Verbose\n\t"
   3182     "+             all messages\n\t"
   3183     "-             no messages\n\t"
   3184     "=             set to defaults\n"
   3185     "NOTE: When thread sensitive debug is enabled on any source, the thread \n"
   3186     "      information could be displayed by 'debug show'.\n"
   3187     "Other usages:\n\t"
   3188     "debug sink [<sink_id>] [EnableMIN=<severity>] [EnableMAX=<severity>]\n\t"
   3189     "           [Units=<unit-list>] [Ports=<port-list>] [eXtra=<param-value>]\n\t"
   3190     "           [PrefixMIN=<severity>] [PrefixMAX=<severity>] [PrefixFormat=<str>]\n\t"
   3191     "Options:\n\t"
   3192     "EnableMIN     minimum severity level for which this sink is enabled\n\t"
   3193     "EnableMAX     maximum severity level for which this sink is enabled\n\t"
   3194     "Units         unit numbers for which this sink is enabled\n\t"
   3195     "Ports         port numbers for which this sink is enabled\n\t"
   3196     "eXtra         parameter for which this sink is enabled (-1 to skip)\n\t"
   3197     "PrefixMIN     minimum severity level for prefixed log message\n\t"
   3198     "PrefixMAX     maximum severity level for prefixed log message\n\t"
   3199     "PrefixFormat  prefix format string\n\t"
   3200     "    The following format specifiers are supported\n\t"
   3201     "    %F - function name\n\t"
   3202     "    %f - file name\n\t"
   3203     "    %l - line number\n\t"
   3204     "    %u - unit number\n\t"
   3205     "    %p - port number\n\t"
   3206     "    %x - xtra parameter\n\t"
   3207     "    %L - layer of this log message source\n\t"
   3208     "    %S - source of this log message\n\t"
   3209     "    %s - severity level (string value) of this log message\n\t"
   3210     "    %t - time stamp (seconds since system start)\n\t"
   3211     "    %T - high resolution timestamp (micro seconds)\n\t"
   3212     "    %P - process or thread name\n\t"
   3213     "Omitting options will list all installed sinks\n"
   3214 #endif
   3215 ;
   3216 
   3217 cmd_result_t
   3218 sh_debug(int u, args_t *a)
   3219 /*
   3220  * Function:     
   3221  *      sh_debug
   3222  * Purpose:    
   3223  *      Set shell debug parameters.
   3224  * Parameters:    
   3225  *      u - unit number
   3226  *      a - arguments.
   3227  * Returns:    
   3228  *      CMD_OK or CMD_USAGE if no match found.
   3229  * Notes:
   3230  */
   3231 {
   3232     int rv = CMD_OK;
   3233     int idx;
   3234     sh_bsl_opt_t option = shBslOptSet;
   3235     char *sub_cmd;
   3236     char *arg1 = NULL;
   3237     char *arg2 = NULL;
   3238     char *arg3 = NULL;
   3239     bsl_layer_list_t layer_list;
   3240     bsl_source_list_t *source_list;
   3241     bsl_severity_t severity;
   3242     bsl_thread_list_t thread_list;
   3243     sh_bsl_thread_opt_t t_option = shBslThreadOptDisable;
   3244 
   3245     /* Check for sub-commands */
   3246     if ((sub_cmd = ARG_GET(a)) != NULL) {
   3247         if (sal_strcasecmp(sub_cmd, "show") == 0) {
   3248             option = shBslOptShow;
   3249         } else if (sal_strcasecmp(sub_cmd, "test") == 0) {
   3250             if ((arg1 = ARG_GET(a)) == NULL) {
   3251                 bsltest_list();
   3252                 return CMD_OK;
   3253             }
   3254             bsltest_run(sal_ctoi(arg1, NULL));
   3255             return CMD_OK;
   3256         } else if (sal_strcasecmp(sub_cmd, "sink") == 0) {
   3257             parse_table_t pt;
   3258             bslsink_sink_t tmp_sink, *cur_sink, *sink;
   3259             char *en_min, *en_max, *pre_min, *pre_max, *pre_cfg;
   3260             char *unit_str, *port_str;
   3261             int sink_id = 0;
   3262 
   3263             if ((arg1 = ARG_GET(a)) == NULL) {
   3264                 cli_out("Id   Name\n");
   3265                 do {
   3266                     sink = bslsink_sink_find_by_id(sink_id++);
   3267                     if (sink != NULL) {
   3268                         cli_out("%-4d %-12s\n",
   3269                                 sink->sink_id, sink->name);
   3270                     }
   3271                 } while (sink != NULL);
   3272                 return CMD_OK;
   3273             }
   3274             if (isint(arg1)) {
   3275                 sink_id = parse_integer(arg1);
   3276                 sink = bslsink_sink_find_by_id(sink_id);
   3277             } else {
   3278                 sink = bslsink_sink_find(arg1);
   3279             }
   3280             if (sink == NULL) {
   3281                 cli_out("%s: Sink not found: %s\n", ARG_CMD(a), arg1);
   3282                 return CMD_FAIL;
   3283             }
   3284 
   3285             /* Show sink settings if no additional parameters specified */
   3286             if (ARG_CUR(a) == NULL) {
   3287                 char range_str[32];
   3288                 bslsink_severity_range_t *range;
   3289 
   3290                 cli_out("%-12s %d\n", "Id:", sink->sink_id);
   3291                 cli_out("%-12s %s\n", "Name:", sink->name);
   3292                 range = &sink->enable_range;
   3293                 if (range->min == range->max) {
   3294                     sal_sprintf(range_str, "%s",
   3295                                 bsl_severity2str(range->min));
   3296                 } else {
   3297                     sal_sprintf(range_str, "%s..%s",
   3298                                 bsl_severity2str(range->min),
   3299                                 bsl_severity2str(range->max));
   3300                 }
   3301                 cli_out("%-12s %s\n", "Enable:", range_str);
   3302                 range = &sink->prefix_range;
   3303                 if (range->min == range->max) {
   3304                     sal_sprintf(range_str, "%s",
   3305                                 bsl_severity2str(range->min));
   3306                 } else {
   3307                     sal_sprintf(range_str, "%s..%s",
   3308                                 bsl_severity2str(range->min),
   3309                                 bsl_severity2str(range->max));
   3310                 }
   3311                 cli_out("%-12s %s, \"%s\"\n", "Prefix:", range_str,
   3312                         sink->prefix_format);
   3313                 sal_sprintf(range_str, "%-12s ", "Units:");
   3314                 sh_bsl_show_bit_range(u, range_str, sink->units,
   3315                                       BSLSINK_MAX_NUM_UNITS);
   3316                 sal_sprintf(range_str, "%-12s ", "Ports:");
   3317                 sh_bsl_show_bit_range(u, range_str, sink->ports,
   3318                                       BSLSINK_MAX_NUM_PORTS);
   3319                 cli_out("%-12s %d\n", "Parameter:", sink->xtra);
   3320                 return CMD_OK;
   3321             }
   3322 
   3323             /* Make a local copy of current sink */
   3324             cur_sink = sink;
   3325             sink = &tmp_sink;
   3326             sal_memcpy(sink, cur_sink, sizeof(*sink));
   3327 
   3328             parse_table_init(u, &pt);
   3329             parse_table_add(&pt, "EnableMIN", PQ_STRING, NULL, &en_min, 0);
   3330             parse_table_add(&pt, "EnableMAX", PQ_STRING, NULL, &en_max, 0);
   3331             parse_table_add(&pt, "Units", PQ_STRING, NULL, &unit_str, 0);
   3332             parse_table_add(&pt, "Ports", PQ_STRING, NULL, &port_str, 0);
   3333             parse_table_add(&pt, "eXtra", PQ_DFL|PQ_INT, 0, &sink->xtra, NULL);
   3334             parse_table_add(&pt, "PrefixMIN", PQ_STRING, NULL, &pre_min, 0);
   3335             parse_table_add(&pt, "PrefixMAX", PQ_STRING, NULL, &pre_max, 0);
   3336             parse_table_add(&pt, "PrefixFormat", PQ_STRING, NULL, &pre_cfg, 0);
   3337 
   3338             if (parse_arg_eq(a, &pt) < 0) {
   3339                 cli_out("%s: Invalid option: %s\n", ARG_CMD(a), ARG_CUR(a));
   3340                 parse_arg_eq_done(&pt);
   3341                 return CMD_USAGE;
   3342             }
   3343             rv = parse_severity_str(u, en_min, &sink->enable_range.min);
   3344             if (rv != 0) {
   3345                 cli_out("Invalid severity: %s\n", en_min);
   3346                 parse_arg_eq_done(&pt);
   3347                 return CMD_USAGE;
   3348             }
   3349             rv = parse_severity_str(u, en_max, &sink->enable_range.max);
   3350             if (rv != 0) {
   3351                 cli_out("Invalid severity: %s\n", en_max);
   3352                 parse_arg_eq_done(&pt);
   3353                 return CMD_USAGE;
   3354             }
   3355             rv = parse_bit_range(u, unit_str, sink->units,
   3356                                  BSLSINK_MAX_NUM_UNITS);
   3357             if (rv != 0) {
   3358                 cli_out("Invalid units: %s\n", unit_str);
   3359                 parse_arg_eq_done(&pt);
   3360                 return CMD_USAGE;
   3361             }
   3362             rv = parse_bit_range(u, port_str, sink->ports,
   3363                                  BSLSINK_MAX_NUM_PORTS);
   3364             if (rv != 0) {
   3365                 cli_out("Invalid ports: %s\n", port_str);
   3366                 parse_arg_eq_done(&pt);
   3367                 return CMD_USAGE;
   3368             }
   3369             rv = parse_severity_str(u, pre_min, &sink->prefix_range.min);
   3370             if (rv != 0) {
   3371                 cli_out("Invalid severity: %s\n", pre_min);
   3372                 parse_arg_eq_done(&pt);
   3373                 return CMD_USAGE;
   3374             }
   3375             rv = parse_severity_str(u, pre_max, &sink->prefix_range.max);
   3376             if (rv != 0) {
   3377                 cli_out("Invalid severity: %s\n", pre_max);
   3378                 parse_arg_eq_done(&pt);
   3379                 return CMD_USAGE;
   3380             }
   3381             if (pre_cfg != NULL && *pre_cfg) {
   3382                 if (sal_strlen(pre_cfg) >= sizeof(sink->prefix_format)) {
   3383                     cli_out("Prefix format string exceeds %d characters.\n",
   3384                             (int)sizeof(sink->prefix_format) - 1);
   3385                     parse_arg_eq_done(&pt);
   3386                     return CMD_FAIL;
   3387                 }
   3388                 sal_strcpy(sink->prefix_format, pre_cfg);
   3389             }
   3390             parse_arg_eq_done(&pt);
   3391             /* Make sure ranges are sane */
   3392             if (sink->enable_range.min > sink->enable_range.max) {
   3393                 sink->enable_range.min = sink->enable_range.max;
   3394             }
   3395             if (sink->prefix_range.min > sink->prefix_range.max) {
   3396                 sink->prefix_range.min = sink->prefix_range.max;
   3397             }
   3398             /* Update sink from local copy */
   3399             sal_memcpy(cur_sink, sink, sizeof(*cur_sink));
   3400             return CMD_OK;
   3401         } else if (sal_strcasecmp(sub_cmd, "thread") == 0) {
   3402             arg1 = ARG_GET(a);
   3403             memset(&thread_list, 0, sizeof(thread_list));
   3404             rv = sh_bsl_thread_parse(arg1, &thread_list, &t_option);
   3405             if (rv < 0) {
   3406                 return rv;
   3407             }
   3408             arg1 = NULL;
   3409         } else {
   3410             ARG_PREV(a);
   3411         }
   3412     } else {
   3413         cli_out("Available layers:\n");
   3414         for (idx = 0; idx < bslLayerCount; idx++) {
   3415             cli_out("%s ", bsl_layer2str(idx));
   3416         }
   3417         cli_out("\n");
   3418         return CMD_OK;
   3419     }    
   3420 
   3421     if (ARG_CNT(a) != 0 ) {
   3422         arg1 = ARG_GET(a);
   3423     }
   3424 
   3425     if (ARG_CNT(a) != 0 ) {
   3426         arg2  = ARG_GET(a);
   3427     }
   3428 
   3429     if (ARG_CNT(a) != 0 ) {
   3430         arg3  = ARG_GET(a);
   3431     }
   3432 
   3433     if (ARG_CNT(a) != 0 ) {
   3434         return CMD_USAGE;
   3435     }
   3436 
   3437     memset(&layer_list, 0, sizeof(layer_list));
   3438     source_list = sal_alloc(sizeof(bsl_source_list_t), "source_list");
   3439     if (source_list == NULL) {
   3440         return CMD_FAIL;
   3441     }
   3442     memset(source_list, 0, sizeof(bsl_source_list_t));
   3443     rv = sh_bsl_parse(arg1, arg2, arg3,
   3444                       &option, &layer_list, source_list, &severity);
   3445     if (rv < 0) {
   3446         sal_free(source_list);
   3447         return rv;
   3448     }
   3449 
   3450     if (t_option != shBslThreadOptDisable) {
   3451         if (t_option == shBslThreadOptClrAll) {
   3452             /* debug thread off. Disable console thread check */
   3453             (void)bslcons_thread_check_enable(0);
   3454         } else {
   3455             (void)bslcons_thread_check_enable(1);
   3456         }
   3457         if (arg1 == NULL){
   3458             /* Check whether is: debug thread off/tid */
   3459             rv = sh_bsl_thread_cfg(u, &layer_list, source_list, &thread_list);
   3460             sal_free(source_list);
   3461             return rv;
   3462         }
   3463     }
   3464 	
   3465     if (option == shBslOptShow) {
   3466         rv = sh_bsl_show(u, &layer_list, source_list, severity);
   3467     } else {
   3468         rv = sh_bsl_cfg(u, option, &layer_list, source_list, severity);
   3469     }
   3470     if (rv < 0) {
   3471         sal_free(source_list);
   3472         return rv;
   3473     }
   3474 
   3475     if (t_option != shBslThreadOptDisable) {
   3476         /* Config the thread information to layer/source.*/
   3477         rv = sh_bsl_thread_cfg(u, &layer_list, source_list, &thread_list);
   3478     } else {
   3479         /* Thread information displayed in debug show */
   3480         if ((option == shBslOptShow) && bslcons_thread_check_is_enabled()) {
   3481             rv = sh_bsl_thread_show(u, &layer_list, source_list);
   3482         }
   3483     }
   3484 
   3485     sal_free(source_list);
   3486 
   3487 	return rv;
   3488 }
   3489 
   3490 
   3491 #ifndef NO_SAL_APPL
   3492 
   3493 char sh_log_usage[] =
   3494     "Parameters: [file=<filename>] [append=<yes|no>]\n\t"
   3495     "[quiet=<yes|no>] [on|off]\n\t"
   3496     "Set a logfile and/or turn on or off logging. When a file is set\n\t"
   3497     "for logging an implicit \"log on\" is assumed.\n";
   3498 
   3499 
   3500 cmd_result_t
   3501 sh_log(int u, args_t *a)
   3502 /*
   3503  * Function:    sh_log
   3504  * Purpose:     Enable/disable logging to a file.
   3505  * Parameters:  u - unit #
   3506  *              a - argument list.
   3507  * Returns:     CMD_OK or CMD_FAIL if unable to open log file.
   3508  */
   3509 {
   3510     cmd_result_t rv = CMD_FAIL;
   3511     char *file, *cur_file;
   3512     int append;
   3513     int quiet;
   3514     int new_file;
   3515     char *c;
   3516     parse_table_t pt;
   3517     int allocation_done = 0;
   3518 
   3519     COMPILER_REFERENCE(u);
   3520     cur_file = NULL;
   3521     memset(&pt,0,sizeof(pt));
   3522     if (bslfile_name() == NULL)
   3523     {
   3524         cur_file = sal_strdup(LOG_DEFAULT_FILE);
   3525     }
   3526     else
   3527     {
   3528         cur_file = sal_strdup(bslfile_name());
   3529     }
   3530 
   3531     if (ARG_CNT(a) == 0)
   3532     {
   3533         cli_out("Logging to file %s: %s\n",
   3534                 cur_file,
   3535                 bslfile_is_enabled() ? "enabled" : "disabled");
   3536         rv = CMD_OK;
   3537         goto done;
   3538     }
   3539 
   3540     parse_table_init(u, &pt);
   3541     parse_table_add(&pt, "File", PQ_STRING, cur_file, &file, 0);
   3542     parse_table_add(&pt, "Append", PQ_BOOL, (void *)1, &append, 0);
   3543     parse_table_add(&pt, "Quiet", PQ_BOOL, (void *)0, &quiet, 0);
   3544 
   3545     if (parse_arg_eq(a, &pt) < 0)
   3546     {
   3547         cli_out("%s: Invalid option: %s\n", ARG_CMD(a), ARG_CUR(a));
   3548         rv = CMD_USAGE;
   3549         goto done;
   3550     }
   3551 
   3552     if ((c = ARG_GET(a)) == NULL)
   3553     {
   3554         c = "on";        /* Default is to turn logging on */
   3555     }
   3556 
   3557     if (!sal_strcasecmp("on", c))
   3558     {
   3559         if (file == NULL || *file == 0)
   3560         {
   3561             /*
   3562              * Make a copy of the filename. This arg will
   3563              * be freed as part of parse_arg_eq_done.
   3564              */
   3565             file = sal_strdup(cur_file);
   3566             if(file != NULL) {
   3567                 allocation_done = 1;
   3568             }
   3569         }
   3570         new_file = 0;
   3571         if (file == NULL || sal_strcmp(cur_file, file) != 0 ||
   3572             bslfile_name() == NULL ||
   3573             append == 0)
   3574         {
   3575             new_file = 1;
   3576         }
   3577         if (new_file)
   3578         {
   3579             if (file == NULL || bslfile_open(file, append) < 0)
   3580             {
   3581                 cli_out("%s: Error: Could not start logging\n", ARG_CMD(a));
   3582                 rv = CMD_FAIL;
   3583                 goto done;
   3584             }
   3585         }
   3586         if (bslfile_enable(TRUE) < 0)
   3587         {
   3588             cli_out("%s: Error: Could not start logging\n", ARG_CMD(a));
   3589             rv = CMD_FAIL;
   3590             goto done;
   3591         }
   3592         if (!quiet)
   3593         {
   3594             cli_out("File logging %s to %s\n",
   3595                     new_file ? "started" : "continued",
   3596                     file);
   3597         }
   3598         rv = CMD_OK;
   3599         goto done;
   3600     }
   3601     if (!sal_strcasecmp("off", c))
   3602     {
   3603         if (cur_file == NULL || ! bslfile_is_enabled())
   3604         {
   3605             cli_out("File logging is not active.\n");
   3606             rv = CMD_FAIL;
   3607             goto done;
   3608         }
   3609         if (bslfile_enable(FALSE) < 0)
   3610         {
   3611             cli_out("%s: Error: Could not stop logging to %s\n",
   3612                     ARG_CMD(a), cur_file);
   3613             rv = CMD_FAIL;
   3614             goto done;
   3615         }
   3616         if (!quiet)
   3617         {
   3618             cli_out("File logging to %s stopped.\n", cur_file);
   3619         }
   3620         rv = CMD_OK;
   3621         goto done;
   3622     }
   3623     rv = CMD_USAGE;
   3624 done:
   3625     if (cur_file != NULL)
   3626     {
   3627         sal_free(cur_file);
   3628         cur_file = NULL;
   3629     }
   3630     if (allocation_done)
   3631     {
   3632         sal_free(file);
   3633     }
   3634     parse_arg_eq_done(&pt);
   3635     return(rv);
   3636 }
   3637 
   3638 
   3639 char sh_console_usage[] =
   3640     "Parameters: on|off\n\t"
   3641     "Turn on or off output to the console. This does not affect current\n\t"
   3642     "logging\n";
   3643 
   3644 cmd_result_t
   3645 sh_console(int u, args_t *a)
   3646 /*
   3647  * Function:     sh_console
   3648  * Purpose:    Control various console options.
   3649  * Parameters:    u - unit number (ignored)
   3650  *        a - arguments
   3651  * Returns:    CMD_USAGE/CMD_OK
   3652  */
   3653 {
   3654     char *c;
   3655 
   3656     COMPILER_REFERENCE(u);
   3657 
   3658     if (ARG_CNT(a) != 1) {
   3659         return(CMD_USAGE);
   3660     }
   3661     c = ARG_GET(a);
   3662 
   3663     if (!sal_strcasecmp("on", c)) {
   3664         bslcons_enable(1);
   3665     } else if (!sal_strcasecmp("off", c)) {
   3666         bslcons_enable(0);
   3667     } else {
   3668         return(CMD_USAGE);
   3669     }
   3670     return(CMD_OK);
   3671 }
   3672 
   3673 #ifdef BSL_TRACE_INCLUDE
   3674 char sh_trace_usage[] =
   3675     "\trace dump|clear|config\n\t"
   3676     "trace dump [Nentry=n]\n\t"
   3677     "\t(displays last n entries)\n\t"
   3678     "\t(if omitted, then dump all)\n\t"
   3679     "trace clear\n\t"
   3680     "trace config [Nentry=n] [SiZe=m]\n\t"
   3681     "\t(if no parameters, display current)\n\t"
   3682     "Warning: Config change clears the buffer\n";
   3683 
   3684 cmd_result_t
   3685 sh_trace(int u, args_t *a)
   3686 /*
   3687  * Function:     sh_trace
   3688  * Purpose:    Control various trace buffer options.
   3689  * Parameters:    u - unit number (ignored)
   3690  *        a - arguments
   3691  * Returns:    CMD_USAGE/CMD_OK
   3692  */
   3693 {
   3694     char *cmd;
   3695     parse_table_t pt;
   3696     int i;
   3697     int nentry = -1;
   3698     int size = -1;
   3699 
   3700     COMPILER_REFERENCE(u);
   3701 
   3702     if ((cmd = ARG_GET(a)) == NULL) {
   3703         return(CMD_USAGE);
   3704     }
   3705     if (!sal_strcasecmp("dump", cmd)) {
   3706         parse_table_init(u, &pt);
   3707         parse_table_add(&pt, "Nentry", PQ_DFL | PQ_INT, (void *)(-1), &nentry, 0);
   3708         if (parse_arg_eq(a, &pt) <= 0) {
   3709             /* Just Display All.. */
   3710         }
   3711         parse_arg_eq_done(&pt);
   3712         bsltrace_print(nentry);
   3713     } else if (!sal_strcasecmp("clear", cmd)) {
   3714         bsltrace_clear();
   3715     } else if (!sal_strcasecmp("config", cmd)) {
   3716         parse_table_init(u, &pt);
   3717         parse_table_add(&pt, "Nentry", PQ_DFL | PQ_INT, (void *)(-1), &nentry, 0);
   3718         parse_table_add(&pt, "SiZe", PQ_DFL | PQ_INT, (void *)(-1), &size, 0);
   3719         if (parse_arg_eq(a, &pt) <= 0) {
   3720             /* No Arguments. Just display the current config */
   3721             i = bsltrace_config_get(&nentry, &size);
   3722             parse_arg_eq_done(&pt);
   3723             cli_out("Trace Buffer length=%d chars, Used %d out of %d entries\n", size, i, nentry);
   3724             return(CMD_OK);
   3725         }
   3726         parse_arg_eq_done(&pt);
   3727         bsltrace_config_set(nentry, size);
   3728     } else {
   3729         return(CMD_USAGE);
   3730     }
   3731     return(CMD_OK);
   3732 }
   3733 #endif /* BSL_TRACE_INCLUDE */
   3734 
   3735 char sh_reboot_usage[] =
   3736     "Parameters: none\n\t"
   3737     "Reboots the processor\n";
   3738 
   3739 cmd_result_t
   3740 sh_reboot(int u, args_t *a)
   3741 /*
   3742  * Function:     sh_reboot
   3743  * Purpose:    Reboot the system.
   3744  * Parameters:    u - unit number
   3745  *        a - arguments [expects none].
   3746  * Returns:    CMD_FAIL or does not return.
   3747  */
   3748 {
   3749     COMPILER_REFERENCE(u);
   3750 
   3751     if (ARG_CNT(a)) {
   3752     return(CMD_USAGE);
   3753     }
   3754     sal_reboot();
   3755     return(CMD_OK);
   3756 }
   3757 
   3758 #endif /* NO_SAL_APPL */
   3759 
   3760 
   3761 #ifndef BCM_PLATFORM_STRING
   3762 #ifdef KEYSTONE
   3763 #define BCM_PLATFORM_STRING "KEYSTONE"
   3764 #else
   3765 #define BCM_PLATFORM_STRING "unknown"
   3766 #endif
   3767 #endif
   3768 
   3769 void
   3770 sh_print_version(int verbose)
   3771 /*
   3772  * Function:     sh_print_version
   3773  * Purpose:    Prints current version of firmware.
   3774  * Parameters:    verbose - includes more info if TRUE
   3775  * Returns:    Nothing
   3776  */
   3777 {
   3778     int length = 4;
   3779     char build_year[5];
   3780 
   3781     sal_strncpy(build_year, _build_datestamp, length);
   3782     build_year[length] = '\0';
   3783     cli_out("Broadcom Command Monitor: "
   3784             "Copyright (c) 1998-%s Broadcom\n", build_year);
   3785     cli_out("Release: %s built %s (%s)\n",
   3786             _build_release, _build_datestamp, _build_date);
   3787     cli_out("From %s@%s:%s\n",
   3788             _build_user, _build_host, _build_tree);
   3789     cli_out("Platform: %s\n", BCM_PLATFORM_STRING); 
   3790     cli_out("OS: %s\n", sal_os_name() ? sal_os_name() : "unknown"); 
   3791 
   3792     if (verbose) {
   3793 #if ( defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT))
   3794     unsigned int i, j;
   3795 #endif
   3796 #if ((defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT)))
   3797         char *phy_list[64];
   3798         int phys_in_list, phy_list_base, rv;
   3799 
   3800 #endif
   3801 
   3802 #if defined(BOOT_LINE_ADRS) && !defined(NO_SAL_APPL)
   3803     cli_out("Boot string: %s\n", (char *)BOOT_LINE_ADRS);
   3804 #endif
   3805 
   3806 
   3807 
   3808 #if (defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT))
   3809     for (i = 0; i < SOC_NUM_SUPPORTED_CHIPS; i += 4) {
   3810         cli_out("%s", i == 0 ? "Chips:" : "      ");
   3811         for (j = i; j < i + 4 && j < SOC_NUM_SUPPORTED_CHIPS; j++) {
   3812         if (SOC_DRIVER_ACTIVE(j)) {
   3813             cli_out(" %s%s",
   3814                     SOC_CHIP_NAME(soc_base_driver_table[j]->type),
   3815                     j < SOC_NUM_SUPPORTED_CHIPS - 1 ? "," : "");
   3816         }
   3817         }
   3818         cli_out("\n");
   3819     }
   3820 #endif
   3821 
   3822 #if (defined(BCM_ESW_SUPPORT) || defined(BCM_SAND_SUPPORT))
   3823 
   3824         phy_list_base = 0;
   3825         cli_out("PHYs: ");
   3826         
   3827         do {
   3828 
   3829             phys_in_list = phy_list_base;
   3830             rv = soc_phy_list_get(phy_list,
   3831                                   COUNTOF(phy_list), &phys_in_list);
   3832            
   3833             /* Save the base for the next iteration if 
   3834                there are more PHYs in the list. */
   3835             phy_list_base += phys_in_list;
   3836            
   3837             if (!((rv == SOC_E_FULL) || (rv == SOC_E_NONE))) {
   3838                 break;
   3839             }
   3840             /* Print the PHY list - 2 step 
   3841                4 PHYs in one row */
   3842             for (i = 0; i < phys_in_list; i += 4) {
   3843                 for (j = i; j < i + 4 && j < phys_in_list; j++) {
   3844                     cli_out(" %s%s",
   3845                             phy_list[j],
   3846                             j < phys_in_list - 1 ? "," : "");
   3847                 }
   3848                 cli_out("\n   ");
   3849             }
   3850         } while (rv == SOC_E_FULL); 
   3851    
   3852         cli_out("\n");
   3853 
   3854     
   3855 #endif 
   3856 
   3857    }
   3858 
   3859 
   3860 }
   3861 char sh_clear_screen_usage[] = 
   3862     "Parameters: none\n\t"
   3863     "clears terminal output\n";
   3864 
   3865 cmd_result_t
   3866 sh_clear_screen(int u, args_t *a)
   3867 /*
   3868  * Function:     sh_clear_screen
   3869  * Purpose:    Clears screen
   3870  * Parameters:    u - Unit number (ignored)
   3871  *        a - pointer to arguments. (ignored)
   3872  * Returns:    CMD_USAGE/CMD_OK
   3873  */
   3874 {
   3875     COMPILER_REFERENCE(u);
   3876     sal_printf("\033[2J\033[1;1H");
   3877     return(CMD_OK);
   3878 }
   3879 
   3880 char sh_version_usage[] =
   3881     "Parameters: none\n\t"
   3882     "Prints current firmware version and build status\n";
   3883 
   3884 cmd_result_t
   3885 sh_version(int u, args_t *a)
   3886 /*
   3887  * Function:     sh_version
   3888  * Purpose:    Print version of the current socdiag shell/driver
   3889  * Parameters:    u - Unit number (ignored)
   3890  *        a - pointer to arguments.
   3891  * Returns:    CMD_USAGE/CMD_OK
   3892  */
   3893 {
   3894     COMPILER_REFERENCE(u);
   3895 
   3896     if (ARG_CNT(a)) {
   3897     return(CMD_USAGE);
   3898     }
   3899     sh_print_version(TRUE);
   3900     return(CMD_OK);
   3901 }
   3902 
   3903 char sh_probe_usage[] =
   3904     "Parameters: <None>\n\t"
   3905     "Probe for available SOC units\n";
   3906 
   3907 cmd_result_t
   3908 sh_probe(int u, args_t *a)
   3909 /*
   3910  * Function:     sh_probe
   3911  * Purpose:    Probe for StrataSwitch Devices.
   3912  * Parameters:    u - unit (ignored)
   3913  *        a - arguments (none)
   3914  * Returns:    CMD_USAGE/CMD_FAIL/CMD_OK
   3915  */
   3916 {
   3917     COMPILER_REFERENCE(u);
   3918 
   3919     if (ARG_CNT(a)) {
   3920     return(CMD_USAGE);
   3921     }
   3922     if (sysconf_probe() < 0) {
   3923     cli_out("%s: Probe failed\n", ARG_CMD(a));
   3924     return(CMD_FAIL);
   3925     } else {
   3926     cli_out("%s: found %d unit%s\n", ARG_CMD(a), soc_ndev,
   3927             soc_ndev==1 ? "" : "s");
   3928     var_set_integer("units", soc_ndev, FALSE, FALSE);
   3929     }
   3930     return(CMD_OK);
   3931 }
   3932 
   3933 char sh_attach_usage[] =
   3934     "Parameters: [Unit #] ...\n\t"
   3935     "If no parameters are given, a current list of attached devices\n\t"
   3936     "is printed. Otherwise, each parameter is considered a unit # and\n\t"
   3937     "an attempt is made to attached it.\n";
   3938 
   3939 cmd_result_t
   3940 sh_attach(int unit, args_t *a)
   3941 /*
   3942  * Function:     sh_attach
   3943  * Purpose:    Attach a soc device, and make it the default device.
   3944  * Parameters:    unit - currently attached unit (-1 if none)
   3945  *        a - args, expects a list of unit #'s to attach
   3946  * Returns:    CMD_FAIL/CMD_OK
   3947  */
   3948 {
   3949     char    *c;
   3950     int        u;
   3951     int         dev;
   3952     uint32 dev_idx;
   3953     uint8 found = 0;
   3954 
   3955     if (soc_ndev < 0) {
   3956         cli_out("%s: Probe command not yet performed\n", ARG_CMD(a));
   3957         return CMD_FAIL;
   3958     }
   3959 
   3960     if (!ARG_CNT(a)) {            /* No parameters */
   3961 
   3962     if (soc_ndev == 0) {
   3963         cli_out("%s: No units probed\n", ARG_CMD(a));
   3964     }
   3965 
   3966     for (dev = 0; dev < SOC_MAX_NUM_DEVICES; dev++) {
   3967         if (CMDEV(dev).dev.info) {
   3968             cli_out("%s: Unit %d (%s): %sattached%s\n",
   3969                     ARG_CMD(a),
   3970                     SOC_NDEV_IDX2DEV(dev), soc_dev_name(SOC_NDEV_IDX2DEV(dev)),
   3971                     soc_attached(SOC_NDEV_IDX2DEV(dev)) ? "" : "not ",
   3972                     (unit == SOC_NDEV_IDX2DEV(dev)) ? " (current unit)" : "");
   3973         }
   3974     }
   3975 
   3976         return(CMD_OK);
   3977     }
   3978 
   3979     while ((c = ARG_GET(a)) != NULL) {
   3980         if (*c == '*') {  /* Attach (report) all devices */
   3981             for (dev = 0; dev < SOC_MAX_NUM_DEVICES; dev++) {
   3982                 if (CMDEV(dev).dev.info) {
   3983                     if (!soc_attached(SOC_NDEV_IDX2DEV(dev))) {
   3984                         if (sysconf_attach(SOC_NDEV_IDX2DEV(dev)) < 0) {
   3985                             cli_out("%s: Error: Could not attach unit: %d\n",
   3986                                     ARG_CMD(a), SOC_NDEV_IDX2DEV(dev));
   3987                             return(CMD_FAIL);
   3988                         }
   3989                     } else {
   3990                         cli_out("Unit %d is attached\n", SOC_NDEV_IDX2DEV(dev));
   3991                     }
   3992                 }
   3993             } /* end of for loop */
   3994             return CMD_OK;
   3995         }
   3996         if (!isint(c)) {
   3997             cli_out("%s: Error: Invalid unit #: %s\n", ARG_CMD(a), c);
   3998             return(CMD_FAIL);
   3999         }
   4000         u = parse_integer(c);
   4001         for(dev_idx = 0; dev_idx < soc_ndev ; ++dev_idx) {
   4002             if(SOC_NDEV_IDX2DEV(dev_idx) == u) {
   4003                 found = 1;
   4004                 break;
   4005             }
   4006         }
   4007         if (!found) {
   4008             cli_out("%s: Error: Unit number out of range (%d - %d)\n",
   4009                     ARG_CMD(a), 0, soc_ndev - 1);
   4010             return(CMD_FAIL);
   4011         } else if (soc_attached(u)) {
   4012             cli_out("%s: Error: Unit already attached: %d\n", ARG_CMD(a), u);
   4013             return(CMD_FAIL);
   4014         } else if (sysconf_attach(u) < 0) {
   4015             cli_out("%s: Error: Could not attach unit: %d\n", ARG_CMD(a), u);
   4016             return(CMD_FAIL);
   4017         } else if (unit < 0) {        /* No current unit */
   4018             sh_swap_unit_vars(u);    /* First unit attached */
   4019         }
   4020     }
   4021 
   4022     return(CMD_OK);
   4023 }
   4024 
   4025 static    cmd_result_t
   4026 sh_do_detach(int u, args_t *a)
   4027 /*
   4028  * Function:     sh_do_detach
   4029  * Purpose:    Detach the specified SOC unit.
   4030  * Parameters:    u - unit number to detach.
   4031  *        a - pointer to arguments (used only for "cmd" error msg.
   4032  * Returns:    CMD_OK - done, CMD_FAIL - soc device not valid/attached.
   4033  */
   4034 {
   4035     if (!sh_check_attached(ARG_CMD(a), u)) {
   4036     return(CMD_FAIL);
   4037     } else if (sysconf_detach(u) < 0) {
   4038     cli_out("%s: Error: detaching unit %d\n", ARG_CMD(a), u);
   4039     return(CMD_FAIL);
   4040     } else {
   4041     return(CMD_OK);
   4042     }
   4043 }
   4044 
   4045 char sh_detach_usage[] =
   4046     "Parameters: [unit #] ...\n\t"
   4047     "If no parameters are given, the default unit is detached.\n\t"
   4048     "If one or more units are specified, each is detached.\n";
   4049 
   4050 cmd_result_t
   4051 sh_detach(int u, args_t *a)
   4052 /*
   4053  * Function:     sh_detach
   4054  * Purpose:    Detach one or more SOC devices.
   4055  * Parameters:    u - unit number to detach (if no parameters given)
   4056  *        a - pointer to args (list of units to detach).
   4057  * Returns:    CMD_OK - done
   4058  *        CMD_FAIL - invalid unit # given.
   4059  */
   4060 {
   4061     cmd_result_t rv = CMD_OK;
   4062     char *c;
   4063     int unit;
   4064 
   4065     if (!ARG_CNT(a)) {            /* Use default unit # */
   4066         if (soc_attached(u)) {
   4067             var_unset(SOC_CHIP_STRING(u), FALSE, TRUE, FALSE);
   4068             var_unset(soc_dev_name(u), FALSE, TRUE, FALSE);
   4069         }
   4070         return(sh_do_detach(u, a));
   4071     }
   4072     while ((CMD_OK == rv) && (c = ARG_GET(a))) {
   4073         if (isint(c)) {
   4074             unit = parse_integer(c);
   4075             if (u == unit) { 
   4076                 var_unset(SOC_CHIP_STRING(u), FALSE, TRUE, FALSE);
   4077                 var_unset(soc_dev_name(u), FALSE, TRUE, FALSE);
   4078             }
   4079             rv = sh_do_detach(unit, a);
   4080         } else {
   4081             cli_out("%s: Error: Invalid unit: %s\n", ARG_CMD(a), c);
   4082             rv = CMD_FAIL;
   4083         }
   4084     }
   4085     return(rv);
   4086 }
   4087 
   4088 char sh_echo_usage[] =
   4089     "Parameters: [-n] <Any text>\n\t"
   4090     "Echo whatever follows on command line, followed by a newline.\n\t"
   4091     "The newline may be suppressed by using the -n option.\n";
   4092 
   4093 /*ARGSUSED*/
   4094 cmd_result_t
   4095 sh_echo(int u, args_t *a)
   4096 /*
   4097  * Function:     sh_echo
   4098  * Purpose:    Echo command input
   4099  * Parameters:    u - unit number, ignored
   4100  *        a - pointer to args.
   4101  * Returns:    CMD_OK.
   4102  */
   4103 {
   4104     char    *c;
   4105     int        suppress_nl = FALSE;
   4106 
   4107 
   4108     COMPILER_REFERENCE(u);
   4109 
   4110     c = ARG_GET(a);
   4111     if (c != NULL && sal_strcmp(c, "-n") == 0) {
   4112     suppress_nl = TRUE;
   4113     c = ARG_GET(a);
   4114     }
   4115 
   4116     while (c != NULL) {
   4117     cli_out("%s", c);
   4118     c = ARG_GET(a);
   4119     if (c != NULL) {
   4120         cli_out(" ");
   4121     }
   4122     }
   4123     if (!suppress_nl) {
   4124     cli_out("\n");
   4125     }
   4126     return(CMD_OK);
   4127 }
   4128 
   4129 char sh_noecho_usage[] =
   4130     "Parameters: <Any text>\n\t"
   4131 "Ignore whatever follows on command line\n";
   4132 
   4133 /*ARGSUSED*/
   4134 cmd_result_t
   4135 sh_noecho(int u, args_t *a)
   4136 /*
   4137  * Function:     sh_noecho
   4138  * Purpose:    ignore command input
   4139  * Parameters:    u - unit number, ignored
   4140  *        a - pointer to args.
   4141  * Returns:    CMD_OK.
   4142  */
   4143 {
   4144     char    *c;
   4145     COMPILER_REFERENCE(u);
   4146 
   4147     while ((c = ARG_GET(a)) != NULL) {
   4148     }
   4149     return(CMD_OK);
   4150 }
   4151 
   4152 #ifndef NO_SAL_APPL
   4153 
   4154 char sh_pause_usage[] =
   4155     "Parameters: [-x] <Any text>\n\t"
   4156     "Echo whatever follows on the command line, then prompt to\n\t"
   4157     "hit SPACE to continue or Q to quit.  On quit, the pause command\n\t"
   4158     "fails (causing the executing script to terminate).  The -x option\n\t"
   4159     "requires the user to press x instead of SPACE to continue.\n";
   4160 
   4161 cmd_result_t
   4162 sh_pause(int u, args_t *a)
   4163 /*
   4164  * Function:     sh_pause
   4165  * Purpose:    Suspend input and wait for confirmation to continue.
   4166  * Parameters:    u - unit # (ignored)
   4167  *        a - pointer to arguments.
   4168  * Returns:    CMD_OK - enter hit
   4169  *        CMD_FAIL - some other input such as "Q".
   4170  */
   4171 {
   4172     cmd_result_t    rv = CMD_OK;
   4173     char        *c;
   4174     int            ch, cont_ch = ' ';
   4175     char        prompt[80];
   4176 
   4177     c = ARG_CUR(a);
   4178 
   4179     if (c != NULL && c[0] == '-' && c[1] != 0 && c[2] == 0) {
   4180     cont_ch = c[1];
   4181     ARG_NEXT(a);
   4182     }
   4183 
   4184     if (islower(cont_ch)) {
   4185     cont_ch = sal_toupper(cont_ch);
   4186     }
   4187 
   4188     sh_echo(u, a);            /* Print out args */
   4189    /* coverity[secure_coding] */
   4190     sal_strcpy(prompt, SAL_VT100_SO "Hit ");
   4191 
   4192     if (cont_ch == ' ') {
   4193     /* coverity[secure_coding] */   
   4194     sal_strcat(prompt, "SPACE");
   4195     } else {
   4196     c = prompt + sal_strlen(prompt);
   4197     c[0] = cont_ch;
   4198     c[1] = 0;
   4199     }
   4200 
   4201     /* coverity[secure_coding] */
   4202     sal_strcat(prompt, " to continue, Q to quit" SAL_VT100_SE);
   4203 
   4204     for (;;) {
   4205     if ((ch = sal_readchar(prompt)) < 0) {
   4206         rv = CMD_FAIL;
   4207         break;
   4208     }
   4209 
   4210     cli_out("\r" SAL_VT100_CE);
   4211 
   4212     if (islower(ch)) {
   4213         ch = sal_toupper(ch);
   4214     }
   4215 
   4216     if (ch == 'Q' || ch == '\033') {    /* ESC */
   4217         rv = CMD_FAIL;
   4218         break;
   4219     }
   4220 
   4221     if (ch == cont_ch) {
   4222         break;
   4223     }
   4224 
   4225     cli_out("\007");
   4226     }
   4227 
   4228     return(rv);
   4229 }
   4230 
   4231 #endif /* NO_SAL_APPL */
   4232 
   4233 void sal_mutex_dbg_dump(void);
   4234 
   4235 char sh_sleep_usage[] =
   4236     "Parameters: [quiet] [seconds [usec]]\n\t"
   4237     "If quiet is specified, no output is generated, otherwise, the\n\t"
   4238     "message \"sleeping for # seconds\" is printed. Seconds specifies\n\t"
   4239     "the number of seconds to sleep.  Usec specifies an additional\n\t"
   4240     "number of microseconds to sleep (0-999999).\n";
   4241 
   4242 /*ARGSUSED*/
   4243 cmd_result_t
   4244 sh_sleep(int u, args_t *a)
   4245 /*
   4246  * Function:     sh_sleep
   4247  * Purpose:    Put CLI task to sleep for some amount of time.
   4248  * Parameters:    u - unit # (ignored).
   4249  * Returns:    CMD_OK
   4250  */
   4251 {
   4252     int sec = 1, usec = 0, quiet = 0;
   4253     char *c = ARG_GET(a);
   4254 
   4255     COMPILER_REFERENCE(u);
   4256 
   4257     if (c && !sal_strcasecmp(c, "quiet")) {
   4258     quiet = 1;
   4259     c = ARG_GET(a);
   4260     }
   4261 
   4262 
   4263     if (c) {
   4264     if (! isint(c) || (sec = parse_integer(c)) < 0) {
   4265         return CMD_USAGE;
   4266     }
   4267     c = ARG_GET(a);
   4268     }
   4269 
   4270     if (c) {
   4271     if (! isint(c) || (usec = parse_integer(c)) < 0) {
   4272         return CMD_USAGE;
   4273     }
   4274     c = ARG_GET(a);
   4275     }
   4276 
   4277     if (c) {
   4278     return CMD_USAGE;
   4279     }
   4280 
   4281     if (! quiet) {
   4282     if (usec) {
   4283         cli_out("Sleeping for %d.%06d seconds\n",
   4284                 sec + usec / 1000000, usec % 1000000);
   4285     } else {
   4286         cli_out("Sleeping for %d second%s\n", sec, sec > 1 ? "s" : "");
   4287     }
   4288     }
   4289 
   4290     sal_sleep(sec);
   4291     sal_usleep(usec);
   4292 
   4293     return CMD_OK;
   4294 }
   4295 
   4296 char sh_delay_usage[] =
   4297     "Parameters: usec\n\t"
   4298     "Cause the CLI task to busy-wait for a specified number of\n\t"
   4299     "microseconds.  The actual amount of delay is only approximate.\n";
   4300 
   4301 /*ARGSUSED*/
   4302 cmd_result_t
   4303 sh_delay(int u, args_t *a)
   4304 /*
   4305  * Function:     sh_delay
   4306  * Purpose:    Make CLI task busy-wait for some amount of time.
   4307  * Parameters:    u - unit # (ignored).
   4308  * Returns:    CMD_OK
   4309  */
   4310 {
   4311     uint32        usec;
   4312     char        *c;
   4313 
   4314     COMPILER_REFERENCE(u);
   4315 
   4316     if ((c = ARG_GET(a)) == NULL || !isint(c)) {
   4317     return CMD_USAGE;
   4318     }
   4319 
   4320     usec = parse_integer(c);
   4321 
   4322     sal_udelay(usec);
   4323 
   4324     return CMD_OK;
   4325 }
   4326 
   4327 #ifndef NO_SAL_APPL
   4328 
   4329 char sh_shell_usage[] =
   4330     "Parameters: None\n\t"
   4331     "Invoke a platform dependent shell. This shell exits when the shell\n\t"
   4332     "exits\n";
   4333 
   4334 /*ARGSUSED*/
   4335 cmd_result_t
   4336 sh_shell(int u, args_t *a)
   4337 /*
   4338  * Function:     sh_shell
   4339  * Purpose:    Call "sal_shell" to do whatever the shell is supposed to.
   4340  * Parameters:    u - unit number (ignored)
   4341  *        a - pointer to args
   4342  * Returns:    CMD_OK
   4343  */
   4344 {
   4345     COMPILER_REFERENCE(u);
   4346 
   4347     if (ARG_CNT(a)) {
   4348     return(CMD_USAGE);
   4349     }
   4350     sal_shell();
   4351     return(CMD_OK);
   4352 }
   4353 #endif
   4354 
   4355 
   4356 #ifndef NO_SAL_APPL
   4357 
   4358 char sh_ls_usage[] =
   4359     "Parameters: <file> ...\n\t"
   4360     "Invoke a platform \"ls\" command, useful to see RC files that may\n\t"
   4361     "be invoked if a command does not match\n";
   4362 
   4363 cmd_result_t
   4364 sh_ls(int u, args_t *a)
   4365 /*
   4366  * Function:    sh_ls
   4367  * Purpose: Perform an "ls" command (platform dependent).
   4368  * Parameters:  u - unit number (ignored)
   4369  *      a - arguments, a list of directories to do an ls in.
   4370  * Returns: CMD_OK
   4371  */
   4372 {
   4373     char    *c, *flags = NULL;
   4374 
   4375     COMPILER_REFERENCE(u);
   4376 
   4377     c = ARG_GET(a);
   4378 
   4379     if (c != NULL && c[0] == '-') {
   4380         flags = c;
   4381         c = ARG_GET(a);
   4382     }
   4383 
   4384     if (c == NULL)
   4385         c = ".";
   4386 
   4387     while (c != NULL) {
   4388         sal_ls(c, flags);
   4389         c = ARG_GET(a);
   4390     }
   4391 
   4392     return(CMD_OK);
   4393 }
   4394 
   4395 char sh_pwd_usage[] =
   4396     "Parameters: <None>\n\t"
   4397     "Print the current platform dependent working directory\n";
   4398 
   4399 /*ARGSUSED*/
   4400 cmd_result_t
   4401 sh_pwd(int u, args_t *a)
   4402 /*
   4403  * Function:     sh_pwd
   4404  * Purpose:    Print the current working directory (Platform dependent).
   4405  * Parameters:    u - unit 3 (ignored)
   4406  *        a - pointer to args (No arguments expected)
   4407  * Returns:    CMD_OK/CMD_FAIL
   4408  */
   4409 {
   4410     char    pwd[128];
   4411 
   4412     COMPILER_REFERENCE(u);
   4413 
   4414     if (ARG_CNT(a)) {
   4415     return(CMD_USAGE);
   4416     }
   4417 
   4418     if (!sal_getcwd(pwd, sizeof(pwd))) {
   4419     cli_out("%s: Error: Unable to determine current directory\n",
   4420             ARG_CMD(a));
   4421     return(CMD_FAIL);
   4422     } else {
   4423     cli_out("Working Directory: %s\n", pwd);
   4424     return(CMD_OK);
   4425     }
   4426 }
   4427 
   4428 #endif /* NO_SAL_APPL */
   4429 
   4430 char sh_history_usage[] =
   4431     "Parameters: [count]\n\t"
   4432     "Displays the command history.\n\t"
   4433     "If count is given, output is limited to at most count lines.\n";
   4434 
   4435 /*ARGSUSED*/
   4436 cmd_result_t
   4437 sh_history(int u, args_t *a)
   4438 /*
   4439  * Function:     sh_history
   4440  * Purpose:    Print history in input log.
   4441  * Parameters:    u - unit (ignored)
   4442  *        a - args.
   4443  * Returns:    CMD_OK.
   4444  */
   4445 {
   4446 #ifdef INCLUDE_EDITLINE
   4447     extern void list_history(int count);
   4448     char *count_str = ARG_GET(a);
   4449     COMPILER_REFERENCE(u);
   4450     list_history(count_str ? parse_integer(count_str) : 999);
   4451     return(CMD_OK);
   4452 #else
   4453     COMPILER_REFERENCE(u);
   4454     cli_out("History not available\n");
   4455     return CMD_FAIL;
   4456 #endif
   4457 }
   4458 
   4459 char sh_loop_usage[] =
   4460     "Parameters: <loop-count> \"command\" ...\n\t"
   4461     "Loop over a series of commands <loop-count> times, if <loop-count>\n\t"
   4462     "is * then is loops forever. Each argument is a complete command,\n\t"
   4463     "so if it contains more that one word it must be placed in quotes.\n\t"
   4464     "For example:\n\n\t\t"
   4465     "loop 10 \"echo hello world\"\n\n\t"
   4466     "will execute the following command 10 times:\n\n\t"
   4467     "\t\"echo hello world\"\n\n\t"
   4468     "If the series of commands fails, the loop will stop only if the\n\t"
   4469     "\"LoopError\" option is true (see the \"set\" command).\n";
   4470 
   4471 cmd_result_t
   4472 sh_loop(int u, args_t *a)
   4473 /*
   4474  * Function:     sh_loop
   4475  * Purpose:    Perform a command inside a loop.
   4476  * Parameters:    u - unit number
   4477  *        a - args, first parameter "#" or "*" for forever.
   4478  *            Remaining args command line as normal.
   4479  * Returns:    Result of command.
   4480  */
   4481 {
   4482     volatile int l;
   4483     volatile int l_cur;            /* Current loop counter */
   4484     char    *c;
   4485     volatile cmd_result_t rv = CMD_OK;
   4486     int        s_arg;            /* Saved ARG value */
   4487     volatile int forever = FALSE;
   4488 #ifndef NO_CTRL_C
   4489     jmp_buf    ctrl_c;
   4490 #endif
   4491  
   4492     if (ARG_CNT(a) < 2) {
   4493         return(CMD_USAGE);
   4494     }
   4495 
   4496     c = ARG_GET(a);
   4497     if (!sal_strcmp(c, "*")) {
   4498         forever = TRUE;
   4499         l = 0;
   4500     } else if (!isint(c) || (0 > (l = parse_integer(c)))) {
   4501         cli_out("%s: Error: Invalid loop count: %s\n",
   4502                 ARG_CMD(a), c);
   4503         return(CMD_FAIL);
   4504     }
   4505 
   4506     /* Push control-c to print nice message when control-c hit */
   4507 
   4508     l_cur = 1;                /* Assign before setjump */
   4509 #ifndef NO_CTRL_C
   4510     COMPILER_REFERENCE(ctrl_c);
   4511     if (setjmp(ctrl_c)) {
   4512         cli_out("%s: Warning: Looping aborted on the %dth loop\n",
   4513                 ARG_CMD(a), l_cur);
   4514         sh_pop_ctrl_c();
   4515         return(CMD_INTR);
   4516     } else {
   4517         sh_push_ctrl_c(&ctrl_c);
   4518     }
   4519 #endif
   4520     if (++sh_rcload_depth == RCLOAD_DEPTH_MAX) {
   4521         cli_out("rcload: recursion too deep in loop\n");
   4522         rv = CMD_FAIL;
   4523         goto done;
   4524     }
   4525 
   4526     /* Now perform the command */
   4527 
   4528     s_arg = a->a_arg;            /* Save to restore after CMD */
   4529 
   4530     for ( ;
   4531          ((CMD_OK == rv) || !sh_set_lperror) && (forever || (l_cur <= l));
   4532          l_cur++){
   4533         a->a_arg = s_arg;
   4534         while ((c = ARG_GET(a)) && ((CMD_OK == rv) || !sh_set_lperror)) {
   4535             rv = sh_process_command(u, c);
   4536         }
   4537     }
   4538 
   4539 done:
   4540     sh_rcload_depth--;
   4541 #ifndef NO_CTRL_C
   4542     sh_pop_ctrl_c();
   4543 #endif
   4544     return(rv);
   4545 }
   4546 
   4547 char sh_for_usage[] =
   4548     "Parameters: <var>=<start>,<stop>[,<step>[,<fmt>]] 'command' ...\n\t"
   4549     "Iterate a series of commands, each time setting <var> to the\n\t"
   4550     "loop value.  Each argument is a complete command, so if it contains\n\t"
   4551     "more than one word, it must be placed in quotes.  For example:\n\n\t"
   4552     "\tfor port=0,23 'echo port=$port'\n"
   4553 #ifndef COMPILER_STRING_CONST_LIMIT
   4554     "\n\tNote the use of single quotes "
   4555     "to avoid expanding the $port variable\n\t"
   4556     "before executing the loop.  <fmt> defaults to %d (decimal), but can\n\t"
   4557     "be any other standard printf(1)-style format string.\n\n\t"
   4558     "If the series of commands fails, the loop will stop only if the\n\t"
   4559     "\"LoopError\" option is true (see the \"set\" command).\n"
   4560 #endif
   4561     ;
   4562 
   4563 cmd_result_t
   4564 sh_for(int u, args_t *a)
   4565 /*
   4566  * Function:     sh_for
   4567  * Purpose:    Perform a command inside a loop.
   4568  * Parameters:    u - unit number
   4569  *        a - args
   4570  * Returns:    Result of command.
   4571  */
   4572 {
   4573     char    *c, *c_var, *c_start, *c_stop, *c_step;
   4574     char    *tokstr = NULL;
   4575     char    *volatile c_fmt;
   4576     volatile int l_start, l_stop, l_step, l_cur = 0;
   4577     volatile cmd_result_t rv = CMD_OK;
   4578     int        s_arg;            /* Saved ARG value */
   4579 #ifndef NO_CTRL_C
   4580     jmp_buf    ctrl_c;
   4581 #endif
   4582  
   4583     if (ARG_CNT(a) < 2) {
   4584     return(CMD_USAGE);
   4585     }
   4586 
   4587     c = ARG_GET(a);
   4588 
   4589     c_var = sal_strtok_r(c, "=", &tokstr);
   4590     c_start = sal_strtok_r(NULL, ",", &tokstr);
   4591     c_stop = sal_strtok_r(NULL, ",", &tokstr);
   4592     c_step = sal_strtok_r(NULL, ",", &tokstr);
   4593     c_fmt = sal_strtok_r(NULL, "\n", &tokstr);
   4594 
   4595     if (c_var == NULL || c_start == NULL || c_stop == NULL) {
   4596         cli_out("%s: Error: Invalid loop format\n", ARG_CMD(a));
   4597         return(CMD_FAIL);
   4598     }
   4599 
   4600     l_start = parse_integer(c_start);
   4601     l_stop = parse_integer(c_stop);
   4602     l_step = c_step ? parse_integer(c_step) : 1;
   4603     if (c_fmt == NULL)
   4604     c_fmt = "%d";
   4605 
   4606     /* Push control-c to print nice message when control-c hit */
   4607 #ifndef NO_CTRL_C
   4608     COMPILER_REFERENCE(ctrl_c);
   4609     if (setjmp(ctrl_c)) {
   4610         cli_out("%s: Warning: Looping aborted on the %dth loop\n",
   4611                 ARG_CMD(a), l_cur);
   4612         rv = CMD_INTR;
   4613         goto done;
   4614     } else {
   4615         sh_push_ctrl_c(&ctrl_c);
   4616     }
   4617 #endif
   4618     if (++sh_rcload_depth == RCLOAD_DEPTH_MAX) {
   4619         cli_out("rcload: recursion too deep in for loop\n");
   4620         rv = CMD_FAIL;
   4621         goto done;
   4622     }
   4623 
   4624     /* Now perform the command */
   4625 
   4626     s_arg = a->a_arg;            /* Save to restore after CMD */
   4627 
   4628     for (l_cur = l_start;
   4629          (CMD_OK == rv || !sh_set_lperror) &&
   4630              ((l_step > 0 && l_cur <= l_stop) ||
   4631               (l_step < 0 && l_cur >= l_stop));
   4632          l_cur += l_step) {
   4633         char value[80];
   4634         sal_sprintf(value, c_fmt, l_cur, "", "", "");
   4635         var_set(c_var, value, 1, 0);
   4636         a->a_arg = s_arg;
   4637         while ((c = ARG_GET(a)) && ((CMD_OK == rv) || !sh_set_lperror)) {
   4638             rv = sh_process_command(u, c);
   4639         }
   4640     }
   4641 
   4642 done:
   4643     var_unset(c_var, 1, 0, 0);
   4644 
   4645     sh_rcload_depth--;
   4646 #ifndef NO_CTRL_C
   4647     sh_pop_ctrl_c();
   4648 #endif
   4649     return(rv);
   4650 }
   4651 
   4652 static cmd_result_t
   4653 sh_do_init(int u, int reset)
   4654 /*
   4655  * Function:     sh_do_init
   4656  * Purpose:    Perform init function on a specific unit.
   4657  * Parameters:    u - unit to initialize.
   4658  *        reset - if TRUE, reset device, if FALSE, do not reset.
   4659  * Returns:    CMD_OK/CMD_FAIL
   4660  */
   4661 {
   4662     /* Prevent hardware access during chip reset */
   4663     system_shutdown(u, 0);
   4664     { 
   4665         if (reset) {
   4666             if (soc_reset_init(u) < 0) {
   4667                 return(CMD_FAIL);
   4668             }
   4669         } else {
   4670 
   4671 #if defined(BCM_DFE_SUPPORT)&& defined(INCLUDE_INTR)
   4672             if (SOC_IS_FE1600(u)) {
   4673                 bcm_pbmp_t rx_los_pbmp;
   4674                 int rx_los_enable;
   4675 
   4676                 /*RX LOS App disable - required in order to run soft reset without traffic loss*/
   4677                 if (rx_los_enable_get(u, &rx_los_pbmp, &rx_los_enable)) {
   4678                     return (CMD_FAIL);
   4679                 }
   4680 
   4681                 if (rx_los_enable) {
   4682                     if (rx_los_unit_detach(u)) {
   4683                         return (CMD_FAIL);
   4684                     }
   4685                 }
   4686 
   4687                 if (soc_init(u) < 0) {
   4688                     return(CMD_FAIL);
   4689                 }
   4690                 /*RX LOS app enable - without resetting RX LOS - required in order to run soft reset without traffic loss*/
   4691 
   4692                 if (rx_los_enable) {
   4693                     if (rx_los_unit_attach(u, rx_los_pbmp, 1)) {
   4694                         return (CMD_FAIL);
   4695                     }
   4696                 }
   4697             } else
   4698 #endif /*defined(BCM_DFE_SUPPORT) && defined(INCLUDE_INTR)*/
   4699             {
   4700                 if (soc_init(u) < 0) {
   4701                     return(CMD_FAIL);
   4702                 }
   4703             }
   4704         }
   4705     }
   4706 
   4707     return(CMD_OK);
   4708 }
   4709 
   4710 #if (defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)) && defined(INCLUDE_INTR)
   4711 cmd_result_t  device_interrupt_handler_appl_deinit(int unit)
   4712 {
   4713     int rv = 0x0;      
   4714 
   4715     if ((SOC_IS_FE1600(unit)) || (SOC_IS_ARAD(unit) && (!SOC_IS_JERICHO(unit)))) {
   4716         if(!SAL_BOOT_NO_INTERRUPTS) {
   4717             interrupt_handler_appl_deinit(unit);
   4718         }
   4719     } else if ((SOC_IS_FE3200(unit)) || (SOC_IS_JERICHO(unit))) {
   4720         if(!SAL_BOOT_NO_INTERRUPTS) {
   4721             interrupt_appl_deinit(unit);
   4722         } 
   4723     }
   4724 
   4725     return rv;
   4726 }
   4727 #endif
   4728 
   4729 #if defined(BCM_SAND_SUPPORT)
   4730 /*
   4731  * Function:     sh_do_deinit
   4732  * Purpose:    Perform deinit function on a specific unit.
   4733  * Parameters:    u - unit to initialize.
   4734  * Returns:    CMD_OK/CMD_FAIL
   4735  */
   4736 static cmd_result_t sh_do_deinit(int u)
   4737 {
   4738 
   4739     if (soc_deinit(u) < 0) {
   4740         return(CMD_FAIL);
   4741     }
   4742     return(CMD_OK);
   4743 }
   4744 
   4745 /*
   4746  * Function:     sh_do_device_reset
   4747  * Purpose:    Perform different device reset modes/actions.
   4748  * Parameters: 
   4749  *      u - unit to initialize 
   4750  *      mode - reset mode: hard reset, soft reset, init ....
   4751  *      action - im/out/inout..
   4752  * Returns:    CMD_OK/CMD_FAIL
   4753  */
   4754 static cmd_result_t sh_do_device_reset(int u, int mode, int action)
   4755 {
   4756 
   4757     if (soc_device_reset(u, mode, action) < 0) {
   4758         return(CMD_FAIL);
   4759     }
   4760     return(CMD_OK);
   4761 }
   4762 #endif /* defined(BCM_SAND_SUPPORT) */
   4763 
   4764 
   4765 #ifdef BROADCOM_DEBUG
   4766 char sh_break_usage[] =
   4767 "Set an breakpoint in this function for `at-will' gdb reentry\n"
   4768 ;
   4769 cmd_result_t
   4770 sh_break(int unit, args_t *a)
   4771 {
   4772     cli_out("At-will breakpoint\n");
   4773     return CMD_OK;
   4774 }
   4775 #endif
   4776 
   4777 char sh_case_usage[] =
   4778     "Parameters: <what> <value> <command> [<value> <command>]...\n\t"
   4779     "Execute a command based on matching a key value.\n";
   4780 
   4781 cmd_result_t
   4782 sh_case(int u, args_t *a)
   4783 /*
   4784  * Function:     sh_case
   4785  * Purpose:    Implement simple case statement.
   4786  * Parameters:    u - unit #
   4787  *        a - args.
   4788  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE, or result of exectued
   4789  *        command.
   4790  */
   4791 {
   4792     char    *c, *key;
   4793 
   4794     if (!(key = ARG_GET(a))) {
   4795     return(CMD_USAGE);
   4796     }
   4797     while ((c = ARG_GET(a)) != NULL) {
   4798     char *cmd = ARG_GET(a);
   4799     if (!cmd) {
   4800         return(CMD_USAGE);
   4801     }
   4802     if (!sal_strcmp(c, key) || !sal_strcmp("*", c)) {
   4803         ARG_DISCARD(a);
   4804         return(sh_process_command(u, cmd));
   4805     }
   4806     }
   4807     return(CMD_OK);
   4808 }
   4809 
   4810 #if (defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT)) && defined(BCM_WARM_BOOT_SUPPORT)
   4811 static char *
   4812 soc_module_name(int unit, int module_num)
   4813 {
   4814     return "unknown";
   4815 }
   4816 
   4817 static void
   4818 appl_warmboot_storage_requirements(int unit)
   4819 {
   4820     int rv, stable_size, total = 0;
   4821     uint8 *scache_ptr;
   4822     soc_scache_handle_t handle = 0;
   4823     int part_count = 0;
   4824     uint32 size = 0;
   4825     uint32 module;
   4826     uint32 storage_per_module[BCM_MODULE__COUNT+3];
   4827 
   4828     /* Check if extended warmboot support is configured */
   4829     rv = soc_stable_size_get(unit, &stable_size);
   4830     if (SOC_FAILURE(rv)) {
   4831         cli_out("Unable to determine scache size!\n");
   4832         return;
   4833     }
   4834 
   4835     if (stable_size == 0) {
   4836         cli_out("External storage not configured!\n");
   4837         return;
   4838     }
   4839 
   4840     cli_out("\nWarmboot storage requirements:\n");
   4841     cli_out("-------------------------------\n");
   4842     
   4843     for (module = 0; module < BCM_MODULE__COUNT; module++) {
   4844         storage_per_module[module] = 0;
   4845         part_count = scache_max_partitions[unit][module];
   4846         while(0 <= part_count) { 
   4847             SOC_SCACHE_HANDLE_SET(handle, unit, module, part_count);
   4848             rv = soc_scache_ptr_get(unit, handle, &scache_ptr,
   4849                                     &size); 
   4850             if(SOC_SUCCESS(rv)) {
   4851                 storage_per_module[module] += size;
   4852             }
   4853             part_count--;
   4854        }
   4855             if (storage_per_module[module] > 0) {
   4856                 cli_out("%s module: %d bytes handle: %#x\n",
   4857                         bcm_module_name(unit, module),
   4858                         storage_per_module[module], handle);
   4859             } else { 
   4860                 storage_per_module[module] = 0;
   4861             }
   4862          
   4863 
   4864     }
   4865 
   4866     for(module = BCM_MODULE__COUNT; module < BCM_MODULE__COUNT + 3; module++) {
   4867         storage_per_module[module] = 0;
   4868         SOC_SCACHE_HANDLE_SET(handle, unit, module, 0);
   4869         rv = soc_scache_ptr_get(unit, handle, &scache_ptr,
   4870                                 &storage_per_module[module]);
   4871         if (SOC_SUCCESS(rv)) {
   4872                 cli_out("%s module: %d bytes handle: %#x\n",
   4873                         soc_module_name(unit, module),
   4874                         storage_per_module[module], handle);
   4875         } else {
   4876             storage_per_module[module] = 0;
   4877         }        
   4878     }
   4879     
   4880     soc_scache_info_dump(unit);
   4881     rv = soc_stable_used_get(unit, &total);
   4882     
   4883     /* Add size of null descriptor which is added in soc_scache_commit */
   4884     if (SOC_SUCCESS(rv)) {
   4885         total += 12;
   4886     } else {
   4887         cli_out("ERROR: Failed to get stable size!!\n");
   4888         return;
   4889     }
   4890 
   4891     cli_out("------------------------------------\n");
   4892     cli_out("Total storage required: %d bytes\n", total);
   4893     
   4894     return;
   4895 }
   4896 
   4897 static void
   4898 appl_warmboot_storage_usage(int unit)
   4899 {
   4900     int rv, stable_size;
   4901 #if defined(BCM_ESW_SUPPORT)
   4902     soc_scache_handle_t handle;
   4903     uint32 total = 0, module, used_per_module[BCM_MODULE__COUNT+3];
   4904 #endif
   4905 
   4906     if (SOC_IS_DPP(unit)) {
   4907         return;
   4908     }
   4909 
   4910     /* Check if extended warmboot support is configured */
   4911     rv = soc_stable_size_get(unit, &stable_size);
   4912     if (SOC_FAILURE(rv)) {
   4913         cli_out("Unable to determine scache size!\n");
   4914         return;
   4915     }
   4916 
   4917     if (stable_size == 0) {
   4918         cli_out("External storage not configured!\n");
   4919         return;
   4920     }
   4921 
   4922 #if defined(BCM_ESW_SUPPORT)
   4923     cli_out("\nWarmboot storage usage:\n");
   4924     cli_out("-------------------------------\n");
   4925     for (module = 0; module < BCM_MODULE__COUNT; module++) {
   4926         SOC_SCACHE_HANDLE_SET(handle, unit, module, 0);
   4927         rv = soc_scache_handle_used_get(unit, handle,
   4928                                         &used_per_module[module]);  
   4929         if (SOC_SUCCESS(rv)) {
   4930             if (used_per_module[module])
   4931                 used_per_module[module] += SOC_WB_SCACHE_CONTROL_SIZE;
   4932             cli_out("%s module: %d bytes handle: %#x\n",
   4933                     bcm_module_name(unit, module),
   4934                     used_per_module[module], handle);
   4935             total += used_per_module[module];
   4936         } else {
   4937             used_per_module[module] = -1;
   4938         }
   4939     }
   4940     for(module = BCM_MODULE__COUNT; module < BCM_MODULE__COUNT + 3; module++) {
   4941         SOC_SCACHE_HANDLE_SET(handle, unit, module, 0);
   4942         rv = soc_scache_handle_used_get(unit, handle,
   4943                                 &used_per_module[module]);
   4944         if (SOC_SUCCESS(rv)) {
   4945             if (used_per_module[module])
   4946                 used_per_module[module]+= SOC_WB_SCACHE_CONTROL_SIZE;
   4947             cli_out("%s module: %d bytes handle: %#x\n",
   4948                     soc_module_name(unit, module),
   4949                     used_per_module[module], handle);
   4950             total += used_per_module[module];
   4951         } else {
   4952             used_per_module[module] = -1;
   4953         }        
   4954     }
   4955     cli_out("------------------------------------\n");
   4956     cli_out("Total storage usage: %d bytes\n", total);
   4957 #endif
   4958     
   4959     return;
   4960 }
   4961 #endif /* BCM_XGS3_SWITCH_SUPPORT && BCM_WARM_BOOT_SUPPORT */
   4962 
   4963 char sh_warmboot_usage[] =
   4964 #if (defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
   4965 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   4966     "Parameters: [on|off|show|shutdown|storage|usage|memoryuse|sw_state_size\n"
   4967     "|sync|test_mode <on|off|dvapi|no_wb_test|allow_wb_test>]\n"
   4968 #else
   4969     "Parameters: [on | off | show | shutdown | storage | sync | usage]\n"
   4970 #endif
   4971     "Signal warm/cold boot or display current boot status\n"
   4972     "or shut down software components before a warm boot\n"
   4973     "or display the warmboot external storage requirements\n"
   4974     "or show actual current module compressed usage (XGS/XCORE only)\n"
   4975 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   4976     "test_mode (req comp flag):\n"
   4977     "\t on - test after API\n"
   4978     "\t dvapi - test after dvapi\n"
   4979 #ifdef CRASH_RECOVERY_SUPPORT
   4980     "\t cr - crash recovery test after every API\n"
   4981     "\t cr_rb - crash recovery roll back test at every API\n"
   4982 #endif
   4983 #ifdef BCM_WARM_BOOT_API_TEST
   4984     "\t issu_sync - perform issu sync at run_cint\n"
   4985     "\t issu_dump [directory] - perform dump at run_cint. If no directory is specified the default dump dir is used instead.\n"
   4986 #endif
   4987     "\t off - none\n\n"
   4988 #endif /* defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) */
   4989     ;
   4990 #else 
   4991     "Parameters: [on | off | show | shutdown]\n"
   4992     "To signal warm or cold boot or to display current boot status\n"
   4993     "or to shut down software components before a warm boot\n"
   4994     ;
   4995 #endif /* BCM_XGS3_SWITCH_SUPPORT */
   4996 
   4997 /*
   4998  * Function:    sh_warmboot
   4999  * Purpose:     Assert WARMBOOT on to set SOC (reload) state for a unit.
   5000  * Parameters:  u - unit number to operate on
   5001  *              a - args
   5002  * Returns:     CMD_OK/CMD_USAGE.
   5003  */
   5004 cmd_result_t
   5005 sh_warmboot(int u, args_t *a)
   5006 {
   5007     char *c;
   5008     COMPILER_REFERENCE(u);
   5009 
   5010     if (0 == ARG_CNT(a)) {
   5011         return(CMD_USAGE);
   5012     } else {
   5013         int unit = 0;
   5014 
   5015         c = ARG_GET(a);
   5016         if (!sal_strcasecmp(c, "on")) {
   5017 #ifdef BCM_WARM_BOOT_SUPPORT
   5018             for (unit = 0; unit < soc_ndev; unit++) {
   5019                  SOC_WARM_BOOT_START(SOC_NDEV_IDX2DEV(unit));
   5020             }
   5021 #else /* BCM_WARM_BOOT_SUPPORT */
   5022             cli_out("Warm Boot support not compiled!"
   5023                     "  Enable by defining BCM_WARM_BOOT_SUPPORT.\n");
   5024             return CMD_FAIL;
   5025 #endif /* BCM_WARM_BOOT_SUPPORT */
   5026         } else if (!sal_strcasecmp(c, "off")) {
   5027             for (unit = 0; unit < soc_ndev; unit++) {
   5028                  SOC_WARM_BOOT_DONE(SOC_NDEV_IDX2DEV(unit));
   5029             }
   5030         } else if (!sal_strcasecmp(c, "shutdown")) {
   5031             return exit_clean();
   5032         }
   5033 #ifdef BCM_WARM_BOOT_SUPPORT
   5034 #if (defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT))
   5035         else if (!sal_strcasecmp(c, "storage")) {
   5036             appl_warmboot_storage_requirements(u);
   5037         }
   5038 #endif /* (BCM_XGS3_SWITCH_SUPPORT || BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT)*/
   5039 
   5040 #if (defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT) || defined(BCM_DNX_SUPPORT))
   5041         else if (!sal_strcasecmp(c, "usage")) {
   5042             appl_warmboot_storage_usage(u);
   5043         }
   5044 #if defined(BCM_PETRA_SUPPORT)
   5045         else if (!sal_strcasecmp(c, "sw_state_size")) {
   5046             uint32 left = 0;
   5047             uint32 in_use = 0;
   5048             shr_sw_state_sizes_get(u, &in_use, &left);
   5049             cli_out("total: %dMB.\n", (left+in_use)/1000000);
   5050             cli_out("in use: %dMB.\n", in_use/1000000);
   5051             cli_out("left: %dMB.\n", left/1000000);
   5052         }
   5053 #endif
   5054 #if defined(BCM_XGS3_SWITCH_SUPPORT) || defined(BCM_SAND_SUPPORT)
   5055         else if (!sal_strcasecmp(c, "sync")) {
   5056             cli_out("syncing state to WB external storage.\n");
   5057             if (bcm_switch_control_set(unit, bcmSwitchControlSync, 1) != BCM_E_NONE){
   5058                 cli_out("bcm_switch_control_set failed.\n");
   5059                 return CMD_FAIL;
   5060             }
   5061         }
   5062 #endif
   5063 #if defined(BCM_SAND_SUPPORT)
   5064         else if (!sal_strcasecmp(c, "test_mode")) {
   5065            char *test_status; 
   5066            if (0 == ARG_CNT(a)) {
   5067                 return(CMD_USAGE);
   5068             }
   5069             
   5070             test_status = ARG_GET(a);
   5071 #ifdef BCM_WARM_BOOT_API_TEST
   5072             if (!sal_strcasecmp(test_status, "on")) {
   5073                /* enable autosync mode */
   5074 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5075                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_AFTER_EVERY_API);
   5076 #endif
   5077             }else if (!sal_strcasecmp(test_status, "dvapi")){
   5078 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5079                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_END_OF_DVAPIS);
   5080 #endif
   5081             }else if (!sal_strcasecmp(test_status, "autosync")){
   5082 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5083                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_AFTER_EVERY_API);
   5084 #endif
   5085                bcm_switch_control_set(unit, bcmSwitchControlAutoSync, 1);
   5086 #ifdef CRASH_RECOVERY_SUPPORT
   5087             }else if (!sal_strcasecmp(test_status, "cr")) {
   5088 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5089                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_CRASH_RECOVERY);
   5090 #endif
   5091             }else if (!sal_strcasecmp(test_status, "cr_rb")) {
   5092                cli_out("cr_rb is temporarily unavailable\n");
   5093 #endif
   5094             }else if (!sal_strcasecmp(test_status, "off")){
   5095 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5096                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_NONE);
   5097 #endif
   5098             }else if (!sal_strcasecmp(test_status, "no_wb_test")){
   5099 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5100                soc_dcmn_wb_no_wb_test_set(u,1);
   5101 #endif
   5102             }else if (!sal_strcasecmp(test_status, "allow_wb_test")){
   5103 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5104                soc_dcmn_wb_no_wb_test_set(u,0);
   5105 #endif
   5106             }else if (!sal_strcasecmp(test_status, "skip")){
   5107                cli_out("skip command is not operable any more\n");
   5108             }else if (!sal_strcasecmp(test_status, "issu_sync")){
   5109 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5110                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_ISSU_SYNC);
   5111 #endif
   5112             }else if (!sal_strcasecmp(test_status, "issu_dump")){
   5113                if (0 == ARG_CNT(a)) {
   5114                     cli_out("no issu_dump directory specified, using default dump directory instead\n");
   5115                } else {
   5116                     char *dump_directory = ARG_GET(a);
   5117                     if (sal_strlen(dump_directory) == 0) return(CMD_USAGE);
   5118 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5119                     soc_dcmn_wb_issu_dump_directory_set(u, dump_directory);
   5120 #endif
   5121                }
   5122 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5123                soc_dcmn_wb_test_mode_set(u,_DCMN_BCM_WARM_BOOT_API_TEST_MODE_ISSU_DUMP);
   5124 #endif
   5125             }else {
   5126                return(CMD_USAGE);
   5127             }
   5128 #else /*BCM_WARM_BOOT_API_TEST*/
   5129             assert(sal_strcasecmp(test_status, "only here to prevent compilation/coverity errors"));
   5130 #endif /*BCM_WARM_BOOT_API_TEST*/
   5131 		}
   5132 #if (defined(LINUX) || defined(UNIX))
   5133 #if defined(BCM_SAND_SUPPORT)
   5134 #ifndef NO_FILEIO
   5135         else if (!sal_strcasecmp(c, "memoryuse")) {
   5136             int values[7];
   5137             int i = 0;
   5138             int page_size = getpagesize();
   5139 
   5140             FILE* status = NULL;
   5141 
   5142             status = sal_fopen( "/proc/self/statm", "r" );
   5143             if (!status) {
   5144                 cli_out("\nError: Unable to open statm file\n");
   5145                 return CMD_FAIL;
   5146             }
   5147 
   5148             cli_out("\n for WarmBoot external storage sizes chek your wb and kaps wb and kbp wb file sizes .\n");
   5149  
   5150             while (fscanf(status, "%d", &values[i]) == 1) {i++;};
   5151             sal_printf("total process size:   %d MB\n", ((values[0]*page_size)/1000000));
   5152             sal_printf("  -data+stack:        %d MB\n", ((values[5]*page_size)/1000000));
   5153             sal_printf("  -text:              %d MB\n", ((values[3]*page_size)/1000000));
   5154             sal_printf("  -resident set size: %d MB\n", ((values[1]*page_size)/1000000));
   5155             sal_printf("  -shared:            %d MB\n", ((values[2]*page_size)/1000000));
   5156 			sal_printf("memory usage:         %d MB\r\n\n", ((values[0]*page_size))/1000000);
   5157 
   5158             sal_fclose((FILE *)status);
   5159 #ifdef BCM_PETRA_SUPPORT
   5160             if (SOC_IS_DPP(u))
   5161             {
   5162             	DISPLAY_MEM_PRINTF(("%s(): Allocations by sal_alloc() and shr_sw_state_alloc()\r\n",__FUNCTION__)) ;
   5163             	DISPLAY_MEM ;
   5164             	DISPLAY_SW_STATE_MEM ;
   5165             }
   5166 #endif
   5167         }
   5168 #endif /*NO_FILEIO*/
   5169 #endif /*BCM_SAND_SUPPORT*/
   5170 #endif /*(defined(LINUX) || defined(UNIX))*/
   5171 #endif /* defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)*/
   5172 #endif /* (BCM_XGS3_SWITCH_SUPPORT || BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)*/
   5173 #endif /* BCM_WARM_BOOT_SUPPORT */
   5174         else if (!sal_strcasecmp(c, "show")) {
   5175             for (unit = 0; unit < soc_ndev; unit++) {
   5176                  if (!soc_attached(SOC_NDEV_IDX2DEV(unit))) {
   5177                      continue;
   5178                  }
   5179 
   5180                  if (SOC_WARM_BOOT(SOC_NDEV_IDX2DEV(unit))) {
   5181                      cli_out("Unit %d: Warm Boot\n", SOC_NDEV_IDX2DEV(unit));
   5182                  } else {
   5183                      cli_out("Unit %d: Cold Boot\n", SOC_NDEV_IDX2DEV(unit));
   5184                  }
   5185             }
   5186         }
   5187 #ifdef BCM_WARM_BOOT_SUPPORT
   5188 #if defined(BCM_ESW_SUPPORT)
   5189         else if (!sal_strcasecmp(c, "scache")) {
   5190             soc_scache_dump_state(unit);
   5191             return (CMD_OK);
   5192         }
   5193 #endif
   5194 #endif /* BCM_WARM_BOOT_SUPPORT */
   5195         else {
   5196             return(CMD_USAGE);
   5197         }
   5198     }
   5199     return(CMD_OK);
   5200 }
   5201 
   5202 #if defined(BCM_WARM_BOOT_API_TEST) 
   5203 char sh_state_usage[] =
   5204     "Parameters: [sw | usage]\n"
   5205     "sw: \n"
   5206     "    [dump size]\n"
   5207     "     dump: \n"
   5208     "           [block | readable]\n"
   5209     "            block: \n"
   5210     "                   [filename]\n"
   5211     "            readable: \n"
   5212     "                     [stdout | file]\n"
   5213     "                      file:\n"
   5214     "                            [filename]\n"
   5215     "     size\n";
   5216 
   5217 /*
   5218  * Function:    sh_state
   5219  * Purpose:     dump: print the sw_state data to the monitor/file
   5220  * Parameters:  u - unit number to operate on
   5221  *              a - args
   5222  * Returns:     CMD_OK/CMD_USAGE.
   5223  */
   5224 cmd_result_t
   5225 sh_state(int u, args_t *a)
   5226 {
   5227     char *c;
   5228     COMPILER_REFERENCE(u);
   5229     COMPILER_REFERENCE(c);
   5230 
   5231     if (0 == ARG_CNT(a)) return(CMD_USAGE);
   5232     else {
   5233         c = ARG_GET(a);
   5234 #ifdef BCM_WARM_BOOT_API_TEST
   5235 #if defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   5236         if (!sal_strcasecmp(c, "sw")) {
   5237             if (0 == ARG_CNT(a)) return(CMD_USAGE);
   5238             c = ARG_GET(a);
   5239             if (!sal_strcasecmp(c, "dump")) {
   5240 #if defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   5241                 if (0 == ARG_CNT(a)) return(CMD_USAGE);
   5242                 c = ARG_GET(a);
   5243                 if (!sal_strcasecmp(c, "block")) {
   5244                     if (0 == ARG_CNT(a)) return(CMD_USAGE);
   5245                     c = ARG_GET(a);
   5246                     cli_out("%d: Dumping SW State Data Block to file.\n", u);
   5247                     shr_sw_state_block_dump(u, 0, c, "w");
   5248                 } else if (!sal_strcasecmp(c, "readable")) {
   5249                     c = ARG_GET(a);
   5250                     if (!sal_strcasecmp(c, "stdout")) {
   5251 #if defined(BCM_PETRA_SUPPORT)
   5252                         sw_state_diagnostic[u].dpp.dump(u);
   5253 #endif
   5254                     } else if (!sal_strcasecmp(c, "file")) {
   5255                         if (0 == ARG_CNT(a)) return(CMD_USAGE);
   5256                         c = ARG_GET(a);
   5257                         shr_sw_state_stride_dump(u, c);
   5258                     } else {
   5259                         return(CMD_USAGE);
   5260                     }
   5261                 }
   5262 #endif
   5263             } else if (!sal_strcasecmp(c, "size")){
   5264 #if defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)
   5265                 uint32 left = 0;
   5266                 uint32 in_use = 0;
   5267                 shr_sw_state_sizes_get(u, &in_use, &left);
   5268                 cli_out("total: %dMB.\n", (left+in_use)/1000000);
   5269                 cli_out("in use: %dMB.\n", in_use/1000000);
   5270                 cli_out("left: %dMB.\n", left/1000000);
   5271 #endif
   5272             } else {
   5273                 return(CMD_USAGE);
   5274             }
   5275         }else
   5276 #endif
   5277 #endif
   5278         {
   5279             return(CMD_USAGE);
   5280         }
   5281     }
   5282     return(CMD_OK);
   5283 }
   5284 #endif/*BCM_WARM_BOOT_API_TEST */
   5285 
   5286 #if defined(BCM_EASY_RELOAD_SUPPORT) || defined(BCM_EASY_RELOAD_WB_COMPAT_SUPPORT)
   5287 
   5288 char cmd_xxreload_usage[] =
   5289 "Parameters\n"
   5290 "\ton   -- Put the chip in reload mode\n"
   5291 "\toff  -- Put the chip in the normal mode\n"
   5292 "\tshow -- Show the mode\n";
   5293 
   5294 static cmd_result_t
   5295 xxreload_set(int unit, int reload)
   5296 {
   5297     if (!SOC_UNIT_VALID(unit)) {
   5298         return (CMD_FAIL);
   5299     }
   5300     SOC_RELOAD_MODE_SET(unit, reload);
   5301 
   5302     return (CMD_OK);
   5303 }
   5304 
   5305 static cmd_result_t
   5306 xxreload_show(int unit)
   5307 {
   5308     int reload;
   5309 
   5310     if (!SOC_UNIT_VALID(unit)) {
   5311         return (CMD_FAIL);
   5312     }
   5313 
   5314     reload = SOC_IS_RELOADING(unit);
   5315     cli_out("Unit %d is in %s mode.\n",
   5316             unit,
   5317             reload ? "reload" : "normal");
   5318 
   5319     return CMD_OK;
   5320 }
   5321 
   5322 cmd_result_t
   5323 cmd_xxreload(int unit, args_t *a)
   5324 {
   5325     char *c;
   5326 
   5327     if (!ARG_CNT(a)) {
   5328         return (xxreload_show(unit));
   5329     }
   5330 
   5331     c = ARG_GET(a);
   5332 
   5333     if (!sal_strcasecmp(c, "on")) {
   5334         return (xxreload_set(unit, TRUE));
   5335     } else if (!sal_strcasecmp(c, "off")) {
   5336         return (xxreload_set(unit, FALSE));
   5337     } else if (!sal_strcasecmp(c, "show")) {
   5338         return (xxreload_show(unit));
   5339     } else {
   5340         return (CMD_USAGE);
   5341     }
   5342 
   5343     return (CMD_OK);
   5344 }
   5345 
   5346 #endif /*defined(BCM_EASY_RELOAD_SUPPORT) || defined(BCM_EASY_RELOAD_WB_COMPAT_SUPPORT)*/
   5347 
   5348 #if defined(BCM_PETRA_SUPPORT)
   5349 
   5350 static cmd_result_t
   5351 sh_do_reinit(int u, int reset)
   5352 /*
   5353  * Function:     sh_do_init
   5354  * Purpose:    Perform init function on a specific unit.
   5355  * Parameters:    u - unit to initialize.
   5356  *        reset - if TRUE, reset device, if FALSE, do not reset.
   5357  * Returns:    CMD_OK/CMD_FAIL
   5358  */
   5359 {
   5360     /* Prevent hardware access during chip reset */
   5361    /* system_shutdown(u, 0); */
   5362 
   5363     if (SOC_IS_DPP(u)) {
   5364         return (soc_dpp_reinit(u,reset));
   5365     }
   5366 
   5367 
   5368     return(CMD_OK);
   5369 }
   5370 
   5371 
   5372 /* Uses same help as sh_init, but must be defined for compilation */
   5373 char sh_reinit_usage[] = "";
   5374 
   5375 cmd_result_t
   5376 sh_reinit(int u, args_t *a)
   5377 /*
   5378  * Function:     sh_reinit
   5379  * Purpose:    Initialize the SOC chip and S/W for a unit.
   5380  * Parameters:    u - unit number to operate on
   5381  *        a - args (none expected)
   5382  * Returns:    CMD_OK/CMD_FAIL.
   5383  */
   5384 {
   5385     cmd_result_t rv = CMD_OK;
   5386     int        bcm_rv;
   5387     char    *c;
   5388     int     usage = 0;
   5389 
   5390     if (!sh_check_attached(ARG_CMD(a), u)) {
   5391     return(CMD_FAIL);
   5392     }
   5393 
   5394     c = ARG_GET(a);
   5395 
   5396     if (!c || !sal_strcasecmp(c, "soc")) {
   5397     if ((rv = sh_do_reinit(u, TRUE)) < 0) {
   5398         cli_out("%s: Unable to initialize device: %d\n",
   5399                 ARG_CMD(a), u);
   5400     }
   5401     } else if (!sal_strcasecmp(c, "bcm")) {
   5402     if ((bcm_rv = bcm_init(u)) < 0) {
   5403         cli_out("%s: Unable to initialize BCM driver on unit %d: %s\n",
   5404                 ARG_CMD(a), u, bcm_errmsg(bcm_rv));
   5405         rv = CMD_FAIL;
   5406         }
   5407     } else if (!sal_strcasecmp(c, "misc")) {
   5408     if ((rv = soc_misc_init(u)) < 0) {
   5409         cli_out("%s: Unable to initialize misc for device %d: %s\n",
   5410                 ARG_CMD(a), u, soc_errmsg(rv));
   5411     }
   5412     } else if (!sal_strcasecmp(c, "noreset")) {
   5413     if ((rv = sh_do_init(u, FALSE)) < 0) {
   5414         cli_out("%s: Unable to initialize device %d\n",
   5415                 ARG_CMD(a), u);
   5416     }
   5417     } else if (!sal_strcasecmp(c, "mmu")) {
   5418         if (SOC_IS_DPP(u)) {
   5419             rv = CMD_OK;
   5420         return rv;
   5421         }
   5422     } else if (!sal_strcasecmp(c, "all")) {
   5423         /* Prevent hardware access during chip reset */
   5424         system_shutdown(u, 0);
   5425     if ((bcm_rv = system_init(u)) < 0) {
   5426         cli_out("%s: Unable to reset and initialize BCM driver: %s\n",
   5427                 ARG_CMD(a), bcm_errmsg(bcm_rv));
   5428         rv = CMD_FAIL;
   5429     }
   5430     } else { /* look for selective init */
   5431         uint32      flags = 0;
   5432         int module_num;
   5433         int found;
   5434 
   5435         if (bcm_attach_check(u) == BCM_E_UNIT) {
   5436             if ((bcm_rv = bcm_attach(u, NULL, NULL, u)) < 0) {
   5437             return CMD_FAIL;
   5438             }
   5439         }
   5440 
   5441         do {
   5442             found = 0;
   5443             for (module_num = 0; module_num < BCM_MODULE__COUNT; module_num++) {
   5444                 if (!sal_strcasecmp(bcm_module_name(u, module_num), c)) {
   5445                     found = 1;
   5446                     flags = (uint32) module_num;
   5447                     if ((bcm_rv = bcm_init_selective(u, flags)) < 0) {
   5448                         cli_out("%s: Unable to initialize %s (flags 0x%x): %s\n",
   5449                                 ARG_CMD(a), c, flags, bcm_errmsg(bcm_rv));
   5450                         rv = CMD_FAIL;
   5451                      }
   5452                     break;
   5453                 }
   5454             }
   5455             if (!found) {
   5456                 cli_out("Unknown module: %s\n", c);
   5457                 usage = 1;
   5458                 break;
   5459             }
   5460         } while ((c = ARG_GET(a)) != NULL);
   5461     }
   5462 
   5463     if (usage) {
   5464     cli_out("%s: Unknown option: %s\n", ARG_CMD(a), c);
   5465     rv = CMD_USAGE;
   5466     }
   5467 
   5468     return(rv);
   5469 }
   5470 #endif /* BCM_PETRA_SUPPORT */
   5471 
   5472 #if (defined(BCM_DFE_SUPPORT)  || defined(BCM_PETRA_SUPPORT)) && defined(INCLUDE_INTR)
   5473 int
   5474 diag_device_interrupt_handler_appl_init(int unit) {
   5475 
   5476     if ((SOC_IS_FE1600(unit)) || (SOC_IS_ARAD(unit))) {
   5477         if(!SAL_BOOT_NO_INTERRUPTS) {
   5478             interrupt_handler_appl_init(unit);
   5479         }
   5480     }
   5481 
   5482    return CMD_OK;
   5483 }
   5484 
   5485 int diag_device_rx_los_handler_appl_init(int unit, args_t *a)
   5486 {
   5487     uint32 short_sleep_usec = 0,
   5488         long_sleep_usec = 0,
   5489         allowed_retries = 0,
   5490         thread_priority = 0,
   5491         active_sleep_usec = 0;
   5492     int link_down_count_max = 0;
   5493     int link_down_cycle_time = 0;
   5494     char *option;
   5495     int warmboot = 0;
   5496     pbmp_t rx_los_pbmp;
   5497     int rv;
   5498 
   5499     if ( SOC_IS_FE1600(unit) || (SOC_IS_ARAD(unit) && !SOC_IS_JERICHO(unit))) {
   5500         BCM_PBMP_CLEAR(rx_los_pbmp);
   5501 
   5502         /* get parameters for rxlos interrupt */
   5503 
   5504         while ((option = ARG_GET(a)) != NULL) {
   5505 
   5506             /* get long sleep in usecs*/
   5507             if (!sal_strcmp(option, "longsleep")) {
   5508                 option = ARG_GET(a);
   5509                 if (option) {
   5510                     long_sleep_usec = sal_ctoi(option, 0);
   5511                 }
   5512 
   5513                 /* get short sleep in usecs */
   5514             } else if (!sal_strcmp(option, "shortsleep")) {
   5515                 option = ARG_GET(a);
   5516                 if (option) {
   5517                     short_sleep_usec = sal_ctoi(option, 0);
   5518                 }
   5519 
   5520                 /* get allowed retries */
   5521             } else if (!sal_strcmp(option, "retries")) {
   5522                 option = ARG_GET(a);
   5523                 if (option) {
   5524                     allowed_retries = sal_ctoi(option, 0);
   5525                 }
   5526 
   5527                 /* get supported pbmp for unit */
   5528             } else if (!sal_strcmp(option, "pbmp")) {
   5529                 option = ARG_GET(a);
   5530                 if (option) {
   5531                     rv = parse_pbmp(unit, option, &rx_los_pbmp);
   5532                     if (BCM_FAILURE(rv)) {
   5533                         cli_out("RX los app: Unknown pbmp: %s\n", option);
   5534                         return CMD_FAIL;
   5535                     }
   5536                 }
   5537 
   5538                 /* get priority for thread */
   5539             } else if (!sal_strcmp(option, "priority")) {
   5540                 option = ARG_GET(a);
   5541                 if (option) {
   5542                     thread_priority = sal_ctoi(option, 0);
   5543                 }
   5544 
   5545                 /* get occurences for interrupt */
   5546             } else if (!sal_strcmp(option, "occurences")) {
   5547                 option = ARG_GET(a);
   5548                 if (option) {
   5549                     link_down_count_max = sal_ctoi(option, 0);
   5550                 }
   5551 
   5552                 /* get cycle time for interrupt */
   5553             } else if (!sal_strcmp(option, "cycle_time")) {
   5554                 option = ARG_GET(a);
   5555                 if (option) {
   5556                     link_down_cycle_time = sal_ctoi(option, 0);
   5557                 }
   5558 
   5559             } else if (!sal_strcmp(option, "warm_boot")) {
   5560                 warmboot = 1;
   5561             } else if (!sal_strcmp(option, "activesleep")) {
   5562                 option = ARG_GET(a);
   5563                 if (option) {
   5564                     active_sleep_usec = sal_ctoi(option, 0);
   5565                 }
   5566             }
   5567         }
   5568 
   5569         /* set rx los appl configs*/
   5570         rv = rx_los_set_config(short_sleep_usec, long_sleep_usec, allowed_retries, thread_priority, link_down_count_max, link_down_cycle_time);
   5571         if (rv != BCM_E_NONE) {
   5572             return CMD_FAIL;
   5573         }
   5574 
   5575         if (active_sleep_usec) {
   5576             rv = rx_los_set_active_sleep_config(active_sleep_usec);
   5577             if (rv != BCM_E_NONE) {
   5578                 return CMD_FAIL;
   5579             }
   5580         }
   5581         rv = rx_los_unit_attach(unit, rx_los_pbmp, warmboot);
   5582         if (rv != BCM_E_NONE) {
   5583             return CMD_FAIL;
   5584         }
   5585     } else {
   5586         cli_out("Error: rx_los - feature unavailable for Jericho devices\n");
   5587         return CMD_FAIL;
   5588     }
   5589 
   5590     return CMD_OK;
   5591 }
   5592 #endif
   5593 
   5594 char sh_init_usage[] =
   5595     "Parameters: [soc|noreset|mmu|bcm|misc|interrupt|all]\n"
   5596 #ifndef COMPILER_STRING_CONST_LIMIT
   5597     "\tPerforms various initializations (default is soc):\n\t"
   5598     "  soc - resets the device, configures minimal register\n\t"
   5599     "        settings and enables interrupts\n\t"
   5600     "  noreset - like soc, but does not reset the device\n\t"
   5601     "  mmu - writes SDRAM and MMU parameters (does not size GBP)\n\t"
   5602     "  bcm - initializes BCM driver internals/registers/tables\n\t"
   5603     "  misc - performs chip-specific fundamental initialization\n\t"
   5604 #if defined(BCM_TRIUMPH_SUPPORT)
   5605     "  tcam - perform tcam initialization\n\t"
   5606 #endif
   5607 #if defined(BCM_PETRA_SUPPORT)
   5608     "  appl_dpp - init application of dpp devices\n\t"
   5609 #endif
   5610     "  interrupt - initialize Interrupt Application Handler\n\t"
   5611     "  all - equivalent to performing soc, mmu, misc, and bcm\n\t"
   5612 #if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
   5613     "  rx_los - init RX LOS application of BCM88750, BCM88650 and BCM88660 devices\n\n"
   5614 #endif
   5615 #if defined(BCM_PETRA_SUPPORT) && defined(BCM_JERICHO_SUPPORT)
   5616     "  pvt_mon [interval] - initialize PVT monitor correction thread, the interval is in seconds\n\t"
   5617 #endif
   5618 #if defined(BCM_PETRA_SUPPORT) && defined(BCM_FLAIR_SUPPORT)
   5619         "  fgl_api - init the fabric FGL customer APIs\n\t"
   5620 #endif
   5621     "Additional selective initialization (components of 'init bcm'):\n\t"
   5622     "port, l2, vlan, trunk, cosq, mcast, linkscan, stat, filter, diffserv\n\t"
   5623     "mirror, packet, l3, stack, ipmc, stg, mbcm, stp, tx, auth.\n"
   5624 #endif
   5625     ;
   5626 
   5627 #if defined(BCM_PETRA_SUPPORT)
   5628 STATIC cmd_result_t
   5629 sh_appl_dpp(int u, args_t *a) {
   5630 
   5631     int        bcm_rv;
   5632     char     *option;
   5633     appl_dcmn_init_param_t init_param;
   5634     sal_memset(&init_param, 0x0, sizeof(appl_dcmn_init_param_t));
   5635     /* default parameters differ than zero*/
   5636     init_param.nof_devices = 1;
   5637     init_param.appl_traffic_enable_stage = TRAFFIC_EN_STAGE_AFTER_STK;
   5638 
   5639     /* My Modid option */
   5640     option = ARG_GET(a);        
   5641     if (option) {
   5642         init_param.modid = sal_ctoi(option,0);
   5643     }
   5644 
   5645     /* Nof devices option */
   5646     option = ARG_GET(a);        
   5647     if (option) {
   5648         init_param.nof_devices = sal_ctoi(option,0);
   5649     }
   5650 
   5651     /* COSQ disable option */
   5652     option = ARG_GET(a);        
   5653     if (option) {
   5654         init_param.cosq_disable = sal_ctoi(option,0);
   5655     }
   5656 
   5657     /* Warmboot option */
   5658     option = ARG_GET(a);        
   5659     if (option) {
   5660         init_param.warmboot = sal_ctoi(option,0);
   5661     }
   5662 
   5663     /* no_appl_stk option */
   5664     option = ARG_GET(a);        
   5665     if (option) {
   5666         init_param.no_appl_stk = sal_ctoi(option,0);
   5667     }
   5668 
   5669     /* no_appl_cosq option */
   5670     option = ARG_GET(a);        
   5671     if (option) {
   5672         init_param.packet_rx_cosq = sal_ctoi(option,0);
   5673     }
   5674 
   5675     /* appl_traffic_enable_stage option */
   5676     option = ARG_GET(a);        
   5677     if (option) {
   5678         init_param.appl_traffic_enable_stage = sal_ctoi(option,0);
   5679     }
   5680 
   5681     /* appl_flags option */
   5682     option = ARG_GET(a);        
   5683     if (option) {
   5684         init_param.appl_flags = sal_ctoi(option,0);
   5685     }
   5686 
   5687     bcm_rv = appl_dpp_bcm_diag_init(u, &init_param);
   5688     if (BCM_FAILURE(bcm_rv)) {
   5689         cli_out("appl_dpp_bcm_diag_init() failed. Error:%d (%s) \n",
   5690                 bcm_rv, bcm_errmsg(bcm_rv));
   5691         return CMD_FAIL;
   5692     }
   5693     return CMD_OK;
   5694 }
   5695 #endif /* BCM_PETRA_SUPPORT */
   5696 
   5697 #ifdef BCM_KATANA2_SUPPORT
   5698 STATIC int
   5699 kt2_sku_config_add(int unit)
   5700 {
   5701     int rv = 0;
   5702     soc_kt2_sku_config_info_t conf;
   5703     _soc_kt2_config_get(unit, &conf);
   5704     var_set_integer("config", conf.config, FALSE, FALSE);
   5705     var_set_integer("BCM56450_CFG_OFFSET",
   5706                     conf.bcm56450_cfg_offset, FALSE, FALSE);
   5707     var_set_integer("BCM56452_CFG_OFFSET",
   5708                     conf.bcm56452_cfg_offset, FALSE, FALSE);
   5709     var_set_integer("BCM56454_CFG_OFFSET",
   5710                     conf.bcm56454_cfg_offset, FALSE, FALSE);
   5711     var_set_integer("BCM56455_CFG_OFFSET",
   5712                     conf.bcm56455_cfg_offset, FALSE, FALSE);
   5713     var_set_integer("BCM56248_CFG_OFFSET",
   5714                     conf.bcm56248_cfg_offset, FALSE, FALSE);
   5715     var_set_integer("olp_port", conf.olp_port, FALSE, FALSE);
   5716     var_set_integer("xfi_0", conf.xfi_0, FALSE, FALSE);
   5717     var_set_integer("xfi_1", conf.xfi_1, FALSE, FALSE);
   5718     return rv;
   5719 }
   5720 #endif /* BCM_KATANA2_SUPPORT */
   5721 
   5722 cmd_result_t
   5723 sh_init(int u, args_t *a)
   5724 /*
   5725  * Function:     sh_init
   5726  * Purpose:    Initialize the SOC chip and S/W for a unit.
   5727  * Parameters:    u - unit number to operate on
   5728  *        a - args (none expected)
   5729  * Returns:    CMD_OK/CMD_FAIL.
   5730  */
   5731 {
   5732     cmd_result_t rv = CMD_OK;
   5733     int        bcm_rv;
   5734     char    *c;
   5735     int     usage = 0;
   5736     SHR_BPROF_STATS_DECL;
   5737 
   5738     if (!sh_check_attached(ARG_CMD(a), u)) {
   5739     return(CMD_FAIL);
   5740     }
   5741 
   5742     c = ARG_GET(a);
   5743 
   5744     if (!c || !sal_strcasecmp(c, "soc")) {
   5745         c = ARG_GET(a);
   5746         if (!c) {
   5747             SHR_BPROF_STATS_TIME(SHR_BPROF_SOC_INIT) {
   5748             if ((rv = sh_do_init(u, TRUE)) < 0) {
   5749                 cli_out("%s: Unable to initialize device: %d\n",
   5750                         ARG_CMD(a), u);
   5751             }
   5752             }
   5753         } else {
   5754             if (!sal_strcasecmp(c, "FALSE")) {
   5755                 SHR_BPROF_STATS_TIME(SHR_BPROF_SOC_INIT) {
   5756                 if ((rv = sh_do_init(u, FALSE)) < 0){
   5757                     cli_out("%s: Unable to initialize device: %d\n",
   5758                             ARG_CMD(a), u);
   5759                 }
   5760                 }
   5761             } else {
   5762                 SHR_BPROF_STATS_TIME(SHR_BPROF_SOC_INIT) {
   5763                 if ((rv = sh_do_init(u, TRUE)) < 0){
   5764                     cli_out("%s: Unable to initialize device: %d\n",
   5765                             ARG_CMD(a), u);
   5766             }
   5767             }
   5768             }
   5769         }
   5770     } else if (!sal_strcasecmp(c, "bcm")) {
   5771     SHR_BPROF_STATS_TIME(SHR_BPROF_BCM_INIT) {
   5772     if ((bcm_rv = bcm_init(u)) < 0) {
   5773         cli_out("%s: Unable to initialize BCM driver on unit %d: %s\n",
   5774                 ARG_CMD(a), u, bcm_errmsg(bcm_rv));
   5775         rv = CMD_FAIL;
   5776     }
   5777     }
   5778     } else if (!sal_strcasecmp(c, "misc")) {
   5779     SHR_BPROF_STATS_TIME(SHR_BPROF_SOC_MISC) {
   5780     if ((rv = soc_misc_init(u)) < 0) {
   5781         cli_out("%s: Unable to initialize misc for device %d: %s\n",
   5782                 ARG_CMD(a), u, soc_errmsg(rv));
   5783     }
   5784     }
   5785 #if defined(BCM_TRIUMPH_SUPPORT)
   5786     } else if (!sal_strcasecmp(c, "tcam")) {
   5787         if ((rv = soc_tcam_init(u)) < 0) {
   5788         cli_out("%s: Unable to initialize tcam for device %d: %s\n",
   5789                 ARG_CMD(a), u, soc_errmsg(rv));
   5790     }
   5791 #endif
   5792 #if defined(BCM_XGS_SUPPORT) || defined(BCM_SAND_SUPPORT)
   5793     } else if (!sal_strcasecmp(c, "noreset")) {
   5794     if ((rv = sh_do_init(u, FALSE)) < 0) {
   5795         cli_out("%s: Unable to initialize device %d\n",
   5796                 ARG_CMD(a), u);
   5797     }
   5798     } else if (!sal_strcasecmp(c, "mmu")) {
   5799 #ifdef BCM_SAND_SUPPORT
   5800         if (SOC_IS_SAND(u)) {
   5801             rv = CMD_OK;
   5802         return rv;
   5803         }
   5804 #endif
   5805 #ifdef BCM_XGS_SUPPORT
   5806     SHR_BPROF_STATS_TIME(SHR_BPROF_SOC_MMU) {
   5807     if ((bcm_rv = soc_mmu_init(u)) < 0) {
   5808         cli_out("%s: Unable to initialize MMU for device: %s\n",
   5809                 ARG_CMD(a), bcm_errmsg(bcm_rv));
   5810         rv = CMD_FAIL;
   5811     }
   5812 #ifdef BCM_KATANA2_SUPPORT
   5813     if (SOC_IS_KATANA2(u) && (!SOC_IS_SABER2(u))) {
   5814         if (kt2_sku_config_add(u) < 0) {
   5815             cli_out("Unable to add sku config specicific for kt2");
   5816        }
   5817     }
   5818 #endif
   5819     }
   5820 #endif
   5821 #endif
   5822 #if (defined(BCM_DFE_SUPPORT)  || defined(BCM_PETRA_SUPPORT))
   5823     } else if (!sal_strcasecmp(c, "interrupt")) {
   5824 #if defined(INCLUDE_INTR)
   5825 
   5826         if ((bcm_rv = diag_device_interrupt_handler_appl_init(u)) < 0) 
   5827         {
   5828             cli_out("%s: Unable to initialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv)); 
   5829             rv = CMD_FAIL;
   5830         }
   5831 #endif /*defined(INCLUDE_INTR)*/
   5832     }  else if (!sal_strcasecmp(c, "rx_los")) {
   5833 #if defined(INCLUDE_INTR)
   5834         if ((bcm_rv = diag_device_rx_los_handler_appl_init(u, a)) < 0) 
   5835         {
   5836             cli_out("%s: Unable to initialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv)); 
   5837             rv = CMD_FAIL;
   5838         }
   5839 #endif /*defined(INCLUDE_INTR)*/
   5840 #endif /*defined(BCM_DFE_SUPPORT)  || defined(BCM_PETRA_SUPPORT)*/
   5841     } else if (!sal_strcasecmp(c, "all")) {
   5842         /* Prevent hardware access during chip reset */
   5843         system_shutdown(u, 0);
   5844     if ((bcm_rv = system_init(u)) < 0) {
   5845         cli_out("%s: Unable to reset and initialize BCM driver: %s\n",
   5846                 ARG_CMD(a), bcm_errmsg(bcm_rv));
   5847         rv = CMD_FAIL;
   5848     } 
   5849 #if defined(BCM_PETRA_SUPPORT)
   5850     } else if (!sal_strcasecmp(c, "appl_dpp")){
   5851           return sh_appl_dpp(u, a);
   5852 #endif /* BCM_PETRA_SUPPORT */
   5853 
   5854     } else if (!sal_strcasecmp(c, "pvt_mon")) {
   5855 #if (defined(BCM_PETRA_SUPPORT) && defined(BCM_JERICHO_SUPPORT))
   5856         int interval = 2;
   5857         c = ARG_GET(a);
   5858 
   5859         if (c != NULL) {
   5860             if (isint(c)) {
   5861                 interval = parse_integer(c);
   5862             }
   5863         }
   5864         if ((bcm_rv = jer_mgmt_pvt_monitor_correction_enable(u, interval)) < 0) {
   5865             cli_out("%s: Unable to initialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv));
   5866             rv = CMD_FAIL;
   5867         }
   5868 #else
   5869         cli_out("Parameters error\n");
   5870         rv = CMD_FAIL;
   5871 #endif
   5872 
   5873         } else if (!sal_strcasecmp(c, "fgl_api")) {
   5874 #if (defined(BCM_PETRA_SUPPORT) && defined(BCM_FLAIR_SUPPORT))
   5875             if ((bcm_rv = jer_fabric_fgl_custom_api_init(u)) < 0) {
   5876                 cli_out("%s: Unable to initialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv));
   5877                 rv = CMD_FAIL;
   5878             }
   5879 #else
   5880             cli_out("Parameters error\n");
   5881             rv = CMD_FAIL;
   5882 #endif
   5883     } else { /* look for selective init */
   5884         uint32      flags = 0;
   5885         int module_num;
   5886         int found;
   5887 
   5888         if (!(SOC_CONTROL(u)->soc_flags & SOC_F_INITED)) {
   5889             cli_out("%s: Device %d was not initialized!"
   5890                     " Please try \"init soc\" first.\n",
   5891                     ARG_CMD(a), u);
   5892             return CMD_FAIL;
   5893         }
   5894 
   5895         if (bcm_attach_check(u) == BCM_E_UNIT) {
   5896             if ((bcm_rv = bcm_attach(u, NULL, NULL, u)) < 0) {
   5897             return CMD_FAIL;
   5898             }
   5899         }
   5900 
   5901         do {
   5902             found = 0;
   5903             for (module_num = 0; module_num < BCM_MODULE__COUNT; module_num++) {
   5904                 if (!sal_strcasecmp(bcm_module_name(u, module_num), c)) {
   5905                     found = 1;
   5906                     flags = (uint32) module_num;
   5907                     if ((bcm_rv = bcm_init_selective(u, flags)) < 0) {
   5908                         cli_out("%s: Unable to initialize %s (flags 0x%x): %s\n",
   5909                                 ARG_CMD(a), c, flags, bcm_errmsg(bcm_rv));
   5910                         rv = CMD_FAIL;
   5911                      }
   5912                     break;
   5913                 }
   5914             }
   5915             if (!found) {
   5916                 cli_out("Unknown module: %s\n", c);
   5917                 usage = 1;
   5918                 break;
   5919             }
   5920         } while ((c = ARG_GET(a)) != NULL);
   5921     }
   5922 
   5923     if (usage) {
   5924     cli_out("%s: Unknown option: %s\n", ARG_CMD(a), c);
   5925     rv = CMD_USAGE;
   5926     }
   5927 #ifdef BCM_BPROF_STATS
   5928     shr_bprof_stats_time_end();
   5929 #endif
   5930 
   5931     return(rv);
   5932 }
   5933 
   5934 #if defined(BCM_SAND_SUPPORT)
   5935 char sh_deinit_usage[] =
   5936     "Parameters: [soc|bcm|interrupt|rx_los]\n"
   5937     "\tPerforms various deinitializations (default is soc):\n\t"
   5938     "  soc - Deinitializes soc layer. Enable clean exit: unregister callbacks, free allocated memory...\n\t"
   5939     "  bcm - Deinitializes BCM driver. Enable clean exit: unregister callbacks, free allocated memory...\n\t"
   5940     "  interrupt - Deinitializes Interrupt Application Handler\n\t"
   5941     "  rx_los - Deinitializes RX LOS application\n\t"
   5942 #if defined(BCM_PETRA_SUPPORT) && defined(BCM_JERICHO_SUPPORT)
   5943     "  pvt_mon - Deinitializes PVT monitor correction thread"
   5944 #endif
   5945     "\n"
   5946     ;
   5947 
   5948 /*
   5949  * Function:     sh_deinit
   5950  * Purpose:    deInitialize the SW modules for a unit.
   5951  * Parameters:    u - unit number to operate on
   5952  *        a - args (none expected)
   5953  * Returns:    CMD_OK/CMD_FAIL.
   5954  */
   5955 cmd_result_t
   5956 sh_deinit(int u, args_t *a)
   5957 
   5958 {
   5959     cmd_result_t rv = CMD_OK;
   5960     int        bcm_rv;
   5961     char    *c;
   5962 
   5963     if (!sh_check_attached(ARG_CMD(a), u)) {
   5964     return(CMD_FAIL);
   5965     }
   5966 
   5967     c = ARG_GET(a);
   5968 
   5969     if (!c || !sal_strcasecmp(c, "soc")) {
   5970             if ((rv = sh_do_deinit(u)) < 0) {
   5971                 cli_out("%s: Unable to Deinitialize device: %d\n",ARG_CMD(a), u);
   5972             }
   5973     }else if (!sal_strcasecmp(c, "bcm")) {
   5974 
   5975         cli_out("Deinit BCM RX Thread.\n");
   5976         if ((bcm_rv = bcm_rx_stop(u, NULL)) < 0) {
   5977             cli_out("%s: Unable to Deinitialize BCM RX thread on unit %d: %s\n",ARG_CMD(a), u, bcm_errmsg(bcm_rv));
   5978             rv = CMD_FAIL;
   5979         }
   5980 
   5981         cli_out("Deinit BCM\n");
   5982         if ((bcm_rv = bcm_detach(u)) < 0) {
   5983             cli_out("%s: Unable to Deinitialize BCM driver on unit %d: %s\n",ARG_CMD(a), u, bcm_errmsg(bcm_rv));
   5984             rv = CMD_FAIL;
   5985         }
   5986     } else if (!sal_strcasecmp(c, "interrupt")) {
   5987 #if (defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)) && defined(INCLUDE_INTR)
   5988         if ((bcm_rv = device_interrupt_handler_appl_deinit(u)) < 0) {
   5989             cli_out("%s: Unable to Deinitialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv));
   5990             rv = CMD_FAIL;
   5991         }
   5992 
   5993 #else
   5994         cli_out("Parameters error\n");
   5995         rv = CMD_FAIL;
   5996 #endif
   5997     } else if (!sal_strcasecmp(c, "rx_los")) {
   5998 #if (defined(BCM_DFE_SUPPORT) || defined(BCM_PETRA_SUPPORT)) && defined(INCLUDE_INTR)
   5999         if ((bcm_rv = rx_los_unit_detach(u)) < 0) {
   6000             cli_out("%s: Unable to Deinitialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv));
   6001             rv = CMD_FAIL;
   6002         }
   6003 #else
   6004         cli_out("Parameters error\n");
   6005         rv = CMD_FAIL;
   6006 #endif
   6007     } else if (!sal_strcasecmp(c, "pvt_mon")) {
   6008 #if (defined(BCM_PETRA_SUPPORT) && defined(BCM_JERICHO_SUPPORT))
   6009         if ((bcm_rv = jer_mgmt_pvt_monitor_correction_disable(u)) < 0) {
   6010             cli_out("%s: Unable to Deinitialize %s: %s\n", ARG_CMD(a), c, bcm_errmsg(bcm_rv));
   6011             rv = CMD_FAIL;
   6012         }
   6013 #else
   6014         cli_out("Parameters error\n");
   6015         rv = CMD_FAIL;
   6016 #endif
   6017     } else {
   6018         cli_out("Parameters error\n");
   6019         rv = CMD_FAIL;
   6020     }
   6021 
   6022     return(rv);
   6023 }
   6024 
   6025 char sh_device_reset_usage[] =
   6026     "usage: DeviceReset <mode> <action>\n"
   6027     "\tPerform different device reset modes/actions.\n"
   6028     "\tParameters:\n"
   6029     "\tmode:\n"
   6030     "\t 0x1 - Hard Reset (Cimic CPS reset)\n"
   6031     "\t 0x2 - Blocks  Reset\n"
   6032     "\t 0x4 - Blocks Soft Reset (only inout)\n"
   6033     "\t 0x8 - Blocks Soft Ingress Reset (only inout)\n"
   6034     "\t 0x10 - Blocks Soft egress Reset (only inout)\n"
   6035     "\t 0x20 - Init Reset (Run soc init)\n"
   6036     "\t 0x40 - Reset + minimal init for access (only inout)\n"
   6037     "\t 0x80 - Enable Traffic (Disable action=1, Enable action=2)\n"
   6038 #ifdef COMPILER_STRING_CONST_LIMIT
   6039     "\nFull documentation cannot be displayed with -pendantic compiler\n";
   6040 #else
   6041     "\t 0x100 - Blocks and Fabric Soft Reset (only inout)\n"
   6042     "\t 0x200 - Blocks and Fabric Soft Ingress Reset (only inout)\n"
   6043     "\t 0x400 - Blocks and Fabric Soft egress Reset (only inout)\n"
   6044     "\t 0x800 - Blocks and Fabric direct Soft reset - directly change the registers\n"
   6045     "\taction:\n"
   6046     "\t 0x1 - In reset (Enable)\n"
   6047     "\t 0x2 - Out of Reset (Disable)\n"
   6048     "\t 0x4 - InOut of Reset\n"
   6049     "\n"
   6050     ;
   6051 #endif   /*COMPILER_STRING_CONST_LIMIT*/
   6052 
   6053 /*
   6054  * Function:     sh_device_reset
   6055  * Purpose:
   6056  *      Perform different device reset modes/actions.
   6057  * Parameters:
   6058  *      unit - Device unit #
   6059  *      mode - reset mode: hard reset, soft reset, init ....
   6060  *      action - im/out/inout.
   6061  * Returns:    CMD_OK/CMD_FAIL.
   6062  */
   6063 cmd_result_t
   6064 sh_device_reset(int u, args_t *a)
   6065 
   6066 {
   6067     cmd_result_t rv = CMD_OK;
   6068     int        bcm_rv, int_mode, int_action;
   6069     char    *mode, *action;
   6070 
   6071     if (!sh_check_attached(ARG_CMD(a), u)) {
   6072     return(CMD_FAIL);
   6073     }
   6074 
   6075      mode = ARG_GET(a);
   6076      if (!mode) {
   6077          cli_out("%s: mode parameter missing: %s\n", ARG_CMD(a), mode);
   6078         rv = CMD_USAGE;
   6079      }
   6080      int_mode = sal_ctoi(mode, 0);
   6081 
   6082      action = ARG_GET(a);
   6083      if (!action) {
   6084          cli_out("%s: action parameter missing: %s\n", ARG_CMD(a), action);
   6085         rv = CMD_USAGE;
   6086      }
   6087      int_action = sal_ctoi(action, 0);
   6088 
   6089      if ((bcm_rv = sh_do_device_reset(u, int_mode, int_action)) < 0) {
   6090          cli_out("%s: Unable to Deinitialize BCM driver on unit %d: %s\n",ARG_CMD(a), u, bcm_errmsg(bcm_rv));
   6091          rv = CMD_FAIL;
   6092      }
   6093 
   6094     return(rv);
   6095 }
   6096 #endif
   6097 
   6098 char sh_expr_usage[] =
   6099     "Parameters: <c-style arithmetic expression>\n\t"
   6100     "Evaluates an expression and sets the result as the return value.\n";
   6101 
   6102 cmd_result_t
   6103 sh_expr(int u, args_t *a)
   6104 /*
   6105  * Function:     sh_expr
   6106  * Purpose:    Expression evaluation support
   6107  * Parameters:    u - unit #
   6108  *        a - pointer to args, concatenates them if multiple
   6109  * Returns:    CMD_OK if not executed, or result of last command execution.
   6110  */
   6111 {
   6112     char        expr[128];
   6113     char        *c;
   6114     INFIX_TYPE        result;
   6115 
   6116     c = ARG_GET(a);
   6117 
   6118     if (c == NULL) {
   6119     return CMD_USAGE;
   6120     }
   6121 
   6122     sal_strncpy(expr, c, sizeof (expr));
   6123     expr[sizeof (expr) - 1] = '\0';
   6124 
   6125     while ((c = ARG_GET(a)) != NULL) {
   6126     int len = sal_strlen(expr);
   6127     sal_strncpy(expr + len, c, sizeof (expr) - len);
   6128     expr[sizeof (expr) - 1] = '\0';
   6129     }
   6130 
   6131     if (infix_eval(expr, &result) < 0) {
   6132     cli_out("Invalid expression: %s\n", expr);
   6133     return CMD_FAIL;
   6134     }
   6135 
   6136     return (int)result;
   6137 }
   6138 
   6139 char sh_if_usage[] =
   6140     "Parameters: <condition> [<command> ... [else <command> ...]]\n"
   6141 #ifndef COMPILER_STRING_CONST_LIMIT
   6142     "\tExecute a list of command lines(s) only if <condition> is a\n\t"
   6143     "non-zero integer or a successful sub-command-line.  Command lines\n\t"
   6144     "of more than one word must be quoted, for example:\n\t"
   6145     "\tif 1 \"echo hello\" \"echo world\"\n\t"
   6146     "will display hello and world.  Simple left-to-right boolean\n\t"
   6147     "operations are permitted, for example:\n\t"
   6148     "\tif $?quickturn && !\"bist arl\" \"echo BIST failed\"\n\t"
   6149     "Processing of multiple command lines ends when one of them fails\n\t"
   6150     "unless IFError is set to FALSE (see help on set for more info).\n\t"
   6151     "The return value from this command is the result of the last\n\t"
   6152     "executed command.\n"
   6153 #endif
   6154     ;
   6155 
   6156 static int
   6157 if_cond(int u, args_t *a)
   6158 {
   6159     int            negate = FALSE, cond;
   6160     char        *c;
   6161 
   6162     if ((c = ARG_GET(a)) == NULL) {
   6163     cli_out("%s: missing test condition\n", ARG_CMD(a));
   6164     return -1;
   6165     } else {
   6166     for (negate = FALSE; *c == '!'; negate = !negate, c++) {
   6167         ;
   6168     }
   6169 
   6170     if (*c == 0) {
   6171         cond = 0;
   6172     } else {
   6173         cond = (sh_process_command(u, c) == CMD_OK);
   6174     }
   6175 
   6176     return negate ? !cond : cond;
   6177     }
   6178 }
   6179 
   6180 cmd_result_t
   6181 sh_if(int u, args_t *a)
   6182 /*
   6183  * Function:     sh_if
   6184  * Purpose:    Basic "if" support.
   6185  * Parameters:    u - unit #
   6186  *        a - pointer to args, expects <bool> <cmd list>
   6187  * Returns:    CMD_OK if not executed, or result of last command execution.
   6188  */
   6189 {
   6190     cmd_result_t    rv = CMD_OK;
   6191     char        *c;
   6192     int            cond;
   6193 
   6194  again:
   6195     if ((cond = if_cond(u, a)) < 0) {
   6196     return CMD_USAGE;
   6197     }
   6198 
   6199     if (!cond) {
   6200     if ((c = ARG_GET(a)) != NULL && strcmp(c, "||") == 0) {
   6201         goto again;
   6202     }
   6203     while (c != NULL && sal_strcasecmp(c, "else") != 0) {
   6204         c = ARG_GET(a);
   6205     }
   6206     if (c == NULL) {
   6207         return rv;
   6208     }
   6209     }
   6210 
   6211     while ((rv == CMD_OK || !sh_set_iferror)
   6212        && (c = ARG_GET(a)) != NULL) {
   6213     if (strcmp(c, "||") == 0) {
   6214         if (if_cond(u, a) < 0) {
   6215         return CMD_USAGE;
   6216         }
   6217     } else if (strcmp(c, "&&") == 0) {
   6218         goto again;
   6219     } else if (sal_strcasecmp(c, "else") == 0) {
   6220         break;
   6221     } else {
   6222         rv = sh_process_command(u, c);
   6223     }
   6224     }
   6225 
   6226     ARG_DISCARD(a);
   6227     return rv;
   6228 }
   6229 
   6230 #ifndef NO_SAL_APPL
   6231 
   6232 static    cmd_result_t
   6233 sh_do_copy(args_t *a, char *s_src, char *s_dst)
   6234 /*
   6235  * Function:     sh_do_copy
   6236  * Purpose:    Perform actual copy of data from source to destination.
   6237  * Parameters:    a - args (Used only for ARG_CMD)
   6238  *        s_src - file name to copy from
   6239  *        s_dst - file name to copy to.
   6240  * Returns:    CMD_OK/CMD_FAIL
   6241  */
   6242 {
   6243 #ifdef NO_FILEIO
   6244     return -1;
   6245 #else
   6246     cmd_result_t volatile rv = CMD_FAIL;
   6247 #ifndef NO_CTRL_C
   6248     jmp_buf    ctrl_c;
   6249 #endif 
   6250     FILE * volatile f_src = NULL,    /* Source/destination FILE */
   6251          * volatile f_dst = NULL;
   6252 
   6253     if (
   6254 #ifndef NO_CTRL_C
   6255             !setjmp(ctrl_c)
   6256 #else
   6257             TRUE
   6258 #endif    
   6259             ) {
   6260         char    buf[1024];
   6261         int     r, w;
   6262 
   6263 #ifndef NO_CTRL_C
   6264         sh_push_ctrl_c(&ctrl_c);
   6265 #endif
   6266         
   6267         if ((f_src = sal_fopen(s_src, "rb")) == NULL) {
   6268             cli_out("%s: Error: unable to open input file: %s\n",
   6269                     ARG_CMD(a), s_src);
   6270             goto done;
   6271         }
   6272 
   6273         if ((f_dst = sal_fopen(s_dst, "wb")) == NULL) {
   6274             cli_out("%s: Error: unable to open output file: %s\n",
   6275                     ARG_CMD(a), s_dst);
   6276             goto done;
   6277         }
   6278 
   6279         while ((r = sal_fread(buf, 1, sizeof(buf), (FILE *) f_src)) > 0)
   6280             if ((w = fwrite(buf, 1, r, (FILE *) f_dst)) != r) {
   6281                 cli_out("%s: Error writing %s\n", ARG_CMD(a), s_dst);
   6282                 goto done;
   6283             }
   6284 
   6285         if (r < 0) {
   6286             cli_out("%s: Error reading %s\n", ARG_CMD(a), s_src);
   6287             goto done;
   6288         }
   6289 
   6290         rv = CMD_OK;
   6291     } else {
   6292         rv = CMD_INTR;
   6293     }
   6294 
   6295  done:
   6296 #ifndef NO_CTRL_C
   6297     sh_pop_ctrl_c();
   6298 #endif
   6299     if (f_src) {
   6300     (void) sal_fclose((FILE *)f_src);
   6301     }
   6302     if (f_dst) {
   6303     if (sal_fclose((FILE *)f_dst)) {
   6304         cli_out("%s: Error closing %s\n", ARG_CMD(a), s_dst);
   6305         rv = CMD_FAIL;
   6306     }
   6307     if (rv < 0) {
   6308         if (sal_remove(s_dst) < 0) {
   6309         cli_out("%s: Error removing partial output file %s\n",
   6310                 ARG_CMD(a), s_dst);
   6311         }
   6312     }
   6313     }
   6314     return(rv);
   6315 #endif /* NO_FILEIO */
   6316 }
   6317 
   6318 char sh_copy_usage[] =
   6319     "Parameters: <source> [<destination>]\n\t"
   6320     "Copy a file from one location to another, intended to copy\n\t"
   6321     "to/from flash, but any valid source and destination file is valid.\n\t"
   6322     "If destination is omitted, the default destination is a file of\n\t"
   6323     "the same name in the current working directory.\n";
   6324 
   6325 cmd_result_t
   6326 sh_copy(int u, args_t *a)
   6327 /*
   6328  * Function:     cmd_copy
   6329  * Purpose:    Copy a file from one location to another, intended to copy
   6330  *        to/from flash device but as long as the targets are
   6331  *        accessible, it will work.
   6332  * Parameters:    u - unit (ignored)
   6333  *        a - arguments, expects "source" "destination", no destination
   6334  *            and it will copy to console.
   6335  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE.
   6336  */
   6337 {
   6338 #ifdef NO_FILEIO
   6339     return -1;
   6340 #else
   6341     char *s_src,
   6342          *s_dst; /* Source destination names */
   6343 
   6344     COMPILER_REFERENCE(u);
   6345 
   6346     if ((ARG_CNT(a) == 0) || (ARG_CNT(a) > 2)) {
   6347     return(CMD_USAGE);
   6348     }
   6349 
   6350     /*
   6351      * Figure out source/destination names, if no destination then use
   6352      * filename without path from source in current working directory.
   6353      */
   6354 
   6355     s_src = ARG_GET(a);
   6356     s_dst = ARG_GET(a);            /* May be NULL */
   6357 
   6358     if (!s_dst) {            /* First, look back for '/' */
   6359     if ((s_dst = sal_strrchr(s_src, '/')) != NULL) {
   6360         s_dst++;
   6361     }
   6362     }
   6363 
   6364     if (!s_dst) {            /* Look back for ':' */
   6365     if ((s_dst = sal_strrchr(s_src, ':')) != NULL) {
   6366         s_dst++;
   6367     }
   6368     }
   6369 
   6370     if (!s_dst) {
   6371     cli_out("%s: Error: No file to copy TO\n", ARG_CMD(a));
   6372     return(CMD_FAIL);
   6373     }
   6374 
   6375     return(sh_do_copy(a, s_src, s_dst));
   6376 #endif /* NO_FILEIO */
   6377 }
   6378 
   6379 char sh_remove_usage[] =
   6380     "Parameters: <file>\n\t"
   6381     "Remove a file from a filesystem\n";
   6382 
   6383 cmd_result_t
   6384 sh_remove(int u, args_t *a)
   6385 /*
   6386  * Function:     sh_remove
   6387  * Purpose:    Remove a file from a file system.
   6388  * Parameters:    u - unit (ignored)
   6389  *        a - arguments, expects "filename", or a serial of file names.
   6390  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE.
   6391  */
   6392 {
   6393 #ifdef NO_FILEIO
   6394     return -1;
   6395 #else
   6396     char    *c;
   6397     int        rv;
   6398     cmd_result_t result = CMD_OK;
   6399 
   6400     COMPILER_REFERENCE(u);
   6401 
   6402     if (0 == ARG_CNT(a)) {
   6403     return(CMD_USAGE);
   6404     }
   6405     while ((c = ARG_GET(a)) != NULL) {
   6406     rv = sal_remove(c);
   6407     if (rv) {
   6408         cli_out("%s: Warning: failed to remove file: %s\n",
   6409                 ARG_CMD(a), c);
   6410         result = CMD_FAIL;
   6411     }
   6412     }
   6413     return(result);
   6414 #endif /* NO_FILEIO */
   6415 }
   6416 
   6417 char sh_rename_usage[] =
   6418     "Parameters: <file_old> <file_new>\n\t"
   6419     "Rename a file on a filesystem.  For FTP, the new file name\n\t"
   6420     "must be a base name only.  Can't rename across file systems.\n";
   6421 
   6422 cmd_result_t
   6423 sh_rename(int u, args_t *a)
   6424 /*
   6425  * Function:     sh_rename
   6426  * Purpose:    Rename a file on a file system.
   6427  * Parameters:    u - unit (ignored)
   6428  *        a - arguments
   6429  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE.
   6430  */
   6431 {
   6432 #ifdef NO_FILEIO
   6433     return -1;
   6434 #else
   6435     char    *file_old, *file_new;
   6436     cmd_result_t result = CMD_OK;
   6437 
   6438     COMPILER_REFERENCE(u);
   6439 
   6440     if (2 != ARG_CNT(a)) {
   6441     return(CMD_USAGE);
   6442     }
   6443 
   6444     file_old = ARG_GET(a);
   6445     file_new = ARG_GET(a);
   6446 
   6447     if (sal_rename(file_old, file_new) < 0) {
   6448     cli_out("%s: Warning: failed to rename file: %s\n",
   6449             ARG_CMD(a), file_old);
   6450     result = CMD_FAIL;
   6451     }
   6452 
   6453     return(result);
   6454 #endif /* NO_FILEIO */
   6455 }
   6456 
   6457 char sh_mkdir_usage[] =
   6458     "Parameters: <path>\n\t"
   6459     "Make a directory.\n";
   6460 
   6461 cmd_result_t
   6462 sh_mkdir(int u, args_t *a)
   6463 /*
   6464  * Function:     sh_mkdir
   6465  * Purpose:    Make a directory.
   6466  * Parameters:    u - unit (ignored)
   6467  *        a - arguments
   6468  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE.
   6469  */
   6470 {
   6471     char    *path;
   6472     cmd_result_t result = CMD_OK;
   6473 
   6474     COMPILER_REFERENCE(u);
   6475 
   6476     if (ARG_CNT(a) != 1) {
   6477     return(CMD_USAGE);
   6478     }
   6479 
   6480     path = ARG_GET(a);
   6481 
   6482     if (sal_mkdir(path) < 0) {
   6483     cli_out("%s: Warning: failed to create directory: %s\n",
   6484             ARG_CMD(a), path);
   6485     result = CMD_FAIL;
   6486     }
   6487 
   6488     return(result);
   6489 }
   6490 
   6491 char sh_rmdir_usage[] =
   6492     "Parameters: <path>\n\t"
   6493     "Remove a directory.\n";
   6494 
   6495 cmd_result_t
   6496 sh_rmdir(int u, args_t *a)
   6497 /*
   6498  * Function:     sh_rmdir
   6499  * Purpose:    Make a directory.
   6500  * Parameters:    u - unit (ignored)
   6501  *        a - arguments
   6502  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE.
   6503  */
   6504 {
   6505     char    *path;
   6506     cmd_result_t result = CMD_OK;
   6507 
   6508     COMPILER_REFERENCE(u);
   6509 
   6510     if (ARG_CNT(a) != 1) {
   6511     return(CMD_USAGE);
   6512     }
   6513 
   6514     path = ARG_GET(a);
   6515 
   6516     if (sal_rmdir(path) < 0) {
   6517     cli_out("%s: Warning: failed to remove directory: %s\n",
   6518             ARG_CMD(a), path);
   6519     result = CMD_FAIL;
   6520     }
   6521 
   6522     return(result);
   6523 }
   6524 
   6525 char sh_date_usage[] =
   6526     "Parameters: \"YYYY/MM/DD hh:mm:ss\"\n\t"
   6527     "If no options are given, displays the current date.  If date is\n\t"
   6528     "specified in format shown (quotes required), sets the current date.\n\t"
   6529     "Date must be in local time according to the time zone.\n";
   6530 
   6531 #ifndef __KERNEL__ 
   6532 #if defined(UNIX)
   6533 static int _date_val(char **sp)
   6534 {
   6535     int val = 0;
   6536     while (**sp && ! isdigit((unsigned) **sp))
   6537     (*sp)++;
   6538     while (isdigit((unsigned) **sp))
   6539     val = val * 10 + ((int) *(*sp)++ - '0');
   6540     return val;
   6541 }
   6542 #endif /* defined(UNIX) */
   6543 #endif
   6544 
   6545 cmd_result_t
   6546 sh_date(int u, args_t *a)
   6547 {
   6548 #ifndef __KERNEL__    
   6549 #if defined(UNIX) 
   6550     char               *c;
   6551     struct tm        tm, *tmp;
   6552     sal_time_t        val;
   6553     char        buf[64];
   6554 
   6555     COMPILER_REFERENCE(u);
   6556 
   6557     sal_memset(&tm, 0, sizeof(struct tm));
   6558     if ((c = ARG_GET(a)) != 0) {
   6559     if (ARG_GET(a))
   6560         return CMD_USAGE;
   6561 
   6562     tm.tm_year = _date_val(&c) - 1900;
   6563     tm.tm_mon = _date_val(&c) - 1;
   6564     tm.tm_mday = _date_val(&c);
   6565     tm.tm_hour = _date_val(&c);
   6566     tm.tm_min = _date_val(&c);
   6567     tm.tm_sec = _date_val(&c);
   6568 
   6569     val = sal_mktime(&tm);
   6570 
   6571     if (sal_date_set(&val) < 0)
   6572         return CMD_FAIL;
   6573     }
   6574 
   6575     if (sal_date_get(&val) < 0)
   6576     return CMD_FAIL;
   6577 
   6578     tmp = sal_localtime((time_t *) &val);
   6579 
   6580     sal_strftime(buf, sizeof (buf), "%Y/%m/%d %H:%M:%S %Z", tmp);
   6581 
   6582     cli_out("%s\n", buf);
   6583 
   6584 #endif /* defined(UNIX) */
   6585 #endif /* !defined(__KERNEL__) */
   6586     return CMD_OK;
   6587 }
   6588 
   6589 #endif /* NO_SAL_APPL */
   6590 
   6591 char sh_time_usage[] =
   6592     "Parameters: [<command> ...]\n\t"
   6593     "Runs command(s) and displays how much time they took to run.\n\t"
   6594     "Example: time \"sleep 1\" \"sleep 2\"\n\t"
   6595     "If no command is specified, displays the current time.\n";
   6596 
   6597 #ifdef    COMPILER_HAS_DOUBLE
   6598 #define    GETTIME    sal_time_double()
   6599 #define    DCLTIME    double
   6600 #define    FMTTIME    "%.6f sec"
   6601 #else
   6602 #define    GETTIME    sal_time_usecs()
   6603 #define    DCLTIME    sal_usecs_t
   6604 #define    FMTTIME    "%u usec"
   6605 #endif
   6606 
   6607 cmd_result_t
   6608 sh_time(int u, args_t *a)
   6609 {
   6610     int            rv = CMD_OK;
   6611     char        *c;
   6612     DCLTIME        t0, ts, te;
   6613     int            ncmd = 0;
   6614 
   6615     if (ARG_CNT(a) == 0) {
   6616     cli_out(FMTTIME "\n", GETTIME);
   6617     return CMD_OK;
   6618     }
   6619 
   6620     t0 = ts = te = 0;
   6621     while (rv == CMD_OK && (c = ARG_GET(a)) != NULL) {
   6622     ts = GETTIME;
   6623     if (ncmd == 0) {
   6624         t0 = ts;
   6625     }
   6626     if ((rv = sh_process_command(u, c)) != CMD_OK) {
   6627         break;
   6628     }
   6629     ncmd++;
   6630     te = GETTIME;
   6631     cli_out("time{%s} = " FMTTIME "\n", c, te - ts);
   6632     }
   6633 
   6634     if (ncmd > 1) {
   6635     cli_out("time{TOTAL} = " FMTTIME "\n", te - t0);
   6636     }
   6637 
   6638     return rv;
   6639 }
   6640 
   6641 #undef    GETTIME
   6642 #undef    DCLTIME
   6643 #undef    FMTTIME
   6644 
   6645 
   6646 #ifndef NO_SAL_APPL
   6647 
   6648 char sh_flashinit_usage[] =
   6649     "Parameters: [format=yes|no] [loader=<os-loader>] [OS=<os_file>]\n\t"
   6650     "Format (clear) the flash disk contents if a flash disk is available\n\t"
   6651     "The command ALWAYS prompts for confirmation from the console.\n";
   6652 
   6653 cmd_result_t
   6654 sh_flashinit(int u, args_t *a)
   6655 /*
   6656  * Function:     sh_flashinit
   6657  * Purpose:    Initialize flash disk, and/or copy files to the flash.
   6658  * Parameters:    u - unit number (ignored)
   6659  *        a - arguments.
   6660  * Returns:    CMD_OK, CMD_USAGE, CMD_FAIL.
   6661  */
   6662 {
   6663     cmd_result_t    rv = CMD_OK;
   6664     char        *file_loader, *file_os;
   6665     int            format;
   6666     parse_table_t    pt;
   6667 
   6668     COMPILER_REFERENCE(u);
   6669 
   6670     parse_table_init(u, &pt);
   6671     parse_table_add(&pt, "Format", PQ_BOOL, 0, &format, 0);
   6672     parse_table_add(&pt, "Loader", PQ_STRING, 0, &file_loader, 0);
   6673     parse_table_add(&pt, "OS", PQ_STRING, 0, &file_os, 0);
   6674 
   6675     if (0 == ARG_CNT(a)) {
   6676     parse_arg_eq_done(&pt);
   6677     return(CMD_USAGE);
   6678     }
   6679     if (0 > parse_arg_eq(a, &pt)) {
   6680     cli_out("%s: Error: Invalid option: %s\n", ARG_CMD(a), ARG_CUR(a));
   6681     parse_arg_eq_done(&pt);
   6682     return(CMD_FAIL);
   6683     } else if (0 != ARG_CNT(a)) {
   6684     cli_out("%s: Error: extra options starting with \"%s\"\n",
   6685             ARG_CMD(a), ARG_CUR(a));
   6686     parse_arg_eq_done(&pt);
   6687     return(CMD_FAIL);
   6688     }
   6689 
   6690 #ifdef ZT6501
   6691     if (file_loader && *file_loader) {
   6692     cli_out("%s: Warning: Writing loader will re-format flash disk\n",
   6693             ARG_CMD(a));
   6694     format = TRUE;
   6695     }
   6696 #endif /* ZT6501 */
   6697 
   6698     if (format) {
   6699     char    input[32];
   6700 
   6701     cli_out("%s: Warning: Formatting flash will destroy all files\n",
   6702             ARG_CMD(a));
   6703 
   6704     if (NULL == sal_readline("OK to continue (yes/no)? ",
   6705                  input, sizeof(input), "no")) {
   6706         rv = CMD_FAIL;
   6707     } else if (sal_strncasecmp("yes", input, sal_strlen(input))) {
   6708         rv = CMD_FAIL;
   6709     }
   6710     }
   6711 
   6712     /*
   6713      * At this point, if rv is still CMD_OK, then go ahead and do
   6714      * what was asked.
   6715      */
   6716     if (CMD_OK == rv) {
   6717     if (file_loader && *file_loader &&
   6718         (0 != sal_flash_boot(file_loader))) {/* Set boot loader image */
   6719         cli_out("%s: Error: Unable to flash loader image: %s\n",
   6720                 ARG_CMD(a), file_loader);
   6721         rv = CMD_FAIL;
   6722     }
   6723     if ((CMD_OK == rv ) && format && (0 != sal_flash_init(TRUE))) {
   6724         /* Format file system  */
   6725         cli_out("%s: Error: Unable to Initialize flash file system\n",
   6726                 ARG_CMD(a));
   6727         rv = CMD_FAIL;
   6728     }
   6729     if ((CMD_OK == rv) && file_os && *file_os) { /* Load OS file */
   6730 #define VX_BOOT_FILE "flash:bcm"
   6731         rv = sh_do_copy(a, file_os, VX_BOOT_FILE);
   6732     }
   6733     }
   6734     parse_arg_eq_done(&pt);
   6735     return(rv);
   6736 }
   6737 
   6738 char sh_flashsync_usage[] =
   6739     "Sync up the flash disk contents with dosFS (dosFS2 only)\n";
   6740 
   6741 cmd_result_t
   6742 sh_flashsync(int u, args_t *a)
   6743 /*
   6744  * Function:    sh_flashsync
   6745  * Purpose:     Sync up the flash disk contents with dosFS
   6746  * Parameters:  u - unit number (ignored)
   6747  *              a - arguments.
   6748  * Returns:     CMD_OK, CMD_USAGE, CMD_FAIL.
   6749  */
   6750 {
   6751     cmd_result_t rv = CMD_OK;
   6752 
   6753     COMPILER_REFERENCE(u);
   6754 
   6755 #if defined(__ECOS)
   6756     if (sal_flash_sync() < 0)
   6757         rv = CMD_FAIL;
   6758 #endif
   6759 
   6760     return(rv);
   6761 }
   6762 
   6763 char sh_cd_usage[] =
   6764     "Parameters: [[-sethome] <directory>]\n\t"
   6765     "Change current working directory. <directory> must be of the\n\t"
   6766     "form \"usr%password@host:<path>\" or \"/flash/<directory>\" for\n\t"
   6767     "FTP to remote system or local flash disk respectively.\n\t"
   6768     "If the target directory does not exist, this command may still\n\t"
   6769     "succeed, but attempts to access files may fail.\n\t"
   6770     "The -sethome option sets the new directory to be the home directory.\n";
   6771 
   6772 /*ARGSUSED*/
   6773 cmd_result_t
   6774 sh_cd(int u, args_t *a)
   6775 /*
   6776  * Function:     sh_cd
   6777  * Purpose:    Change directory
   6778  * Parameters:    u - unit number (ignored)
   6779  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE
   6780  */
   6781 {
   6782     char    *c;
   6783     int        sethome = 0;
   6784 
   6785     COMPILER_REFERENCE(u);
   6786 
   6787     c = ARG_GET(a);
   6788 
   6789     if (c != NULL && strcmp(c, "-sethome") == 0) {
   6790     sethome = 1;
   6791     c = ARG_GET(a);
   6792     }
   6793 
   6794     if (sal_cd(c)) {        /* NULL changes to "home" dir */
   6795     if (c == NULL) {
   6796         cli_out("%s: Invalid home directory\n", ARG_CMD(a));
   6797     } else {
   6798         cli_out("%s: Invalid directory: %s\n", ARG_CMD(a), c);
   6799     }
   6800 
   6801     return(CMD_FAIL);
   6802     }
   6803 
   6804     if (sethome && c != NULL && sal_homedir_set(c) < 0) {
   6805     cli_out("%s: Unable to set home directory: %s\n", ARG_CMD(a), c);
   6806     return CMD_FAIL;
   6807     }
   6808 
   6809     return(CMD_OK);
   6810 }
   6811 
   6812 cmd_result_t
   6813 sh_do_more(FILE *f)
   6814 /*
   6815  * Function:     sh_do_more
   6816  * Purpose:    Copy a file to console, stopping line "more".
   6817  * Parameters:    f - pointer to FILE to read from.
   6818  * Returns:    CMD_OK
   6819  */
   6820 {
   6821 #ifdef NO_FILEIO
   6822     return -1;
   6823 #else
   6824     int        line, next_stop;
   6825     char    buf[1024];
   6826 
   6827     line = 0;
   6828     next_stop = sh_set_more_lines;
   6829 
   6830     while (sal_fgets(buf, sizeof(buf) - 1, f)) {
   6831     /* Dump data */
   6832     cli_out("%s", buf);
   6833     if (++line == next_stop) {
   6834         extern char readchar(char *s);
   6835         int c;
   6836         cli_out(SAL_VT100_SO
   6837                 "Line: %d ----- 'q' to quit, any key to continue -----"
   6838                 SAL_VT100_SE,
   6839                 line);
   6840         c = sal_readchar("");
   6841         cli_out("\r" SAL_VT100_CE);
   6842         switch (c) {
   6843         case EOF:
   6844         case 'q':
   6845         case 'Q':
   6846         return(CMD_OK);
   6847         case '\r':
   6848         case '\n':
   6849         next_stop++;
   6850         break;
   6851         default:
   6852         next_stop += sh_set_more_lines;
   6853         break;            /* Just keep going */
   6854         }
   6855     }
   6856     }
   6857     return(CMD_OK);
   6858 #endif /* NO_FILEIO */
   6859 }
   6860 
   6861 char sh_more_usage[] =
   6862     "Parameters: <file> ...\n\t"
   6863     "Copy the listed files to the console, stopping after a set number\n\t"
   6864     "of lines. The default number of lines is 20, but it may be changed\n\t"
   6865     "by setting \"MoreLines\" to a different number. \"help set\" for\n\t"
   6866     "more information\n";
   6867 
   6868 cmd_result_t
   6869 sh_more(int u, args_t *a)
   6870 /*
   6871  * Function:     sh_more
   6872  * Purpose:    More a file to the TTY.
   6873  * Parameters:    u - unit (ignored)
   6874  *        a - args, each of the files to be displayed.
   6875  * Returns:    CMD_OK/CMD_FAIL/CMD_USAGE
   6876  */
   6877 {
   6878 #ifdef NO_FILEIO
   6879     return -1;
   6880 #else
   6881 #ifndef NO_CTRL_C
   6882     jmp_buf    ctrl_c;
   6883 #endif
   6884     volatile cmd_result_t rv = CMD_OK;
   6885     FILE * volatile f = NULL;
   6886     char    *c;
   6887 
   6888     COMPILER_REFERENCE(u);
   6889 
   6890     if (0 == ARG_CNT(a)) {
   6891     return(CMD_USAGE);
   6892     }
   6893 
   6894     /*
   6895      * Try to catch ^C to avoid leaving file open if more is ^C'd.
   6896      * There are still a number of unlikely race conditions here.
   6897      */
   6898 
   6899     if (
   6900 #ifndef NO_CTRL_C
   6901            !setjmp(ctrl_c)
   6902 #else
   6903            TRUE
   6904 #endif
   6905            ) {
   6906 #ifndef NO_CTRL_C
   6907         sh_push_ctrl_c(&ctrl_c);
   6908 #endif
   6909 
   6910         while ((CMD_OK == rv) && (NULL != (c = ARG_GET(a)))) {
   6911             f = sal_fopen(c, "r");
   6912             if (!f) {
   6913                 cli_out("%s: Error: Unable to open file: %s\n",
   6914                         ARG_CMD(a), c);
   6915                 rv = CMD_FAIL;
   6916             } else {
   6917                 rv = sh_do_more((FILE *)f);
   6918                 sal_fclose((FILE *)f);        /* Cast for un-volatile */
   6919                 f = NULL;
   6920             }
   6921         }
   6922     } else if (f) {
   6923         sal_fclose((FILE *)f);
   6924         f = NULL;
   6925         rv = CMD_INTR;
   6926     }
   6927 
   6928 #ifndef NO_CTRL_C
   6929     sh_pop_ctrl_c();
   6930 #endif
   6931     return(rv);
   6932 #endif /* NO_FILEIO */
   6933 }
   6934 
   6935 char sh_write_usage[] =
   6936     "Parameters: <file> [<word> ...]\n\t"
   6937     "Write data to a file. If only file is given, the console is read\n\t"
   6938     "until EOF (CTRL-D) is seen. Otherwise, all the words on the\n\t"
   6939     "command line are written with a single \"Space\" between them\n";
   6940 
   6941 cmd_result_t
   6942 sh_write(int u, args_t *a)
   6943 /*
   6944  * Function:     cmd_write
   6945  * Purpose:    Write words into a file.
   6946  * Parameters:    u - SOC unit number, IGNORED.
   6947  *        a - pointer to args, expects filename and optional text.
   6948  * Returns:    CMD_OK, CMD_FAIL.
   6949  */
   6950 {
   6951 #ifdef NO_FILEIO
   6952     return -1;
   6953 #else
   6954 #ifndef NO_CTRL_C
   6955     jmp_buf    ctrl_c;
   6956 #endif
   6957     volatile cmd_result_t rv = CMD_OK;
   6958     FILE * volatile f = NULL;
   6959     char    *c, *fname;
   6960     char    input[512];
   6961 
   6962     COMPILER_REFERENCE(u);
   6963 
   6964     input[sizeof(input) - 1] = '\0';
   6965 
   6966     if (0 == ARG_CNT(a)) {
   6967     return(CMD_USAGE);
   6968     }
   6969 
   6970     /*
   6971      * Try to catch ^C to avoid leaving file open if more is ^C'd.
   6972      * There are still a number of unlikely race conditions here.
   6973      */
   6974 
   6975     if (
   6976 #ifndef NO_CTRL_C
   6977             !setjmp(ctrl_c)
   6978 #else
   6979             TRUE
   6980 #endif
   6981             ) {
   6982 #ifndef NO_CTRL_C
   6983         sh_push_ctrl_c(&ctrl_c);
   6984 #endif
   6985 
   6986         fname = ARG_GET(a);
   6987 
   6988         /* If no args, prompt user, otherwise, just write them out */
   6989 
   6990         f = sal_fopen(fname, "w");
   6991         if (!f) {
   6992             cli_out("%s: Error: Unable to open file: %s\n",
   6993                     ARG_CMD(a), fname);
   6994             rv = CMD_FAIL;
   6995         } else if (0 == ARG_CNT(a)) {    /* Interactive */
   6996             while((sal_readline("< ", input, sizeof(input) - 1, NULL))) {
   6997                 sal_fprintf(f, "%s\n", input);
   6998             }
   6999         } else {
   7000             int    first = TRUE;
   7001 
   7002             while ((c = ARG_GET(a)) != NULL) {
   7003                 sal_fprintf((FILE *)f, "%s%s", first ? "" : " ", c);
   7004                 first = FALSE;
   7005             }
   7006             sal_fprintf((FILE *)f, "\n");
   7007         }
   7008     } else {
   7009         rv = CMD_INTR;
   7010     }
   7011     if (f) {
   7012         sal_fclose((FILE *)f);
   7013         f = NULL;
   7014     }
   7015 
   7016 #ifndef NO_CTRL_C
   7017     sh_pop_ctrl_c();
   7018 #endif
   7019     return(rv);
   7020 #endif /* NO_FILEIO */
   7021 }
   7022 
   7023 
   7024 #endif /* NO_SAL_APPL */
   7025 
   7026 /*
   7027  * Background-command Support
   7028  */
   7029 
   7030 #define _MAX_BG_TASKS 10
   7031 
   7032 typedef struct {
   7033     int unit;
   7034     int idx;
   7035     int job;
   7036     sal_thread_t thread_id;
   7037     sal_sem_t sem;
   7038     char cmd[ARGS_BUFFER];
   7039 } _bg_job_t;
   7040 
   7041 static _bg_job_t    *_bg_jobs[SOC_MAX_NUM_DEVICES][_MAX_BG_TASKS];
   7042 static int        _bg_job_count;
   7043 
   7044 /*
   7045  * Run the background thread
   7046  */
   7047 static void
   7048 _bg_cmd(void *cookie)
   7049 {
   7050     _bg_job_t    *info;
   7051     int        rv;
   7052 
   7053     info = (_bg_job_t *)cookie;
   7054 
   7055     sal_sem_take(info->sem, sal_sem_FOREVER);
   7056 
   7057     switch((rv = sh_process_command(info->unit, info->cmd))) {
   7058     case CMD_OK:
   7059     case CMD_EXIT:
   7060     case CMD_INTR:
   7061         break;
   7062     default:
   7063         cli_out("bg: error in job %d: code %d\n", info->job, rv);
   7064         break;
   7065     }
   7066 
   7067     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   7068                 (BSL_META_U(info->unit,
   7069                             "bg: end of job %d\n"), info->job));
   7070 
   7071     sal_sem_destroy(info->sem);
   7072     _bg_jobs[info->unit][info->idx] = NULL;
   7073     sal_free(info);
   7074 
   7075     sal_thread_exit(rv);
   7076 }
   7077 
   7078 void
   7079 sh_bg_init(void)
   7080 {
   7081     sal_memset(_bg_jobs, 0, sizeof(_bg_jobs));
   7082 }
   7083 
   7084 typedef void (*void_fn_ptr)(void *);
   7085 
   7086 char sh_bg_usage[] =
   7087     "bg \"<cmd>\"\n"
   7088     "    Execute cmd in the background\n";
   7089 
   7090 cmd_result_t
   7091 sh_bg(int unit, args_t *args)
   7092 {
   7093     _bg_job_t    *info;
   7094     char    *cmd;
   7095     int        i;
   7096 
   7097     if (ARG_CNT(args) != 1) {
   7098         return CMD_USAGE;
   7099     }
   7100 
   7101     /* find an empty slot */
   7102     info = NULL;
   7103     for (i = 0; i < _MAX_BG_TASKS; i++) {
   7104         if (_bg_jobs[unit][i] == NULL) {
   7105         info = sal_alloc(sizeof(_bg_job_t), "bg_job");
   7106         if (info == NULL) {
   7107         cli_out("bg: cannot allocate job info\n");
   7108         return CMD_FAIL;
   7109         }
   7110         sal_memset(info, 0, sizeof(_bg_job_t));
   7111         _bg_jobs[unit][i] = info;
   7112         break;
   7113         }
   7114     }
   7115 
   7116     if (info == NULL) {
   7117         cli_out("bg: ERROR: too many background tasks\n");
   7118         return CMD_FAIL;
   7119     }
   7120 
   7121     info->unit = unit;
   7122     info->idx = i;
   7123     info->job = ++_bg_job_count;
   7124     info->sem = sal_sem_create("bg_job", sal_sem_BINARY, 0);
   7125     if (!info->sem) {
   7126         cli_out("bg: ERROR: cannot create task semaphore\n");
   7127     sal_free(info);
   7128     _bg_jobs[unit][i] = NULL;
   7129         return CMD_FAIL;
   7130     }
   7131     cmd = ARG_GET(args);
   7132     sal_memcpy(info->cmd, cmd, ARGS_BUFFER);
   7133 
   7134     info->thread_id = sal_thread_create("bcmBG",
   7135                     128*1024,
   7136                                         SOC_BG_THREAD_PRI,
   7137                                         (void_fn_ptr)_bg_cmd,
   7138                     (void *)info);
   7139     if (!info->thread_id || (info->thread_id == SAL_THREAD_ERROR)) {
   7140         cli_out("bg: ERROR: cannot create thread\n");
   7141     sal_sem_destroy(info->sem);
   7142     sal_free(info);
   7143     _bg_jobs[unit][i] = NULL;
   7144         return CMD_FAIL;
   7145     }
   7146     LOG_VERBOSE(BSL_LS_SOC_COMMON,
   7147                 (BSL_META_U(unit,
   7148                             "bg: starting job %d\n"), info->job));
   7149     sal_sem_give(info->sem);
   7150 
   7151     return CMD_OK;
   7152 }
   7153 
   7154 char sh_jobs_usage[] =
   7155     "jobs\n"
   7156     "    List jobs running in the background\n";
   7157 
   7158 cmd_result_t
   7159 sh_jobs(int unit, args_t *args)
   7160 {
   7161     int        i;
   7162     _bg_job_t    *info;
   7163 
   7164     COMPILER_REFERENCE(args);
   7165 
   7166     for (i = 0; i < _MAX_BG_TASKS; i++) {
   7167     info = _bg_jobs[unit][i];
   7168         if (info != NULL) {
   7169         cli_out("Job %d: %s\n", info->job, info->cmd);
   7170     }
   7171     }
   7172 
   7173     return CMD_OK;
   7174 }
   7175 
   7176 char sh_kill_usage[] =
   7177     "kill <n>\n"
   7178     "    Destroy a background task.\n"
   7179     "    Use 'jobs' to see a list of tasks currently in the  background.\n";
   7180 
   7181 cmd_result_t
   7182 sh_kill(int unit, args_t *args)
   7183 {
   7184     int        i, job;
   7185     _bg_job_t    *info;
   7186 
   7187     if (!ARG_CNT(args)) {
   7188         return CMD_USAGE;
   7189     }
   7190 
   7191     job = sal_strtoul(_ARG_GET(args), NULL, 10);
   7192 
   7193     for (i = 0; i < _MAX_BG_TASKS; i++) {
   7194     info = _bg_jobs[unit][i];
   7195         if (info != NULL && info->job == job) {
   7196         sal_thread_destroy(info->thread_id);
   7197         cli_out("Job %d killed\n", info->job);
   7198         sal_sem_destroy(info->sem);
   7199         sal_free(info);
   7200         _bg_jobs[unit][i] = NULL;
   7201         return CMD_OK;
   7202     }
   7203     }
   7204     cli_out("Job %d not found\n", job);
   7205     return CMD_FAIL;
   7206 }
   7207 
   7208 int resTestMax(int x,int y) {
   7209     return (x>y)?x:y;
   7210 }
   7211 #ifdef _GET_NONBLANK
   7212 #undef _GET_NONBLANK
   7213 #endif /* def _GET_NOBLANK */
   7214 #define _GET_NONBLANK(a,c) \
   7215     do { \
   7216         (c) = ARG_GET(a); \
   7217         if (NULL == (c)) { \
   7218             return CMD_USAGE; \
   7219         } \
   7220     } while (0)
   7221 
   7222 char cmd_sh_restest_usage[] =
   7223 #ifdef COMPILER_STRING_CONST_LIMIT
   7224     "  restest <args>\n"
   7225 #else
   7226     "(caps are obligatory, lower optional; <var> = use var's value; [optional])\n"
   7227     "  ResTest Create [TL2]    (create test resources, private to this command)\n"
   7228     "  ResTest DEstroy         (destroy test resources)\n"
   7229     "  ResTest DUmp [Unit]     (dump test resources or unit resources)\n"
   7230     "  ResTest T               (verify resources are all free)\n"
   7231     "  ResTest T0              (basic alloc and free, increasing block sizes)\n"
   7232     "  ResTest T1              (basic alloc and free, decreasing block sizes)\n"
   7233     "  ResTest T2              (allocate and then free entire pools)\n"
   7234     "  ResTest T3              (alloc pools +1 alloc, free pools, +1 alloc, free)\n"
   7235     "  ResTest T4              (free unallocated elements/blocks)\n"
   7236     "  ResTest T5              (aligned alloc tests against bitmap allocator)\n"
   7237     "  ResTest T6              (aligned tagged alloc tests against tag bmp alloc)\n"
   7238     "  ResTest T7              (basic alloc and free, inc+dec block size, tagged)\n"
   7239     "  ResTest T8              (test pool/type set/unset, info, and free checks)\n"
   7240     "  ResTest T9              (test alloc WITH_ID and REPLACE)\n"
   7241     "  ResTest TA              (test sparse allocation)\n"
   7242     "The TL2 argument to create sets the tag length 2 (instead of 1) for those\n"
   7243     "pools that support tagging.  The dump command can dump either the test\n"
   7244     "resources or the unit resources, and assumes the test resources if the unit\n"
   7245     "keyword is not included.\n"
   7246 #endif
   7247     ;
   7248 
   7249 #ifdef TEST_BLOCKS
   7250 #undef TEST_BLOCKS
   7251 #endif /* def TEST_BLOCKS */
   7252 #define TEST_BLOCKS 64
   7253 
   7254 cmd_result_t
   7255 cmd_sh_restest(int unit, args_t *a){
   7256     static shr_mres_handle_t         localRes = NULL;
   7257     static int                       tagLen = 1;
   7258     char                             *c;
   7259     int                              result = BCM_E_NONE;
   7260     int                              xresult;
   7261     int                              index;
   7262     int                              offset;
   7263     int                              res;
   7264     int                              pool;
   7265     int                              rescount;
   7266     int                              auxpool;
   7267     int                              used;
   7268     shr_res_allocator_t              restype;
   7269     uint8                            curtag[2];
   7270     char                             name[32];
   7271     shr_res_tagged_bitmap_extras_t   tagBitmapExtras;
   7272     shr_res_idxres_extras_t          idxresExtras;
   7273     shr_res_aidxres_extras_t         aidxresExtras;
   7274     shr_res_mdb_extras_t             mdbExtras;
   7275     shr_res_pool_info_t              poolInfo;
   7276     shr_res_type_info_t              typeInfo;
   7277     int                              base[SHR_RES_ALLOCATOR_COUNT << 1][TEST_BLOCKS];
   7278     int                              size[SHR_RES_ALLOCATOR_COUNT << 1][TEST_BLOCKS];
   7279     uint8                            tag[SHR_RES_ALLOCATOR_COUNT << 1][TEST_BLOCKS][2];
   7280     int                              skip[SHR_RES_ALLOCATOR_COUNT << 1];
   7281     void                             *extraPtr;
   7282     const void                       *extraGet;
   7283     uint32                           statusFlags;
   7284     uint32                           pattern;
   7285     int                              length;
   7286     int                              repeats;
   7287     int                              repeat;
   7288     int                              elem;
   7289 
   7290     _GET_NONBLANK(a,c);
   7291     if (!sal_strncasecmp(c,"create",resTestMax(sal_strlen(c),1))) {
   7292         c = ARG_GET(a);
   7293         if (c) {
   7294             if (!sal_strncasecmp(c,"tl2",3)) {
   7295                 tagLen = 2;
   7296                 c = ARG_GET(a);
   7297             }
   7298         }
   7299         if (localRes) {
   7300             /* destroy old resources and reinit */
   7301             result = shr_mres_destroy(localRes);
   7302             if (BCM_E_NONE != result) {
   7303                 cli_out("unable to destroy old %p resources: %d (%s)\n",
   7304                         (void*)localRes,
   7305                         result,
   7306                         _SHR_ERRMSG(result));
   7307             }
   7308         } else {
   7309             /* okay so far */
   7310             result = BCM_E_NONE;
   7311         }
   7312         if (BCM_E_NONE == result) {
   7313             result = shr_mres_create(&localRes,
   7314                                      SHR_RES_ALLOCATOR_COUNT << 1 /* types */,
   7315                                      SHR_RES_ALLOCATOR_COUNT /* pools */ );
   7316             if (BCM_E_NONE != result) {
   7317                 cli_out("failed to set up new resources: %d (%s)\n",
   7318                         result,
   7319                         _SHR_ERRMSG(result));
   7320             }
   7321         }
   7322         for (index = 0;
   7323              (BCM_E_NONE == result) && (index < SHR_RES_ALLOCATOR_COUNT);
   7324              index++) {
   7325             switch (index) {
   7326             case SHR_RES_ALLOCATOR_BITMAP:
   7327                 extraPtr = NULL;
   7328                 break;
   7329             case SHR_RES_ALLOCATOR_TAGGED_BITMAP:
   7330                 extraPtr = &tagBitmapExtras;
   7331                 tagBitmapExtras.grain_size = 4;
   7332                 tagBitmapExtras.tag_length = tagLen;
   7333                 break;
   7334             case SHR_RES_ALLOCATOR_IDXRES:
   7335                 extraPtr = &idxresExtras;
   7336                 idxresExtras.scaling_factor = 1;
   7337                 break;
   7338             case SHR_RES_ALLOCATOR_AIDXRES:
   7339                 extraPtr = &aidxresExtras;
   7340                 aidxresExtras.blocking_factor = 7;
   7341                 break;
   7342             case SHR_RES_ALLOCATOR_MDB:
   7343                 extraPtr = &mdbExtras;
   7344                 mdbExtras.bank_size = 1024;
   7345                 mdbExtras.free_lists = 10;
   7346                 mdbExtras.free_counts[0] = 2;
   7347                 mdbExtras.free_counts[1] = 4;
   7348                 mdbExtras.free_counts[2] = 8;
   7349                 mdbExtras.free_counts[3] = 16;
   7350                 mdbExtras.free_counts[4] = 32;
   7351                 mdbExtras.free_counts[5] = 64;
   7352                 mdbExtras.free_counts[6] = 128;
   7353                 mdbExtras.free_counts[7] = 256;
   7354                 mdbExtras.free_counts[8] = 512;
   7355                 mdbExtras.free_counts[9] = 1024;
   7356                 break;
   7357             default:
   7358                 extraPtr = NULL;
   7359             } /* switch(index) */
   7360             sal_snprintf(&(name[0]),
   7361                          sizeof(name) - 1,
   7362                          "test: pool %d",
   7363                          index);
   7364             result = shr_mres_pool_set(localRes,
   7365                                        index /* as pool ID */,
   7366                                        index /* as manager type */,
   7367                                        1024 /* low ID */,
   7368                                        6144 /* count */,
   7369                                        extraPtr,
   7370                                        &(name[0]));
   7371             if (BCM_E_NONE != result) {
   7372                 cli_out("failed to set up %p pool %d: %d (%s)\n",
   7373                         (void*)localRes,
   7374                         index,
   7375                         result,
   7376                         _SHR_ERRMSG(result));
   7377             }
   7378         }
   7379         for (index = 0;
   7380              (BCM_E_NONE == result) &&
   7381               (index < (SHR_RES_ALLOCATOR_COUNT << 1));
   7382              index++) {
   7383             sal_snprintf(&(name[0]),
   7384                          sizeof(name) - 1,
   7385                          "test: type %d",
   7386                          index);
   7387             result = shr_mres_type_set(localRes,
   7388                                        index /* as type ID */,
   7389                                        index % SHR_RES_ALLOCATOR_COUNT,
   7390                                        1 /* element size */,
   7391                                        &(name[0]));
   7392             if (BCM_E_NONE != result) {
   7393                 cli_out("failed to set up %p type %d: %d (%s)\n",
   7394                         (void*)localRes,
   7395                         index,
   7396                         result,
   7397                         _SHR_ERRMSG(result));
   7398             }
   7399         }
   7400         if (BCM_E_NONE == result) {
   7401             cli_out("initialised %p resources successfully\n",
   7402                     (void*)localRes);
   7403         }
   7404     } else if (!sal_strncasecmp(c,"destroy",resTestMax(sal_strlen(c),2))) {
   7405         c = ARG_GET(a);
   7406         if (localRes) {
   7407             result = shr_mres_destroy(localRes);
   7408             if (BCM_E_NONE == result) {
   7409                 cli_out("destroyed %p resources successfully\n",
   7410                         (void*)localRes);
   7411                 localRes = NULL;
   7412             } else {
   7413                 cli_out("failed to destroy %p resources: %d (%s)\n",
   7414                         (void*)localRes,
   7415                         result,
   7416                         _SHR_ERRMSG(result));
   7417             }
   7418         } else {
   7419             cli_out("no test resources to destroy\n");
   7420             result = BCM_E_INIT;
   7421         }
   7422     } else if (!sal_strncasecmp(c,"dump",resTestMax(sal_strlen(c),2))) {
   7423         c = ARG_GET(a);
   7424         if ((!c) || (!sal_strncasecmp(c,"test",resTestMax(sal_strlen(c),1)))) {
   7425             if (localRes) {
   7426                 result = shr_mres_dump(localRes);
   7427                 if (BCM_E_NONE != result) {
   7428                     cli_out("failed to dump test resource information:"
   7429                             " %d (%s)\n",
   7430                             result,
   7431                             _SHR_ERRMSG(result));
   7432                 }
   7433             } else {
   7434                 cli_out("no test resources to dump\n");
   7435                 result = BCM_E_INIT;
   7436             }
   7437         } else if (!sal_strncasecmp(c,"unit",resTestMax(sal_strlen(c),1))) {
   7438             result = shr_res_dump(unit);
   7439             if (BCM_E_NONE != result) {
   7440                 cli_out("failed to dump unit %d resource information:"
   7441                         " %d (%s)\n",
   7442                         unit,
   7443                         result,
   7444                         _SHR_ERRMSG(result));
   7445             }
   7446         } else {
   7447             cli_out("invalid argument: %s\n", c);
   7448             return CMD_USAGE;
   7449         }
   7450     } else if (!sal_strncasecmp(c, "t0", resTestMax(sal_strlen(c), 2))) {
   7451         if (localRes) {
   7452             result = shr_mres_get(localRes, &rescount, NULL);
   7453             if (BCM_E_NONE == result) {
   7454                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   7455                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   7456                 }
   7457             } else {
   7458                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   7459                         (void*)localRes,
   7460                         result,
   7461                         _SHR_ERRMSG(result));
   7462                 rescount = 0;
   7463             }
   7464             for (res = 0;
   7465                  (BCM_E_NONE == result) && (res < rescount);
   7466                  res++) {
   7467                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   7468                 if (BCM_E_NONE == result) {
   7469                     result = shr_mres_pool_get(localRes,
   7470                                                pool,
   7471                                                &restype,
   7472                                                NULL,
   7473                                                NULL,
   7474                                                NULL,
   7475                                                NULL);
   7476                     if (BCM_E_NONE != result) {
   7477                         cli_out("unable to retrieve %p type %d -> pool %d"
   7478                                 " manager: %d (%s)\n",
   7479                                 (void*)localRes,
   7480                                 res,
   7481                                 pool,
   7482                                 result,
   7483                                 _SHR_ERRMSG(result));
   7484                     }
   7485                 } else {
   7486                     cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   7487                             (void*)localRes,
   7488                             res,
   7489                             result,
   7490                             _SHR_ERRMSG(result));
   7491                 }
   7492                 for (index = 0;
   7493                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7494                      index++) {
   7495                     switch (restype) {
   7496                     case SHR_RES_ALLOCATOR_IDXRES:
   7497                         /* can only do 'WITH_ID' for larger than one */
   7498                         size[res][index] = 1;
   7499                         break;
   7500                     default:
   7501                         size[res][index] = 1 + index;
   7502                         break;
   7503                     }
   7504                     result = shr_mres_alloc(localRes,
   7505                                             res,
   7506                                             0 /* flags */,
   7507                                             size[res][index],
   7508                                             &(base[res][index]));
   7509                     cli_out("allocated %p:%d:%d\r",
   7510                             (void*)localRes,
   7511                             res,
   7512                             index);
   7513                     if (BCM_E_NONE != result) {
   7514                         cli_out("failed to allocate %p resource %d block %d"
   7515                                 " of %d elements: %d (%s)\n",
   7516                                 (void*)localRes,
   7517                                 res,
   7518                                 index,
   7519                                 size[res][index],
   7520                                 result,
   7521                                 _SHR_ERRMSG(result));
   7522                     }
   7523                 }
   7524             }
   7525             for (res = 0;
   7526                  (BCM_E_NONE == result) && (res < rescount);
   7527                  res++) {
   7528                 for (index = 0;
   7529                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7530                      index++) {
   7531                     result = shr_mres_check(localRes,
   7532                                             res,
   7533                                             size[res][index],
   7534                                             base[res][index]);
   7535                     cli_out("checked %p:%d:%d     \r",
   7536                             (void*)localRes,
   7537                             res,
   7538                             index);
   7539                     if (BCM_E_EXISTS != result) {
   7540                         cli_out("unexpected result checking %p resource %d"
   7541                                 " block %d at %d (%d elements): %d (%s)\n",
   7542                                 (void*)localRes,
   7543                                 res,
   7544                                 index,
   7545                                 base[res][index],
   7546                                 size[res][index],
   7547                                 result,
   7548                                 _SHR_ERRMSG(result));
   7549                         result = BCM_E_INTERNAL;
   7550                     } else {
   7551                         /* correct value */
   7552                         result = BCM_E_NONE;
   7553                     }
   7554                 }
   7555             }
   7556             for (res = 0;
   7557                  (BCM_E_NONE == result) && (res < rescount);
   7558                  res++) {
   7559                 for (index = 0;
   7560                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7561                      index++) {
   7562                     result = shr_mres_free(localRes,
   7563                                            res,
   7564                                            size[res][index],
   7565                                            base[res][index]);
   7566                     cli_out("freed %p:%d:%d                \r",
   7567                             (void*)localRes,
   7568                             res,
   7569                             index);
   7570                     if (BCM_E_NONE != result) {
   7571                         cli_out("failed to free %p resource %d block %d of"
   7572                                 " %d elements at %d: %d (%s)\n",
   7573                                 (void*)localRes,
   7574                                 res,
   7575                                 index,
   7576                                 size[res][index],
   7577                                 base[res][index],
   7578                                 result,
   7579                                 _SHR_ERRMSG(result));
   7580                     }
   7581                 }
   7582             }
   7583             for (res = 0;
   7584                  (BCM_E_NONE == result) && (res < rescount);
   7585                  res++) {
   7586                 for (index = 0;
   7587                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7588                      index++) {
   7589                     result = shr_mres_check(localRes,
   7590                                             res,
   7591                                             size[res][index],
   7592                                             base[res][index]);
   7593                     cli_out("checked %p:%d:%d     \r",
   7594                             (void*)localRes,
   7595                             res,
   7596                             index);
   7597                     if (BCM_E_NOT_FOUND != result) {
   7598                         cli_out("unexpected result checking %p resource %d"
   7599                                 " block %d at %d (%d elements): %d (%s)\n",
   7600                                 (void*)localRes,
   7601                                 res,
   7602                                 index,
   7603                                 base[res][index],
   7604                                 size[res][index],
   7605                                 result,
   7606                                 _SHR_ERRMSG(result));
   7607                         result = BCM_E_INTERNAL;
   7608                     } else {
   7609                         /* correct value */
   7610                         result = BCM_E_NONE;
   7611                     }
   7612                 }
   7613             }
   7614             for (res = 0;
   7615                  (BCM_E_NONE == result) && (res < rescount);
   7616                  res++) {
   7617                 cli_out("%p resource %d allocated and freed:\n",
   7618                         (void*)localRes,
   7619                         res);
   7620                 for (index = 0;
   7621                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7622                      index++) {
   7623                     cli_out("  %4d(%4d)", base[res][index], size[res][index]);
   7624                     if (3 == (index & 3)) {
   7625                         cli_out("\n");
   7626                     }
   7627                 }
   7628                 if (0 != (index & 3)) {
   7629                     cli_out("\n");
   7630                 }
   7631             }
   7632         } else { /* if (localRes) */
   7633             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   7634         } /* if (localRes) */
   7635     } else if (!sal_strncasecmp(c, "t1", resTestMax(sal_strlen(c), 2))) {
   7636         if (localRes) {
   7637             result = shr_mres_get(localRes, &rescount, NULL);
   7638             if (BCM_E_NONE == result) {
   7639                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   7640                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   7641                 }
   7642             } else {
   7643                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   7644                         (void*)localRes,
   7645                         result,
   7646                         _SHR_ERRMSG(result));
   7647                 rescount = 0;
   7648             }
   7649             for (res = 0;
   7650                  (BCM_E_NONE == result) && (res < rescount);
   7651                  res++) {
   7652                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   7653                 if (BCM_E_NONE == result) {
   7654                     result = shr_mres_pool_get(localRes,
   7655                                                pool,
   7656                                                &restype,
   7657                                                NULL,
   7658                                                NULL,
   7659                                                NULL,
   7660                                                NULL);
   7661                     if (BCM_E_NONE != result) {
   7662                         cli_out("unable to retrieve %p type %d -> pool %d"
   7663                                 " manager: %d (%s)\n",
   7664                                 (void*)localRes,
   7665                                 res,
   7666                                 pool,
   7667                                 result,
   7668                                 _SHR_ERRMSG(result));
   7669                     }
   7670                 } else {
   7671                     cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   7672                             (void*)localRes,
   7673                             res,
   7674                             result,
   7675                             _SHR_ERRMSG(result));
   7676                 }
   7677                 for (index = 0;
   7678                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7679                      index++) {
   7680                     switch (restype) {
   7681                     case SHR_RES_ALLOCATOR_IDXRES:
   7682                         /* can only do 'WITH_ID' for larger than one */
   7683                         size[res][index] = 1;
   7684                         break;
   7685                     default:
   7686                         size[res][index] = TEST_BLOCKS + 1 - index;
   7687                         break;
   7688                     }
   7689                     result = shr_mres_alloc(localRes,
   7690                                             res,
   7691                                             0 /* flags */,
   7692                                             size[res][index],
   7693                                             &(base[res][index]));
   7694                     cli_out("allocated %p:%d:%d\r",
   7695                             (void*)localRes,
   7696                             res,
   7697                             index);
   7698                     if (BCM_E_NONE != result) {
   7699                         cli_out("failed to allocate %p resource %d block %d"
   7700                                 " of %d elements: %d (%s)\n",
   7701                                 (void*)localRes,
   7702                                 res,
   7703                                 index,
   7704                                 size[res][index],
   7705                                 result,
   7706                                 _SHR_ERRMSG(result));
   7707                     }
   7708                 }
   7709             }
   7710             for (res = 0;
   7711                  (BCM_E_NONE == result) && (res < rescount);
   7712                  res++) {
   7713                 for (index = 0;
   7714                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7715                      index++) {
   7716                     result = shr_mres_check(localRes,
   7717                                             res,
   7718                                             size[res][index],
   7719                                             base[res][index]);
   7720                     cli_out("checked %p:%d:%d     \r",
   7721                             (void*)localRes,
   7722                             res,
   7723                             index);
   7724                     if (BCM_E_EXISTS != result) {
   7725                         cli_out("unexpected result checking %p resource %d"
   7726                                 " block %d at %d (%d elements): %d (%s)\n",
   7727                                 (void*)localRes,
   7728                                 res,
   7729                                 index,
   7730                                 base[res][index],
   7731                                 size[res][index],
   7732                                 result,
   7733                                 _SHR_ERRMSG(result));
   7734                         result = BCM_E_INTERNAL;
   7735                     } else {
   7736                         /* correct value */
   7737                         result = BCM_E_NONE;
   7738                     }
   7739                 }
   7740             }
   7741             for (res = 0;
   7742                  (BCM_E_NONE == result) && (res < rescount);
   7743                  res++) {
   7744                 for (index = 0;
   7745                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7746                      index++) {
   7747                     result = shr_mres_free(localRes,
   7748                                            res,
   7749                                            size[res][index],
   7750                                            base[res][index]);
   7751                     cli_out("freed %p:%d:%d                \r",
   7752                             (void*)localRes,
   7753                             res,
   7754                             index);
   7755                     if (BCM_E_NONE != result) {
   7756                         cli_out("failed to free %p resource %d block %d of"
   7757                                 " %d elements at %d: %d (%s)\n",
   7758                                 (void*)localRes,
   7759                                 res,
   7760                                 index,
   7761                                 size[res][index],
   7762                                 base[res][index],
   7763                                 result,
   7764                                 _SHR_ERRMSG(result));
   7765                     }
   7766                 }
   7767             }
   7768             for (res = 0;
   7769                  (BCM_E_NONE == result) && (res < rescount);
   7770                  res++) {
   7771                 for (index = 0;
   7772                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7773                      index++) {
   7774                     result = shr_mres_check(localRes,
   7775                                             res,
   7776                                             size[res][index],
   7777                                             base[res][index]);
   7778                     cli_out("checked %p:%d:%d     \r",
   7779                             (void*)localRes,
   7780                             res,
   7781                             index);
   7782                     if (BCM_E_NOT_FOUND != result) {
   7783                         cli_out("unexpected result checking %p resource %d"
   7784                                 " block %d at %d (%d elements): %d (%s)\n",
   7785                                 (void*)localRes,
   7786                                 res,
   7787                                 index,
   7788                                 base[res][index],
   7789                                 size[res][index],
   7790                                 result,
   7791                                 _SHR_ERRMSG(result));
   7792                         result = BCM_E_INTERNAL;
   7793                     } else {
   7794                         /* correct value */
   7795                         result = BCM_E_NONE;
   7796                     }
   7797                 }
   7798             }
   7799             for (res = 0;
   7800                  (BCM_E_NONE == result) && (res < rescount);
   7801                  res++) {
   7802                 cli_out("%p resource %d allocated and freed:\n",
   7803                         (void*)localRes,
   7804                         res);
   7805                 for (index = 0;
   7806                      (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   7807                      index++) {
   7808                     cli_out("  %4d(%4d)", base[res][index], size[res][index]);
   7809                     if (3 == (index & 3)) {
   7810                         cli_out("\n");
   7811                     }
   7812                 }
   7813                 if (0 != (index & 3)) {
   7814                     cli_out("\n");
   7815                 }
   7816             }
   7817         } else { /* if (localRes) */
   7818             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   7819         } /* if (localRes) */
   7820     } else if (!sal_strncasecmp(c, "t2", resTestMax(sal_strlen(c), 2))) {
   7821         if (localRes) {
   7822             result = shr_mres_get(localRes, &rescount, NULL);
   7823             if (BCM_E_NONE == result) {
   7824                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   7825                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   7826                 }
   7827             } else {
   7828                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   7829                         (void*)localRes,
   7830                         result,
   7831                         _SHR_ERRMSG(result));
   7832                 rescount = 0;
   7833             }
   7834             for (res = 0;
   7835                  (BCM_E_NONE == result) && (res < rescount);
   7836                  res++) {
   7837                 skip[res] = FALSE;
   7838                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   7839                 if (BCM_E_NONE == result) {
   7840                     result = shr_mres_pool_get(localRes,
   7841                                                pool,
   7842                                                &restype,
   7843                                                &(base[res][0]),
   7844                                                &(size[res][0]),
   7845                                                NULL,
   7846                                                NULL);
   7847                     if (BCM_E_NONE == result) {
   7848                         /* got the data properly */
   7849                         if (SHR_RES_ALLOCATOR_MDB == restype) {
   7850                             /* mdb does not support alloc > bank size */
   7851                             result = shr_mres_pool_get(localRes,
   7852                                                        pool,
   7853                                                        NULL,
   7854                                                        NULL,
   7855                                                        NULL,
   7856                                                        &extraGet,
   7857                                                        NULL);
   7858                             if (BCM_E_NONE == result) {
   7859                                 sal_memcpy(&mdbExtras,
   7860                                            extraGet,
   7861                                            sizeof(mdbExtras));
   7862                                 auxpool = size[res][0] - mdbExtras.bank_size;
   7863                                 size[res][0] = mdbExtras.bank_size;
   7864                                 for (index = 1;
   7865                                      (index < TEST_BLOCKS) &&
   7866                                      (auxpool > 0);
   7867                                      index++) {
   7868                                     base[res][index] = base[res][index-1] +
   7869                                                        mdbExtras.bank_size;
   7870                                     if (auxpool > mdbExtras.bank_size) {
   7871                                         size[res][index] = mdbExtras.bank_size;
   7872                                         auxpool -= mdbExtras.bank_size;
   7873                                     } else {
   7874                                         size[res][index] = auxpool;
   7875                                         auxpool = 0;
   7876                                     }
   7877                                 }
   7878                                 while (index < TEST_BLOCKS) {
   7879                                     base[res][index] = 0;
   7880                                     size[res][index] = 0;
   7881                                     index++;
   7882                                 }
   7883                                 if (auxpool) {
   7884                                     cli_out("test will not cover all of %p"
   7885                                             " resource %d: not enough workspace"
   7886                                             " to cover all banks; %d elements"
   7887                                             " left\n",
   7888                                             (void*)localRes,
   7889                                             res,
   7890                                             auxpool);
   7891                                     skip[res] = TRUE;
   7892                                 }
   7893                             }
   7894                         } else {
   7895                             for (index = 1;
   7896                                  index < TEST_BLOCKS;
   7897                                  index++) {
   7898                                 base[res][index] = 0;
   7899                                 size[res][index] = 0;
   7900                             }
   7901                         }
   7902                     }
   7903                     if (BCM_E_NONE != result) {
   7904                         cli_out("unable to retrieve %p type %d -> pool %d"
   7905                                 " manager info: %d (%s)\n",
   7906                                 (void*)localRes,
   7907                                 res,
   7908                                 pool,
   7909                                 result,
   7910                                 _SHR_ERRMSG(result));
   7911                     }
   7912                 } else {
   7913                     cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   7914                             (void*)localRes,
   7915                             res,
   7916                             result,
   7917                             _SHR_ERRMSG(result));
   7918                 }
   7919                 used = FALSE;
   7920                 for (index = 0;
   7921                      (BCM_E_NONE == result) && (index < res);
   7922                      index++) {
   7923                     result = shr_mres_type_get(localRes,
   7924                                                index,
   7925                                                &auxpool,
   7926                                                NULL,
   7927                                                NULL);
   7928                     if (BCM_E_NONE != result) {
   7929                         cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   7930                                 (void*)localRes,
   7931                                 index,
   7932                                 result,
   7933                                 _SHR_ERRMSG(result));
   7934                     } else if (auxpool == pool) {
   7935                         used = TRUE;
   7936                         break;
   7937                     }
   7938                 }
   7939                 if (BCM_E_NONE == result) {
   7940                     for (index = 0;
   7941                          index < (TEST_BLOCKS);
   7942                          index++) {
   7943                         if (0 == size[res][index]) {
   7944                             /* no more blocks to cover here */
   7945                             break;
   7946                         }
   7947                         result = shr_mres_alloc(localRes,
   7948                                                 res,
   7949                                                 SHR_RES_ALLOC_WITH_ID,
   7950                                                 size[res][index],
   7951                                                 &(base[res][index]));
   7952                         cli_out("allocated %p:%d:%d\r",
   7953                                 (void*)localRes,
   7954                                 res,
   7955                                 index);
   7956                         if (!used) {
   7957                             /* BCM_E_NONE is expected result */
   7958                             if (BCM_E_NONE != result) {
   7959                                 cli_out("unable to allocate %p type %d (pool"
   7960                                         " %d) range of %d..%d: %d (%s)\n",
   7961                                         (void*)localRes,
   7962                                         res,
   7963                                         pool,
   7964                                         base[res][index],
   7965                                         base[res][index] + size[res][index] - 1,
   7966                                         result,
   7967                                         _SHR_ERRMSG(result));
   7968                             }
   7969                         } else {
   7970                             /* BCM_E_RESOURCE is expected result */
   7971                             if (BCM_E_NONE == result) {
   7972                                 if (!skip[res]) {
   7973                                     cli_out("should not have been able to"
   7974                                             " allocate %p type %d because type"
   7975                                             " %d should have already consumed"
   7976                                             " all of pool %d\n",
   7977                                             (void*)localRes,
   7978                                             res,
   7979                                             index,
   7980                                             pool);
   7981                                     result = BCM_E_INTERNAL;
   7982                                 }
   7983                             } else if (BCM_E_RESOURCE != result) {
   7984                                 cli_out("unexpected error allocating %p type %d"
   7985                                         " (pool %d) entire range %d..%d:"
   7986                                         " %d (%s)\n",
   7987                                         (void*)localRes,
   7988                                         res,
   7989                                         pool,
   7990                                         base[res][index],
   7991                                         base[res][index] + size[res][index] - 1,
   7992                                         result,
   7993                                         _SHR_ERRMSG(result));
   7994                             } else {
   7995                                 /* expected in use; don't free it either */
   7996                                 result = BCM_E_NONE;
   7997                                 size[res][index] = 0;
   7998                             }
   7999                         }
   8000                     }
   8001                 }
   8002             }
   8003             for (res = 0;
   8004                  (BCM_E_NONE == result) && (res < rescount);
   8005                  res++) {
   8006                 for (index = 0;
   8007                      index < TEST_BLOCKS;
   8008                      index++) {
   8009                     if (size[res][index]) {
   8010                         result = shr_mres_check(localRes,
   8011                                                 res,
   8012                                                 size[res][index],
   8013                                                 base[res][index]);
   8014                         cli_out("checked %p:%d:%d     \r",
   8015                                 (void*)localRes,
   8016                                 res,
   8017                                 index);
   8018                         if (BCM_E_EXISTS != result) {
   8019                             cli_out("unexpected result checking %p resource %d"
   8020                                     " block %d at %d (%d elements): %d (%s)\n",
   8021                                     (void*)localRes,
   8022                                     res,
   8023                                     index,
   8024                                     base[res][index],
   8025                                     size[res][index],
   8026                                     result,
   8027                                     _SHR_ERRMSG(result));
   8028                             result = BCM_E_INTERNAL;
   8029                         } else {
   8030                             /* correct value */
   8031                             result = BCM_E_NONE;
   8032                         }
   8033                     }
   8034                 }
   8035             }
   8036             for (res = 0;
   8037                  (BCM_E_NONE == result) && (res < rescount);
   8038                  res++) {
   8039                 for (index = 0;
   8040                      index < TEST_BLOCKS;
   8041                      index++) {
   8042                     if (size[res][index]) {
   8043                         result = shr_mres_free(localRes,
   8044                                                res,
   8045                                                size[res][index],
   8046                                                base[res][index]);
   8047                         cli_out("freed %p:%d:%d                \r",
   8048                                 (void*)localRes,
   8049                                 res,
   8050                                 index);
   8051                         if (BCM_E_NONE != result) {
   8052                             cli_out("failed to free %p resource %d block %d of"
   8053                                     " %d elements at %d: %d (%s)\n",
   8054                                     (void*)localRes,
   8055                                     res,
   8056                                     index,
   8057                                     size[res][index],
   8058                                     base[res][index],
   8059                                     result,
   8060                                     _SHR_ERRMSG(result));
   8061                         }
   8062                     }
   8063                 }
   8064             }
   8065             for (res = 0;
   8066                  (BCM_E_NONE == result) && (res < rescount);
   8067                  res++) {
   8068                 for (index = 0;
   8069                      index < TEST_BLOCKS;
   8070                      index++) {
   8071                     if (size[res][index]) {
   8072                         result = shr_mres_check(localRes,
   8073                                                 res,
   8074                                                 size[res][index],
   8075                                                 base[res][index]);
   8076                         cli_out("checked %p:%d:%d     \r",
   8077                                 (void*)localRes,
   8078                                 res,
   8079                                 index);
   8080                         if (BCM_E_NOT_FOUND != result) {
   8081                             cli_out("unexpected result checking %p resource %d"
   8082                                     " block %d at %d (%d elements): %d (%s)\n",
   8083                                     (void*)localRes,
   8084                                     res,
   8085                                     index,
   8086                                     base[res][index],
   8087                                     size[res][index],
   8088                                     result,
   8089                                     _SHR_ERRMSG(result));
   8090                             result = BCM_E_INTERNAL;
   8091                         } else {
   8092                             /* correct value */
   8093                             result = BCM_E_NONE;
   8094                         }
   8095                     }
   8096                 }
   8097             }
   8098             for (res = 0;
   8099                  (BCM_E_NONE == result) && (res < rescount);
   8100                  res++) {
   8101                 if (size[res][0]) {
   8102                     cli_out("%p resource %d allocated and freed\n",
   8103                             (void*)localRes,
   8104                             res);
   8105                 } else {
   8106                     cli_out("%p resource %d overlapped another resource"
   8107                             " (same pool)\n",
   8108                             (void*)localRes,
   8109                             res);
   8110                 }
   8111             }
   8112         } else { /* if (localRes) */
   8113             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   8114         } /* if (localRes) */
   8115     } else if (!sal_strncasecmp(c, "t3", resTestMax(sal_strlen(c), 2))) {
   8116         if (localRes) {
   8117             result = shr_mres_get(localRes, &rescount, NULL);
   8118             if (BCM_E_NONE == result) {
   8119                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   8120                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   8121                 }
   8122             } else {
   8123                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   8124                         (void*)localRes,
   8125                         result,
   8126                         _SHR_ERRMSG(result));
   8127                 rescount = 0;
   8128             }
   8129             for (res = 0;
   8130                  (BCM_E_NONE == result) && (res < rescount);
   8131                  res++) {
   8132                 skip[res] = FALSE;
   8133                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   8134                 if (BCM_E_NONE == result) {
   8135                     result = shr_mres_pool_get(localRes,
   8136                                                pool,
   8137                                                &restype,
   8138                                                &(base[res][0]),
   8139                                                &(size[res][0]),
   8140                                                NULL,
   8141                                                NULL);
   8142                     if (BCM_E_NONE == result) {
   8143                         /* got the data properly */
   8144                         if (SHR_RES_ALLOCATOR_MDB == restype) {
   8145                             /* mdb does not support alloc > bank size */
   8146                             result = shr_mres_pool_get(localRes,
   8147                                                        pool,
   8148                                                        NULL,
   8149                                                        NULL,
   8150                                                        NULL,
   8151                                                        &extraGet,
   8152                                                        NULL);
   8153                             if (BCM_E_NONE == result) {
   8154                                 sal_memcpy(&mdbExtras,
   8155                                            extraGet,
   8156                                            sizeof(mdbExtras));
   8157                                 auxpool = size[res][0] - mdbExtras.bank_size;
   8158                                 size[res][0] = mdbExtras.bank_size;
   8159                                 for (index = 1;
   8160                                      (index < TEST_BLOCKS) &&
   8161                                      (auxpool > 0);
   8162                                      index++) {
   8163                                     base[res][index] = base[res][index-1] +
   8164                                                        mdbExtras.bank_size;
   8165                                     if (auxpool > mdbExtras.bank_size) {
   8166                                         size[res][index] = mdbExtras.bank_size;
   8167                                         auxpool -= mdbExtras.bank_size;
   8168                                     } else {
   8169                                         size[res][index] = auxpool;
   8170                                         auxpool = 0;
   8171                                     }
   8172                                 }
   8173                                 while (index < TEST_BLOCKS) {
   8174                                     base[res][index] = 0;
   8175                                     size[res][index] = 0;
   8176                                     index++;
   8177                                 }
   8178                                 if (auxpool) {
   8179                                     cli_out("test will not cover all of %p"
   8180                                             " resource %d: not enough workspace"
   8181                                             " to cover all banks; %d elements"
   8182                                             " left\n",
   8183                                             (void*)localRes,
   8184                                             res,
   8185                                             auxpool);
   8186                                     skip[res] = TRUE;
   8187                                 }
   8188                             }
   8189                         } else {
   8190                             for (index = 1;
   8191                                  index < TEST_BLOCKS;
   8192                                  index++) {
   8193                                 base[res][index] = 0;
   8194                                 size[res][index] = 0;
   8195                             }
   8196                         }
   8197                     }
   8198                     if (BCM_E_NONE != result) {
   8199                         cli_out("unable to retrieve %p type %d -> pool %d"
   8200                                 " manager info: %d (%s)\n",
   8201                                 (void*)localRes,
   8202                                 res,
   8203                                 pool,
   8204                                 result,
   8205                                 _SHR_ERRMSG(result));
   8206                     }
   8207                 } else {
   8208                     cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   8209                             (void*)localRes,
   8210                             res,
   8211                             result,
   8212                             _SHR_ERRMSG(result));
   8213                 }
   8214                 used = FALSE;
   8215                 for (index = 0;
   8216                      (BCM_E_NONE == result) && (index < res);
   8217                      index++) {
   8218                     result = shr_mres_type_get(localRes,
   8219                                                index,
   8220                                                &auxpool,
   8221                                                NULL,
   8222                                                NULL);
   8223                     if (BCM_E_NONE != result) {
   8224                         cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   8225                                 (void*)localRes,
   8226                                 index,
   8227                                 result,
   8228                                 _SHR_ERRMSG(result));
   8229                     } else if (auxpool == pool) {
   8230                         used = TRUE;
   8231                         break;
   8232                     }
   8233                 }
   8234                 if (BCM_E_NONE == result) {
   8235                     for (index = 0;
   8236                          index < (TEST_BLOCKS);
   8237                          index++) {
   8238                         if (0 == size[res][index]) {
   8239                             /* no more blocks to cover here */
   8240                             break;
   8241                         }
   8242                         result = shr_mres_alloc(localRes,
   8243                                                 res,
   8244                                                 SHR_RES_ALLOC_WITH_ID,
   8245                                                 size[res][index],
   8246                                                 &(base[res][index]));
   8247                         cli_out("allocated %p:%d:%d\r",
   8248                                 (void*)localRes,
   8249                                 res,
   8250                                 index);
   8251                         if (!used) {
   8252                             /* BCM_E_NONE is expected result */
   8253                             if (BCM_E_NONE != result) {
   8254                                 cli_out("unable to allocate %p type %d (pool"
   8255                                         " %d) range of %d..%d: %d (%s)\n",
   8256                                         (void*)localRes,
   8257                                         res,
   8258                                         pool,
   8259                                         base[res][index],
   8260                                         base[res][index] + size[res][index] - 1,
   8261                                         result,
   8262                                         _SHR_ERRMSG(result));
   8263                             }
   8264                         } else {
   8265                             /* BCM_E_RESOURCE is expected result */
   8266                             if (BCM_E_NONE == result) {
   8267                                 if (!skip[res]) {
   8268                                     cli_out("should not have been able to"
   8269                                             "allocate %p type %d because type"
   8270                                             " %d should have already consumed"
   8271                                             " all of pool %d\n",
   8272                                             (void*)localRes,
   8273                                             res,
   8274                                             index,
   8275                                             pool);
   8276                                     result = BCM_E_INTERNAL;
   8277                                 }
   8278                             } else if (BCM_E_RESOURCE != result) {
   8279                                 cli_out("unexpected error allocating %p type %d"
   8280                                         " (pool %d) entire range %d..%d:"
   8281                                         " %d (%s)\n",
   8282                                         (void*)localRes,
   8283                                         res,
   8284                                         pool,
   8285                                         base[res][index],
   8286                                         base[res][index] + size[res][index] - 1,
   8287                                         result,
   8288                                         _SHR_ERRMSG(result));
   8289                             } else {
   8290                                 /* expected in use; don't free it either */
   8291                                 result = BCM_E_NONE;
   8292                                 size[res][index] = 0;
   8293                             }
   8294                         }
   8295                     }
   8296                 }
   8297             }
   8298             for (res = 0;
   8299                  (BCM_E_NONE == result) && (res < rescount);
   8300                  res++) {
   8301                 result = shr_mres_alloc(localRes,
   8302                                         res,
   8303                                         0 /* flags */,
   8304                                         1 /* count */,
   8305                                         &auxpool);
   8306                 if (BCM_E_NONE == result) {
   8307                     if (!skip[res]) {
   8308                         cli_out("%p res %d was able to allocate another"
   8309                                 " element %d when the entire pool should have"
   8310                                 " been already in use\n",
   8311                                 (void*)localRes,
   8312                                 res,
   8313                                 auxpool);
   8314                     }
   8315                     result = shr_mres_free(localRes, res, 1, auxpool);
   8316                     if (BCM_E_NONE != result) {
   8317                         cli_out("%p res %d was unable to return element"
   8318                                 " %d to free: %d (%s)\n",
   8319                                 (void*)localRes,
   8320                                 res,
   8321                                 auxpool,
   8322                                 result,
   8323                                 _SHR_ERRMSG(result));
   8324                     }
   8325                     result = BCM_E_INTERNAL;
   8326                 } else if (BCM_E_RESOURCE != result) {
   8327                     cli_out("%p res %d encountered an unexpected error trying"
   8328                             " to allocate another element when it should have"
   8329                             " been full: %d (%s)\n",
   8330                             (void*)localRes,
   8331                             res,
   8332                             result,
   8333                             _SHR_ERRMSG(result));
   8334                 } else {
   8335                     /* this is okay, so keep going */
   8336                     result = BCM_E_NONE;
   8337                 }
   8338             }
   8339             for (res = 0;
   8340                  (BCM_E_NONE == result) && (res < rescount);
   8341                  res++) {
   8342                 for (index = 0;
   8343                      index < TEST_BLOCKS;
   8344                      index++) {
   8345                     if (size[res][index]) {
   8346                         result = shr_mres_free(localRes,
   8347                                                res,
   8348                                                size[res][index],
   8349                                                base[res][index]);
   8350                         cli_out("freed %p:%d:%d                \r",
   8351                                 (void*)localRes,
   8352                                 res,
   8353                                 index);
   8354                         if (BCM_E_NONE != result) {
   8355                             cli_out("failed to free %p resource %d block %d of"
   8356                                     " %d elements at %d: %d (%s)\n",
   8357                                     (void*)localRes,
   8358                                     res,
   8359                                     index,
   8360                                     size[res][index],
   8361                                     base[res][index],
   8362                                     result,
   8363                                     _SHR_ERRMSG(result));
   8364                         }
   8365                     }
   8366                 }
   8367             }
   8368             for (res = 0;
   8369                  (BCM_E_NONE == result) && (res < rescount);
   8370                  res++) {
   8371                 result = shr_mres_alloc(localRes,
   8372                                         res,
   8373                                         0 /* flags */,
   8374                                         1 /* count */,
   8375                                         &auxpool);
   8376                 if (BCM_E_NONE != result) {
   8377                     cli_out("%p res %d was unable to allocate an element"
   8378                             " after being filled and them freed: %d (%s)\n",
   8379                             (void*)localRes,
   8380                             res,
   8381                             result,
   8382                             _SHR_ERRMSG(result));
   8383                 } else {
   8384                     result = shr_mres_free(localRes, res, 1, auxpool);
   8385                     if (BCM_E_NONE != result) {
   8386                         cli_out("%p res %d was unable to return element"
   8387                                 " %d to free: %d (%s)\n",
   8388                                 (void*)localRes,
   8389                                 res,
   8390                                 auxpool,
   8391                                 result,
   8392                                 _SHR_ERRMSG(result));
   8393                     }
   8394                 }
   8395             }
   8396             for (res = 0;
   8397                  (BCM_E_NONE == result) && (res < rescount);
   8398                  res++) {
   8399                 if (size[res][0]) {
   8400                     cli_out("%p resource %d allocated and freed\n",
   8401                             (void*)localRes,
   8402                             res);
   8403                 } else {
   8404                     cli_out("%p resource %d overlapped another resource"
   8405                             " (same pool)\n",
   8406                             (void*)localRes,
   8407                             res);
   8408                 }
   8409             }
   8410         } else { /* if (localRes) */
   8411             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   8412         } /* if (localRes) */
   8413     } else if (!sal_strncasecmp(c, "t4", resTestMax(sal_strlen(c), 2))) {
   8414         if (localRes) {
   8415             result = shr_mres_get(localRes, &rescount, NULL);
   8416             if (BCM_E_NONE == result) {
   8417                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   8418                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   8419                 }
   8420             } else {
   8421                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   8422                         (void*)localRes,
   8423                         result,
   8424                         _SHR_ERRMSG(result));
   8425                 rescount = 0;
   8426             }
   8427             for (res = 0;
   8428                  (BCM_E_NONE == result) && (res < rescount);
   8429                  res++) {
   8430                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   8431                 if (BCM_E_NONE == result) {
   8432                     result = shr_mres_pool_get(localRes,
   8433                                                pool,
   8434                                                &restype,
   8435                                                &(base[res][0]),
   8436                                                &(size[res][0]),
   8437                                                NULL,
   8438                                                NULL);
   8439                 }
   8440                 if (BCM_E_NONE == result) {
   8441                     result = shr_mres_free(localRes, res, 1, base[res][0]);
   8442                     if (BCM_E_NONE == result) {
   8443                         cli_out("%p resource %d freed element %d size 1 when"
   8444                                 " such a block should not exist\n",
   8445                                 (void*)localRes,
   8446                                 res,
   8447                                 base[res][0]);
   8448                         result = BCM_E_INTERNAL;
   8449                     } else if (BCM_E_NOT_FOUND != result) {
   8450                         cli_out("%p resource %d trying to free element %d size"
   8451                                 " 1 encountered an unexpected error: %d (%s)\n",
   8452                                 (void*)localRes,
   8453                                 res,
   8454                                 base[res][0],
   8455                                 result,
   8456                                 _SHR_ERRMSG(result));
   8457                     } else {
   8458                         result = BCM_E_NONE;
   8459                     }
   8460                 }
   8461             }
   8462             for (res = 0;
   8463                  (BCM_E_NONE == result) && (res < rescount);
   8464                  res++) {
   8465                 cli_out("was properly unable to free an unallocated block in"
   8466                         " %p resource %d\n",
   8467                         (void*)localRes,
   8468                         res);
   8469             }
   8470         } else { /* if (localRes) */
   8471             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   8472         } /* if (localRes) */
   8473     } else if (!sal_strncasecmp(c, "t5", resTestMax(sal_strlen(c), 2))) {
   8474         if (localRes) {
   8475             result = shr_mres_get(localRes, &rescount, NULL);
   8476             if (BCM_E_NONE == result) {
   8477                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   8478                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   8479                 }
   8480             } else {
   8481                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   8482                         (void*)localRes,
   8483                         result,
   8484                         _SHR_ERRMSG(result));
   8485                 rescount = 0;
   8486             }
   8487             res = 0;
   8488             do {
   8489                 do {
   8490                     result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   8491                     if (BCM_E_NONE == result) {
   8492                         result = shr_mres_pool_get(localRes,
   8493                                                    pool,
   8494                                                    &restype,
   8495                                                    &(base[res][0]),
   8496                                                    &(size[res][0]),
   8497                                                    NULL,
   8498                                                    NULL);
   8499                         if ((BCM_E_NONE == result)  &&
   8500                             ((size[res][0] < 512) ||
   8501                              ((SHR_RES_ALLOCATOR_BITMAP != restype) &&
   8502                               (SHR_RES_ALLOCATOR_TAGGED_BITMAP != restype)))) {
   8503                             res++;
   8504                         }
   8505                     } else {
   8506                         cli_out("unable to retrieve %p res type %d info: %d (%s)\n",
   8507                                 (void*)localRes,
   8508                                 res,
   8509                                 result,
   8510                                 _SHR_ERRMSG(result));
   8511                     }
   8512                 } while ((res < rescount) &&
   8513                          (BCM_E_NONE == result) &&
   8514                          ((size[res][0] < 512) ||
   8515                           ((SHR_RES_ALLOCATOR_BITMAP != restype) &&
   8516                            (SHR_RES_ALLOCATOR_TAGGED_BITMAP != restype))));
   8517                 /* now res is a bitmap type and we know its base and size */
   8518                 if (res < rescount) {
   8519                     cli_out("using resource ID %d\n", res);
   8520                     /* allocate some aligned to base of pool, no offset */
   8521                     xresult = BCM_E_NONE;
   8522                     for (index = 1;
   8523                          (index < 17) && (BCM_E_NONE == result);
   8524                          index++) {
   8525                         size[res][index] = 7;
   8526                         result = shr_mres_alloc_align(localRes,
   8527                                                       res,
   8528                                                       0 /* flags */,
   8529                                                       index /* align */,
   8530                                                       0 /* offset */,
   8531                                                       size[res][index],
   8532                                                       &(base[res][index]));
   8533                         if (BCM_E_NONE == result) {
   8534                             cli_out("allocated %2d elems at %5d, align %2d, offset"
   8535                                     " %2d; offset = %2d: ",
   8536                                     size[res][index],
   8537                                     base[res][index],
   8538                                     index,
   8539                                     0,
   8540                                     (base[res][index] - base[res][0]) % index);
   8541                             if (0 == ((base[res][index] - base[res][0]) % index)) {
   8542                                 cli_out("PASS\n");
   8543                             } else {
   8544                                 cli_out("FAIL\n");
   8545                                 xresult = BCM_E_FAIL;
   8546                             }
   8547                         } else {
   8548                             cli_out("failed to alloc %d elems, align %d, offset %d:"
   8549                                     " %d %s)\n",
   8550                                     size[res][index],
   8551                                     index,
   8552                                     0,
   8553                                     result,
   8554                                     _SHR_ERRMSG(result));
   8555                             xresult = result;
   8556                         }
   8557                     }
   8558                     while (index > 1) {
   8559                         index--;
   8560                         result = shr_mres_free(localRes,
   8561                                                res,
   8562                                                size[res][index],
   8563                                                base[res][index]);
   8564                         if (BCM_E_NONE != result) {
   8565                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8566                                     size[res][index],
   8567                                     base[res][index],
   8568                                     result,
   8569                                     _SHR_ERRMSG(result));
   8570                             xresult = result;
   8571                         }
   8572                     }
   8573                     for (index = 1;
   8574                          (index < 17) && (BCM_E_NONE == result);
   8575                          index++) {
   8576                         size[res][index] = 7;
   8577                         result = shr_mres_alloc_align(localRes,
   8578                                                       res,
   8579                                                       0 /* flags */,
   8580                                                       16 /* align */,
   8581                                                       index - 1 /* offset */,
   8582                                                       size[res][index],
   8583                                                       &(base[res][index]));
   8584                         if (BCM_E_NONE == result) {
   8585                             cli_out("allocated %2d elems at %5d, align %2d, offset"
   8586                                     " %2d; offset = %2d: ",
   8587                                     size[res][index],
   8588                                     base[res][index],
   8589                                     16,
   8590                                     index - 1,
   8591                                     (base[res][index] - base[res][0]) % (16));
   8592                             if ((index - 1) == ((base[res][index] -
   8593                                                  base[res][0]) % 16)) {
   8594                                 cli_out("PASS\n");
   8595                             } else {
   8596                                 cli_out("FAIL\n");
   8597                                 xresult = BCM_E_FAIL;
   8598                             }
   8599                         } else {
   8600                             cli_out("failed to alloc %d elems, align %d, offset %d:"
   8601                                     " %d %s)\n",
   8602                                     size[res][index],
   8603                                     index - 1,
   8604                                     0,
   8605                                     result,
   8606                                     _SHR_ERRMSG(result));
   8607                             xresult = result;
   8608                         }
   8609                     }
   8610                     while (index > 1) {
   8611                         index--;
   8612                         result = shr_mres_free(localRes,
   8613                                                res,
   8614                                                size[res][index],
   8615                                                base[res][index]);
   8616                         if (BCM_E_NONE != result) {
   8617                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8618                                     size[res][index],
   8619                                     base[res][index],
   8620                                     result,
   8621                                     _SHR_ERRMSG(result));
   8622                             xresult = result;
   8623                         }
   8624                     }
   8625                     for (index = 1;
   8626                          (index < 17) && (BCM_E_NONE == result);
   8627                          index++) {
   8628                         size[res][index] = 7;
   8629                         result = shr_mres_alloc_align(localRes,
   8630                                                       res,
   8631                                                       SHR_RES_ALLOC_ALIGN_ZERO,
   8632                                                       index /* align */,
   8633                                                       0 /* offset */,
   8634                                                       size[res][index],
   8635                                                       &(base[res][index]));
   8636                         if (BCM_E_NONE == result) {
   8637                             cli_out("allocated %2d elems at %5d, align %2d, offset"
   8638                                     " %2d; offset = %2d: ",
   8639                                     size[res][index],
   8640                                     base[res][index],
   8641                                     index,
   8642                                     0,
   8643                                     base[res][index] % index);
   8644                             if (0 == (base[res][index] % index)) {
   8645                                 cli_out("PASS\n");
   8646                             } else {
   8647                                 cli_out("FAIL\n");
   8648                                 xresult = BCM_E_FAIL;
   8649                             }
   8650                         } else {
   8651                             cli_out("failed to alloc %d elems, align %d, offset %d:"
   8652                                     " %d %s)\n",
   8653                                     size[res][index],
   8654                                     index,
   8655                                     0,
   8656                                     result,
   8657                                     _SHR_ERRMSG(result));
   8658                             xresult = result;
   8659                         }
   8660                     }
   8661                     while (index > 1) {
   8662                         index--;
   8663                         result = shr_mres_free(localRes,
   8664                                                res,
   8665                                                size[res][index],
   8666                                                base[res][index]);
   8667                         if (BCM_E_NONE != result) {
   8668                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8669                                     size[res][index],
   8670                                     base[res][index],
   8671                                     result,
   8672                                     _SHR_ERRMSG(result));
   8673                             xresult = result;
   8674                         }
   8675                     }
   8676                     for (index = 1;
   8677                          (index < 17) && (BCM_E_NONE == result);
   8678                          index++) {
   8679                         size[res][index] = 7;
   8680                         result = shr_mres_alloc_align(localRes,
   8681                                                       res,
   8682                                                       SHR_RES_ALLOC_ALIGN_ZERO,
   8683                                                       16 /* align */,
   8684                                                       index - 1 /* offset */,
   8685                                                       size[res][index],
   8686                                                       &(base[res][index]));
   8687                         if (BCM_E_NONE == result) {
   8688                             cli_out("allocated %2d elems at %5d, align %2d, offset"
   8689                                     " %2d; offset = %2d: ",
   8690                                     size[res][index],
   8691                                     base[res][index],
   8692                                     16,
   8693                                     index - 1,
   8694                                     base[res][index] % 16);
   8695                             if ((index - 1) == (base[res][index] % 16)) {
   8696                                 cli_out("PASS\n");
   8697                             } else {
   8698                                 cli_out("FAIL\n");
   8699                                 xresult = BCM_E_FAIL;
   8700                             }
   8701                         } else {
   8702                             cli_out("failed to alloc %d elems, align %d, offset %d:"
   8703                                     " %d %s)\n",
   8704                                     size[res][index],
   8705                                     index - 1,
   8706                                     0,
   8707                                     result,
   8708                                     _SHR_ERRMSG(result));
   8709                             xresult = result;
   8710                         }
   8711                     }
   8712                     while (index > 1) {
   8713                         index--;
   8714                         result = shr_mres_free(localRes,
   8715                                                res,
   8716                                                size[res][index],
   8717                                                base[res][index]);
   8718                         if (BCM_E_NONE != result) {
   8719                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8720                                     size[res][index],
   8721                                     base[res][index],
   8722                                     result,
   8723                                     _SHR_ERRMSG(result));
   8724                             xresult = result;
   8725                         }
   8726                     }
   8727                     for (index = 1;
   8728                          (index < 17) && (BCM_E_NONE == result);
   8729                          index++) {
   8730                         size[res][index] = 7;
   8731                         result = shr_mres_alloc_align(localRes,
   8732                                                       res,
   8733                                                       SHR_RES_ALLOC_ALIGN_ZERO,
   8734                                                       17 /* align */,
   8735                                                       index - 1 /* offset */,
   8736                                                       size[res][index],
   8737                                                       &(base[res][index]));
   8738                         if (BCM_E_NONE == result) {
   8739                             cli_out("allocated %2d elems at %5d, align %2d, offset"
   8740                                     " %2d; offset = %2d: ",
   8741                                     size[res][index],
   8742                                     base[res][index],
   8743                                     17,
   8744                                     index - 1,
   8745                                     base[res][index] % 17);
   8746                             if ((index - 1) == (base[res][index] % 17)) {
   8747                                 cli_out("PASS\n");
   8748                             } else {
   8749                                 cli_out("FAIL\n");
   8750                                 xresult = BCM_E_FAIL;
   8751                             }
   8752                         } else {
   8753                             cli_out("failed to alloc %d elems, align %d, offset %d:"
   8754                                     " %d %s)\n",
   8755                                     size[res][index],
   8756                                     index - 1,
   8757                                     0,
   8758                                     result,
   8759                                     _SHR_ERRMSG(result));
   8760                             xresult = result;
   8761                         }
   8762                     }
   8763                     while (index > 1) {
   8764                         index--;
   8765                         result = shr_mres_free(localRes,
   8766                                                res,
   8767                                                size[res][index],
   8768                                                base[res][index]);
   8769                         if (BCM_E_NONE != result) {
   8770                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8771                                     size[res][index],
   8772                                     base[res][index],
   8773                                     result,
   8774                                     _SHR_ERRMSG(result));
   8775                             xresult = result;
   8776                         }
   8777                     }
   8778                     result = xresult;
   8779                     res++;
   8780                 } else {
   8781                     cli_out("no more sufficiently large bitmap based pools\n");
   8782                     result = BCM_E_INTERNAL;
   8783                 }
   8784             } while (BCM_E_NONE == result);
   8785             result = BCM_E_NONE;
   8786         } else { /* if (localRes) */
   8787             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   8788         } /* if (localRes) */
   8789     } else if (!sal_strncasecmp(c, "t6", resTestMax(sal_strlen(c), 2))) {
   8790         if (localRes) {
   8791             result = shr_mres_get(localRes, &rescount, NULL);
   8792             if (BCM_E_NONE == result) {
   8793                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   8794                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   8795                 }
   8796             } else {
   8797                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   8798                         (void*)localRes,
   8799                         result,
   8800                         _SHR_ERRMSG(result));
   8801                 rescount = 0;
   8802             }
   8803             res = 0;
   8804             do {
   8805                 do {
   8806                     result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   8807                     if (BCM_E_NONE == result) {
   8808                         result = shr_mres_pool_get(localRes,
   8809                                                    pool,
   8810                                                    &restype,
   8811                                                    &(base[res][0]),
   8812                                                    &(size[res][0]),
   8813                                                    NULL,
   8814                                                    NULL);
   8815                         if ((BCM_E_NONE == result)  &&
   8816                             ((size[res][0] < 512) ||
   8817                              (SHR_RES_ALLOCATOR_TAGGED_BITMAP != restype))) {
   8818                             res++;
   8819                         }
   8820                     } else {
   8821                         cli_out("unable to retrieve %p res type %d info: %d (%s)\n",
   8822                                 (void*)localRes,
   8823                                 res,
   8824                                 result,
   8825                                 _SHR_ERRMSG(result));
   8826                     }
   8827                 } while ((res < rescount) &&
   8828                          (BCM_E_NONE == result) &&
   8829                          ((size[res][0] < 512) ||
   8830                           (SHR_RES_ALLOCATOR_TAGGED_BITMAP != restype)));
   8831                 /* now res is a bitmap type and we know its base and size */
   8832                 if (res < rescount) {
   8833                     cli_out("using resource ID %d\n", res);
   8834                     /* allocate some aligned to base of pool, no offset */
   8835                     xresult = BCM_E_NONE;
   8836                     for (index = 1, curtag[0] = 0, curtag[1] = 0;
   8837                          (index < 17) && (BCM_E_NONE == result);
   8838                          index++,
   8839                          curtag[0] = (curtag[0] + 1) & 0x0F,
   8840                          curtag[1] = ((curtag[0]&0x1)?curtag[1]^0x01:curtag[1])) {
   8841                         size[res][index] = 7;
   8842                         if (2 == tagLen) {
   8843                             tag[res][index][0] = curtag[0] & 0x07;
   8844                             tag[res][index][1] = curtag[0] & 0x08;
   8845                         } else {
   8846                             tag[res][index][0] = curtag[0];
   8847                             tag[res][index][1] = curtag[1];
   8848                         }
   8849                         result = shr_mres_alloc_align_tag(localRes,
   8850                                                           res,
   8851                                                           0 /* flags */,
   8852                                                           index /* align */,
   8853                                                           0 /* offset */,
   8854                                                           &(tag[res][index][0]),
   8855                                                           size[res][index],
   8856                                                           &(base[res][index]));
   8857                         if (BCM_E_NONE == result) {
   8858                             cli_out("allocated %2d elems tag %02X%02X at %5d,"
   8859                                     " align  %2d, offset %2d; offset = %2d: ",
   8860                                     size[res][index],
   8861                                     tag[res][index][0],
   8862                                     tag[res][index][1],
   8863                                     base[res][index],
   8864                                     index,
   8865                                     0,
   8866                                     (base[res][index] - base[res][0]) % index);
   8867                             if (0 == ((base[res][index] - base[res][0]) % index)) {
   8868                                 cli_out("PASS\n");
   8869                             } else {
   8870                                 cli_out("FAIL\n");
   8871                                 xresult = BCM_E_FAIL;
   8872                             }
   8873                         } else {
   8874                             cli_out("failed to alloc %d elems tag %02X%02X,"
   8875                                     " align %2d, offset %d: %d %s)\n",
   8876                                     size[res][index],
   8877                                     tag[res][index][0],
   8878                                     tag[res][index][1],
   8879                                     index,
   8880                                     0,
   8881                                     result,
   8882                                     _SHR_ERRMSG(result));
   8883                             xresult = result;
   8884                         }
   8885                     }
   8886                     while (index > 1) {
   8887                         index--;
   8888                         result = shr_mres_free(localRes,
   8889                                                res,
   8890                                                size[res][index],
   8891                                                base[res][index]);
   8892                         if (BCM_E_NONE != result) {
   8893                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8894                                     size[res][index],
   8895                                     base[res][index],
   8896                                     result,
   8897                                     _SHR_ERRMSG(result));
   8898                             xresult = result;
   8899                         }
   8900                     }
   8901                     for (index = 1, curtag[0] = 0, curtag[1] = 0;
   8902                          (index < 17) && (BCM_E_NONE == result);
   8903                          index++,
   8904                          curtag[0] = (curtag[0] + 1) & 0x0F,
   8905                          curtag[1] = ((curtag[0]&0x1)?curtag[1]^0x01:curtag[1])) {
   8906                         size[res][index] = 7;
   8907                         if (2 == tagLen) {
   8908                             tag[res][index][0] = curtag[0] & 0x07;
   8909                             tag[res][index][1] = curtag[0] & 0x08;
   8910                         } else {
   8911                             tag[res][index][0] = curtag[0];
   8912                             tag[res][index][1] = curtag[1];
   8913                         }
   8914                         result = shr_mres_alloc_align_tag(localRes,
   8915                                                           res,
   8916                                                           0 /* flags */,
   8917                                                           16 /* align */,
   8918                                                           index - 1 /* offset */,
   8919                                                           &(tag[res][index][0]),
   8920                                                           size[res][index],
   8921                                                           &(base[res][index]));
   8922                         if (BCM_E_NONE == result) {
   8923                             cli_out("allocated %2d elems tag %02X%02X at %5d,"
   8924                                     " align %2d, offset %2d; offset = %2d: ",
   8925                                     size[res][index],
   8926                                     tag[res][index][0],
   8927                                     tag[res][index][1],
   8928                                     base[res][index],
   8929                                     16,
   8930                                     index - 1,
   8931                                     (base[res][index] - base[res][0]) % (16));
   8932                             if ((index - 1) == ((base[res][index] -
   8933                                                  base[res][0]) % 16)) {
   8934                                 cli_out("PASS\n");
   8935                             } else {
   8936                                 cli_out("FAIL\n");
   8937                                 xresult = BCM_E_FAIL;
   8938                             }
   8939                         } else {
   8940                             cli_out("failed to alloc %d elems tag %02X%02X,"
   8941                                     " align %2d, offset %d: %d %s)\n",
   8942                                     size[res][index],
   8943                                     tag[res][index][0],
   8944                                     tag[res][index][1],
   8945                                     index - 1,
   8946                                     0,
   8947                                     result,
   8948                                     _SHR_ERRMSG(result));
   8949                             xresult = result;
   8950                         }
   8951                     }
   8952                     while (index > 1) {
   8953                         index--;
   8954                         result = shr_mres_free(localRes,
   8955                                                res,
   8956                                                size[res][index],
   8957                                                base[res][index]);
   8958                         if (BCM_E_NONE != result) {
   8959                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   8960                                     size[res][index],
   8961                                     base[res][index],
   8962                                     result,
   8963                                     _SHR_ERRMSG(result));
   8964                             xresult = result;
   8965                         }
   8966                     }
   8967                     for (index = 1, curtag[0] = 0, curtag[1] = 0;
   8968                          (index < 17) && (BCM_E_NONE == result);
   8969                          index++,
   8970                          curtag[0] = (curtag[0] + 1) & 0x0F,
   8971                          curtag[1] = ((curtag[0]&0x1)?curtag[1]^0x01:curtag[1])) {
   8972                         size[res][index] = 7;
   8973                         if (2 == tagLen) {
   8974                             tag[res][index][0] = curtag[0] & 0x07;
   8975                             tag[res][index][1] = curtag[0] & 0x08;
   8976                         } else {
   8977                             tag[res][index][0] = curtag[0];
   8978                             tag[res][index][1] = curtag[1];
   8979                         }
   8980                         result = shr_mres_alloc_align_tag(localRes,
   8981                                                           res,
   8982                                                           SHR_RES_ALLOC_ALIGN_ZERO,
   8983                                                           index /* align */,
   8984                                                           0 /* offset */,
   8985                                                           &(tag[res][index][0]),
   8986                                                           size[res][index],
   8987                                                           &(base[res][index]));
   8988                         if (BCM_E_NONE == result) {
   8989                             cli_out("allocated %2d elems tag %02X%02X at %5d,"
   8990                                     " align %2d, offset %2d; offset = %2d: ",
   8991                                     size[res][index],
   8992                                     tag[res][index][0],
   8993                                     tag[res][index][1],
   8994                                     base[res][index],
   8995                                     index,
   8996                                     0,
   8997                                     base[res][index] % index);
   8998                             if (0 == (base[res][index] % index)) {
   8999                                 cli_out("PASS\n");
   9000                             } else {
   9001                                 cli_out("FAIL\n");
   9002                                 xresult = BCM_E_FAIL;
   9003                             }
   9004                         } else {
   9005                             cli_out("failed to alloc %d elems tag %02X%02X,"
   9006                                     " align %2d, offset %d: %d %s)\n",
   9007                                     size[res][index],
   9008                                     tag[res][index][0],
   9009                                     tag[res][index][1],
   9010                                     index,
   9011                                     0,
   9012                                     result,
   9013                                     _SHR_ERRMSG(result));
   9014                             xresult = result;
   9015                         }
   9016                     }
   9017                     while (index > 1) {
   9018                         index--;
   9019                         result = shr_mres_free(localRes,
   9020                                                res,
   9021                                                size[res][index],
   9022                                                base[res][index]);
   9023                         if (BCM_E_NONE != result) {
   9024                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   9025                                     size[res][index],
   9026                                     base[res][index],
   9027                                     result,
   9028                                     _SHR_ERRMSG(result));
   9029                             xresult = result;
   9030                         }
   9031                     }
   9032                     for (index = 1, curtag[0] = 0, curtag[1] = 0;
   9033                          (index < 17) && (BCM_E_NONE == result);
   9034                          index++,
   9035                          curtag[0] = (curtag[0] + 1) & 0x0F,
   9036                          curtag[1] = ((curtag[0]&0x1)?curtag[1]^0x01:curtag[1])) {
   9037                         size[res][index] = 7;
   9038                         if (2 == tagLen) {
   9039                             tag[res][index][0] = curtag[0] & 0x07;
   9040                             tag[res][index][1] = curtag[0] & 0x08;
   9041                         } else {
   9042                             tag[res][index][0] = curtag[0];
   9043                             tag[res][index][1] = curtag[1];
   9044                         }
   9045                         result = shr_mres_alloc_align_tag(localRes,
   9046                                                           res,
   9047                                                           SHR_RES_ALLOC_ALIGN_ZERO,
   9048                                                           16 /* align */,
   9049                                                           index - 1 /* offset */,
   9050                                                           &(tag[res][index][0]),
   9051                                                           size[res][index],
   9052                                                           &(base[res][index]));
   9053                         if (BCM_E_NONE == result) {
   9054                             cli_out("allocated %2d elems tag %02X%02X at %5d,"
   9055                                     " align %2d, offset %2d; offset = %2d: ",
   9056                                     size[res][index],
   9057                                     tag[res][index][0],
   9058                                     tag[res][index][1],
   9059                                     base[res][index],
   9060                                     16,
   9061                                     index - 1,
   9062                                     base[res][index] % 16);
   9063                             if ((index - 1) == (base[res][index] % 16)) {
   9064                                 cli_out("PASS\n");
   9065                             } else {
   9066                                 cli_out("FAIL\n");
   9067                                 xresult = BCM_E_FAIL;
   9068                             }
   9069                         } else {
   9070                             cli_out("failed to alloc %d elems tag %02X%02X,"
   9071                                     " align %2d, offset %d: %d %s)\n",
   9072                                     size[res][index],
   9073                                     tag[res][index][0],
   9074                                     tag[res][index][1],
   9075                                     index - 1,
   9076                                     0,
   9077                                     result,
   9078                                     _SHR_ERRMSG(result));
   9079                             xresult = result;
   9080                         }
   9081                     }
   9082                     while (index > 1) {
   9083                         index--;
   9084                         result = shr_mres_free(localRes,
   9085                                                res,
   9086                                                size[res][index],
   9087                                                base[res][index]);
   9088                         if (BCM_E_NONE != result) {
   9089                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   9090                                     size[res][index],
   9091                                     base[res][index],
   9092                                     result,
   9093                                     _SHR_ERRMSG(result));
   9094                             xresult = result;
   9095                         }
   9096                     }
   9097                     for (index = 1, curtag[0] = 0, curtag[1] = 0;
   9098                          (index < 17) && (BCM_E_NONE == result);
   9099                          index++,
   9100                          curtag[0] = (curtag[0] + 1) & 0x0F,
   9101                          curtag[1] = ((curtag[0]&0x1)?curtag[1]^0x01:curtag[1])) {
   9102                         size[res][index] = 7;
   9103                         if (2 == tagLen) {
   9104                             tag[res][index][0] = curtag[0] & 0x07;
   9105                             tag[res][index][1] = curtag[0] & 0x08;
   9106                         } else {
   9107                             tag[res][index][0] = curtag[0];
   9108                             tag[res][index][1] = curtag[1];
   9109                         }
   9110                         result = shr_mres_alloc_align_tag(localRes,
   9111                                                           res,
   9112                                                           SHR_RES_ALLOC_ALIGN_ZERO,
   9113                                                           17 /* align */,
   9114                                                           index - 1 /* offset */,
   9115                                                           &(tag[res][index][0]),
   9116                                                           size[res][index],
   9117                                                           &(base[res][index]));
   9118                         if (BCM_E_NONE == result) {
   9119                             cli_out("allocated %2d elems tag %02X%02X at %5d,"
   9120                                     " align %2d, offset %2d; offset = %2d: ",
   9121                                     size[res][index],
   9122                                     tag[res][index][0],
   9123                                     tag[res][index][1],
   9124                                     base[res][index],
   9125                                     17,
   9126                                     index - 1,
   9127                                     base[res][index] % 17);
   9128                             if ((index - 1) == (base[res][index] % 17)) {
   9129                                 cli_out("PASS\n");
   9130                             } else {
   9131                                 cli_out("FAIL\n");
   9132                                 xresult = BCM_E_FAIL;
   9133                             }
   9134                         } else {
   9135                             cli_out("failed to alloc %d elems tag %02X%02X,"
   9136                                     " align %2d, offset %d: %d %s)\n",
   9137                                     size[res][index],
   9138                                     tag[res][index][0],
   9139                                     tag[res][index][1],
   9140                                     index - 1,
   9141                                     0,
   9142                                     result,
   9143                                     _SHR_ERRMSG(result));
   9144                             xresult = result;
   9145                         }
   9146                     }
   9147                     while (index > 1) {
   9148                         index--;
   9149                         result = shr_mres_free(localRes,
   9150                                                res,
   9151                                                size[res][index],
   9152                                                base[res][index]);
   9153                         if (BCM_E_NONE != result) {
   9154                             cli_out("unable to free %d elems at %d: %d (%s)\n",
   9155                                     size[res][index],
   9156                                     base[res][index],
   9157                                     result,
   9158                                     _SHR_ERRMSG(result));
   9159                             xresult = result;
   9160                         }
   9161                     }
   9162                     result = xresult;
   9163                     res++;
   9164                 } else {
   9165                     cli_out("no more sufficiently large bitmap based pools\n");
   9166                     result = BCM_E_INTERNAL;
   9167                 }
   9168             } while (BCM_E_NONE == result);
   9169             result = BCM_E_NONE;
   9170         } else { /* if (localRes) */
   9171             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   9172         } /* if (localRes) */
   9173     } else if (!sal_strncasecmp(c, "t7", resTestMax(sal_strlen(c), 2))) {
   9174         if (localRes) {
   9175             for (auxpool = 0; auxpool < 2; auxpool++) {
   9176                 result = shr_mres_get(localRes, &rescount, NULL);
   9177                 if (BCM_E_NONE == result) {
   9178                     if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
   9179                         rescount = SHR_RES_ALLOCATOR_COUNT << 1;
   9180                     }
   9181                 } else {
   9182                     cli_out("unable to retrieve %p resource type count : %d (%s)\n",
   9183                             (void*)localRes,
   9184                             result,
   9185                             _SHR_ERRMSG(result));
   9186                     rescount = 0;
   9187                 }
   9188                 for (res = 0;
   9189                      (BCM_E_NONE == result) && (res < rescount);
   9190                      res++) {
   9191                     result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   9192                     if (BCM_E_NONE == result) {
   9193                         result = shr_mres_pool_get(localRes,
   9194                                                    pool,
   9195                                                    &restype,
   9196                                                    NULL,
   9197                                                    NULL,
   9198                                                    NULL,
   9199                                                    NULL);
   9200                         if (BCM_E_NONE != result) {
   9201                             cli_out("unable to retrieve %p type %d -> pool %d"
   9202                                     " manager: %d (%s)\n",
   9203                                     (void*)localRes,
   9204                                     res,
   9205                                     pool,
   9206                                     result,
   9207                                     _SHR_ERRMSG(result));
   9208                         }
   9209                     } else {
   9210                         cli_out("unable to retrieve %p type %d pool: %d (%s)\n",
   9211                                 (void*)localRes,
   9212                                 res,
   9213                                 result,
   9214                                 _SHR_ERRMSG(result));
   9215                     }
   9216                     skip[res] = FALSE;
   9217                     if (BCM_E_NONE == result) {
   9218                         if (restype != SHR_RES_ALLOCATOR_TAGGED_BITMAP) {
   9219                             skip[res] = TRUE;
   9220                             continue;
   9221                         }
   9222                     }
   9223                     for (index = 0, curtag[0] = 0, curtag[1] = 0;
   9224                          (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   9225                          index++,
   9226                          curtag[0] = (curtag[0] + 1) & 0x0F,
   9227                          curtag[1] = ((curtag[0]&0x1)?curtag[1]^0x01:curtag[1])) {
   9228                         if (auxpool) {
   9229                             size[res][index] = TEST_BLOCKS - index;
   9230                         } else {
   9231                             size[res][index] = 1 + index;
   9232                         }
   9233                         if (2 == tagLen) {
   9234                             tag[res][index][0] = curtag[0] & 0x07;
   9235                             tag[res][index][1] = curtag[0] & 0x08;
   9236                         } else {
   9237                             tag[res][index][0] = curtag[0];
   9238                             tag[res][index][1] = curtag[1];
   9239                         }
   9240                         result = shr_mres_alloc_tag(localRes,
   9241                                                     res,
   9242                                                     0 /* flags */,
   9243                                                     &(tag[res][index][0]),
   9244                                                     size[res][index],
   9245                                                     &(base[res][index]));
   9246                         cli_out("allocated %p:%d:%d\r",
   9247                                 (void*)localRes,
   9248                                 res,
   9249                                 index);
   9250                         if (BCM_E_NONE != result) {
   9251                             cli_out("failed to allocate %p resource %d block %d"
   9252                                     " of %d elements tag %02X%02X: %d (%s)\n",
   9253                                     (void*)localRes,
   9254                                     res,
   9255                                     index,
   9256                                     size[res][index],
   9257                                     tag[res][index][0],
   9258                                     tag[res][index][1],
   9259                                     result,
   9260                                     _SHR_ERRMSG(result));
   9261                         }
   9262                     }
   9263                 }
   9264                 for (res = 0;
   9265                      (BCM_E_NONE == result) && (res < rescount);
   9266                      res++) {
   9267                     if (skip[res]) {
   9268                         continue;
   9269                     }
   9270                     for (index = 0;
   9271                          (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   9272                          index++) {
   9273                         result = shr_mres_check(localRes,
   9274                                                 res,
   9275                                                 size[res][index],
   9276                                                 base[res][index]);
   9277                         cli_out("checked %p:%d:%d     \r",
   9278                                 (void*)localRes,
   9279                                 res,
   9280                                 index);
   9281                         if (BCM_E_EXISTS != result) {
   9282                             cli_out("unexpected result checking %p resource %d"
   9283                                     " block %d at %d (%d elements tag %02X%02X):"
   9284                                     " %d (%s)\n",
   9285                                     (void*)localRes,
   9286                                     res,
   9287                                     index,
   9288                                     base[res][index],
   9289                                     size[res][index],
   9290                                     tag[res][index][0],
   9291                                     tag[res][index][1],
   9292                                     result,
   9293                                     _SHR_ERRMSG(result));
   9294                             result = BCM_E_INTERNAL;
   9295                         } else {
   9296                             /* correct value */
   9297                             result = BCM_E_NONE;
   9298                         }
   9299                     }
   9300                 }
   9301                 for (res = 0;
   9302                      (BCM_E_NONE == result) && (res < rescount);
   9303                      res++) {
   9304                     if (skip[res]) {
   9305                         continue;
   9306                     }
   9307                     cli_out("free resource %d\n", res);
   9308                     for (index = 0;
   9309                          (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   9310                          index++) {
   9311                         result = shr_mres_free(localRes,
   9312                                                res,
   9313                                                size[res][index],
   9314                                                base[res][index]);
   9315                         cli_out("freed %p:%d:%d                \r",
   9316                                 (void*)localRes,
   9317                                 res,
   9318                                 index);
   9319                         if (BCM_E_NONE != result) {
   9320                             cli_out("failed to free %p resource %d block %d of"
   9321                                     " %d elements tag %02X%02X at %d: %d (%s)\n",
   9322                                     (void*)localRes,
   9323                                     res,
   9324                                     index,
   9325                                     size[res][index],
   9326                                     tag[res][index][0],
   9327                                     tag[res][index][1],
   9328                                     base[res][index],
   9329                                     result,
   9330                                     _SHR_ERRMSG(result));
   9331                         }
   9332                     }
   9333                 }
   9334                 for (res = 0;
   9335                      (BCM_E_NONE == result) && (res < rescount);
   9336                      res++) {
   9337                     if (skip[res]) {
   9338                         continue;
   9339                     }
   9340                     for (index = 0;
   9341                          (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   9342                          index++) {
   9343                         result = shr_mres_check(localRes,
   9344                                                 res,
   9345                                                 size[res][index],
   9346                                                 base[res][index]);
   9347                         cli_out("checked %p:%d:%d     \r",
   9348                                 (void*)localRes,
   9349                                 res,
   9350                                 index);
   9351                         if (BCM_E_NOT_FOUND != result) {
   9352                             cli_out("unexpected result checking %p resource %d"
   9353                                     " block %d at %d (%d elements tag %02X%02X):"
   9354                                     " %d (%s)\n",
   9355                                     (void*)localRes,
   9356                                     res,
   9357                                     index,
   9358                                     base[res][index],
   9359                                     size[res][index],
   9360                                     tag[res][index][0],
   9361                                     tag[res][index][1],
   9362                                     result,
   9363                                     _SHR_ERRMSG(result));
   9364                             result = BCM_E_INTERNAL;
   9365                         } else {
   9366                             /* correct value */
   9367                             result = BCM_E_NONE;
   9368                         }
   9369                     }
   9370                 }
   9371                 for (res = 0;
   9372                      (BCM_E_NONE == result) && (res < rescount);
   9373                      res++) {
   9374                     if (skip[res]) {
   9375                         continue;
   9376                     }
   9377                     cli_out("%p resource %d allocated and freed:\n",
   9378                             (void*)localRes,
   9379                             res);
   9380                     for (index = 0;
   9381                          (BCM_E_NONE == result) && (index < TEST_BLOCKS);
   9382                          index++) {
   9383                         cli_out("  %4d(%4d)%02X%02X", base[res][index], size[res][index], tag[res][index][0], tag[res][index][1]);
   9384                         if (1 == (index & 1)) {
   9385                             cli_out("\n");
   9386                         }
   9387                     }
   9388                     if (0 != (index & 3)) {
   9389                         cli_out("\n");
   9390                     }
   9391                 }
   9392             }
   9393         } else { /* if (localRes) */
   9394             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   9395         } /* if (localRes) */
   9396     } else if (!sal_strncasecmp(c, "t8", resTestMax(sal_strlen(c), 2))) {
   9397         if (localRes) {
   9398             /* allocate a single element in all types */
   9399             cli_out("allocate one element of all types\n");
   9400             for (res = 0; res < (SHR_RES_ALLOCATOR_COUNT << 1); res++) {
   9401                 size[res][0] = 1;
   9402                 result = shr_mres_alloc(localRes,
   9403                                         res,
   9404                                         0 /* flags */,
   9405                                         size[res][0],
   9406                                         &(base[res][0]));
   9407                 if (BCM_FAILURE(result)) {
   9408                     break;
   9409                 }
   9410             }
   9411             if (BCM_FAILURE(result)) {
   9412                 cli_out("failed to allocate %d elem in %p type %d: %d (%s)\n",
   9413                         size[res][0],
   9414                         (void*)localRes,
   9415                         res,
   9416                         result,
   9417                         _SHR_ERRMSG(result));
   9418             }
   9419             /* will want an extra set of elements for checking later */
   9420             cli_out("allocate another element of all types\n");
   9421             for (res = 0; res < (SHR_RES_ALLOCATOR_COUNT << 1); res++) {
   9422                 size[res][1] = 1;
   9423                 result = shr_mres_alloc(localRes,
   9424                                         res,
   9425                                         0 /* flags */,
   9426                                         size[res][1],
   9427                                         &(base[res][1]));
   9428                 if (BCM_FAILURE(result)) {
   9429                     break;
   9430                 }
   9431             }
   9432             if (BCM_FAILURE(result)) {
   9433                 cli_out("failed to allocate %d elem in %p type %d: %d (%s)\n",
   9434                         size[res][1],
   9435                         (void*)localRes,
   9436                         res,
   9437                         result,
   9438                         _SHR_ERRMSG(result));
   9439             }
   9440             /* make sure can not destroy a type with elements */
   9441             if (BCM_E_NONE == result) {
   9442                 cli_out("try to destroy types with active elements\n");
   9443             }
   9444             for (res = 0;
   9445                  (BCM_E_NONE == result) &&
   9446                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9447                  res++) {
   9448                 result = shr_mres_type_unset(localRes, res);
   9449                 if (BCM_E_CONFIG == result) {
   9450                     /* this is the correct result */
   9451                     result = BCM_E_NONE;
   9452                 } else if (BCM_E_NONE == result) {
   9453                     /* should not have allowed this */
   9454                     cli_out("was allowed to destroy type %d with active"
   9455                             " elements\n",
   9456                             res);
   9457                     result = BCM_E_INTERNAL;
   9458                 } else {
   9459                     /* should never see other error codes */
   9460                     cli_out("unexpected error trying to destroy type %d with"
   9461                             " active elements: %d (%s)\n",
   9462                             res,
   9463                             result,
   9464                             _SHR_ERRMSG(result));
   9465                 }
   9466             }
   9467             /* make sure can not overwrite a type with elements */
   9468             cli_out("try to overwrite types with active elements\n");
   9469             for (res = 0;
   9470                  (BCM_E_NONE == result) &&
   9471                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9472                  res++) {
   9473                 sal_snprintf(&(name[0]),
   9474                              sizeof(name) - 1,
   9475                              "test: type %d",
   9476                              res);
   9477                 result = shr_mres_type_set(localRes,
   9478                                            res /* as type ID */,
   9479                                            res % SHR_RES_ALLOCATOR_COUNT,
   9480                                            1 /* element size */,
   9481                                            &(name[0]));
   9482                 if (BCM_E_CONFIG == result) {
   9483                     /* this is the correct result */
   9484                     result = BCM_E_NONE;
   9485                 } else if (BCM_E_NONE == result) {
   9486                     /* should not have allowed this */
   9487                     cli_out("was allowed to overwrite type %d with active"
   9488                             " elements\n",
   9489                             res);
   9490                     result = BCM_E_INTERNAL;
   9491                 } else {
   9492                     /* should never see other error codes */
   9493                     cli_out("unexpected error trying to overwrite type %d with"
   9494                             " active elements: %d (%s)\n",
   9495                             res,
   9496                             result,
   9497                             _SHR_ERRMSG(result));
   9498                 }
   9499             }
   9500             /* check inuse count for all types */
   9501             if (BCM_E_NONE == result) {
   9502                 cli_out("check in-use count for every type and pool\n");
   9503             }
   9504             for (res = 0;
   9505                  (BCM_E_NONE == result) &&
   9506                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9507                  res++) {
   9508                 result = shr_mres_type_info_get(localRes,
   9509                                                 res,
   9510                                                 &typeInfo);
   9511                 if (BCM_E_NONE == result) {
   9512                     if (typeInfo.used != size[res][0] + size[res][1]) {
   9513                         cli_out("incorrect used count for %p type %d: %d but"
   9514                                 " should be %d\n",
   9515                                 (void*)localRes,
   9516                                 res,
   9517                                 typeInfo.used,
   9518                                 size[res][0] + size[res][1]);
   9519                         result = BCM_E_INTERNAL;
   9520                     }
   9521                 }
   9522             }
   9523             for (res = 0;
   9524                  (BCM_E_NONE == result) &&
   9525                  (res < SHR_RES_ALLOCATOR_COUNT);
   9526                  res++) {
   9527                 result = shr_mres_pool_info_get(localRes,
   9528                                                 res,
   9529                                                 &poolInfo);
   9530                 if (BCM_E_NONE == result) {
   9531                     if (poolInfo.used != (size[res][0] + size[res][1] +
   9532                                           size[res+SHR_RES_ALLOCATOR_COUNT][0] +
   9533                                           size[res+SHR_RES_ALLOCATOR_COUNT][1])) {
   9534                         cli_out("incorrect used count for %p pool %d: %d but"
   9535                                 " should be %d\n",
   9536                                 (void*)localRes,
   9537                                 res,
   9538                                 poolInfo.used,
   9539                                 size[res][0] +
   9540                                 size[res][1] +
   9541                                 size[res+SHR_RES_ALLOCATOR_COUNT][0] +
   9542                                 size[res+SHR_RES_ALLOCATOR_COUNT][1]);
   9543                         result = BCM_E_INTERNAL;
   9544                     }
   9545                 }
   9546             }
   9547             /* free and check a single element in all types */
   9548             if (BCM_E_NONE == result) {
   9549                 cli_out("free one element of every type & check status\n");
   9550             }
   9551             for (res = 0;
   9552                  (BCM_E_NONE == result) &&
   9553                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9554                  res++) {
   9555                 result = shr_mres_free_and_status(localRes,
   9556                                                   res,
   9557                                                   size[res][0],
   9558                                                   base[res][0],
   9559                                                   &statusFlags);
   9560                 if (BCM_E_NONE == result) {
   9561                     if (statusFlags & SHR_RES_FREED_TYPE_LAST_ELEM) {
   9562                         cli_out("unexpected last element in %p type"
   9563                                 " %d; should not be empty yet\n",
   9564                                 (void*)localRes,
   9565                                 res);
   9566                         result = BCM_E_INTERNAL;
   9567                     }
   9568                     if (statusFlags & SHR_RES_FREED_POOL_LAST_ELEM) {
   9569                         cli_out("unexpected last element in %p type"
   9570                                 " %d pool; should not be empty yet\n",
   9571                                 (void*)localRes,
   9572                                 res);
   9573                         result = BCM_E_INTERNAL;
   9574                     }
   9575                 } else {
   9576                     cli_out("failed to free %d elem at %d in %p type %d:"
   9577                             " %d (%s)\n",
   9578                             size[res][0],
   9579                             base[res][0],
   9580                             (void*)localRes,
   9581                             res,
   9582                             result,
   9583                             _SHR_ERRMSG(result));
   9584                 }
   9585             }
   9586             /* free and check the last element in all types */
   9587             if (BCM_E_NONE == result) {
   9588                 cli_out("free remaining element of every type and check status\n");
   9589             }
   9590             for (res = 0;
   9591                  (BCM_E_NONE == result) &&
   9592                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9593                  res++) {
   9594                 result = shr_mres_free_and_status(localRes,
   9595                                                   res,
   9596                                                   size[res][1],
   9597                                                   base[res][1],
   9598                                                   &statusFlags);
   9599                 if (BCM_E_NONE == result) {
   9600                     if (0 == (statusFlags & SHR_RES_FREED_TYPE_LAST_ELEM)) {
   9601                         cli_out("expected but did not see last element"
   9602                                 " indicator for %p type %d\n",
   9603                                 (void*)localRes,
   9604                                 res);
   9605                         result = BCM_E_INTERNAL;
   9606                     }
   9607                     if (res < SHR_RES_ALLOCATOR_COUNT) {
   9608                         if (statusFlags & SHR_RES_FREED_POOL_LAST_ELEM) {
   9609                             cli_out("unexpected last element for %p type"
   9610                                     " %d pool; should not be empty yet\n",
   9611                                     (void*)localRes,
   9612                                     res);
   9613                             result = BCM_E_INTERNAL;
   9614                         }
   9615                     } else {
   9616                         if (0 == (statusFlags & SHR_RES_FREED_POOL_LAST_ELEM)) {
   9617                             cli_out("expected but did not see last element"
   9618                                     " indicator for %p type %d pool\n",
   9619                                     (void*)localRes,
   9620                                     res);
   9621                             result = BCM_E_INTERNAL;
   9622                         }
   9623                     }
   9624                 } else { /* if (BCM_E_NONE == result) */
   9625                     cli_out("failed to free %d elem at %d in %p type %d:"
   9626                             " %d (%s)\n",
   9627                             size[res][1],
   9628                             base[res][1],
   9629                             (void*)localRes,
   9630                             res,
   9631                             result,
   9632                             _SHR_ERRMSG(result));
   9633                 } /* if (BCM_E_NONE == result) */
   9634             } /* for (all types as long as no errors) */
   9635             /* try to reconfigure the underlying pools with types attached */
   9636             if (BCM_E_NONE == result) {
   9637                 cli_out("try to destroy pools with types using them\n");
   9638             }
   9639             for (index = 0;
   9640                  (BCM_E_NONE == result) && (index < SHR_RES_ALLOCATOR_COUNT);
   9641                  index++) {
   9642                 result = shr_mres_pool_unset(localRes, index);
   9643                 if (BCM_E_CONFIG == result) {
   9644                     /* desired result */
   9645                     result = BCM_E_NONE;
   9646                 } else if (BCM_E_NONE == result) {
   9647                     /* should not have been able to do this */
   9648                     cli_out("should not have been able to remove %p pool %d\n,",
   9649                             (void*)localRes,
   9650                             index);
   9651                     result = BCM_E_INTERNAL;
   9652                 } else {
   9653                     cli_out("unexpected error removing %p pool %d: %d (%s)\n",
   9654                             (void*)localRes,
   9655                             index,
   9656                             result,
   9657                             _SHR_ERRMSG(result));
   9658                 }
   9659             }
   9660             if (BCM_E_NONE == result) {
   9661                 cli_out("try to overwrite pools with types using them\n");
   9662             }
   9663             for (index = 0;
   9664                  (BCM_E_NONE == result) && (index < SHR_RES_ALLOCATOR_COUNT);
   9665                  index++) {
   9666                 switch (index) {
   9667                 case SHR_RES_ALLOCATOR_BITMAP:
   9668                     extraPtr = NULL;
   9669                     break;
   9670                 case SHR_RES_ALLOCATOR_TAGGED_BITMAP:
   9671                     extraPtr = &tagBitmapExtras;
   9672                     tagBitmapExtras.grain_size = 4;
   9673                     tagBitmapExtras.tag_length = 1;
   9674                     break;
   9675                 case SHR_RES_ALLOCATOR_IDXRES:
   9676                     extraPtr = &idxresExtras;
   9677                     idxresExtras.scaling_factor = 1;
   9678                     break;
   9679                 case SHR_RES_ALLOCATOR_AIDXRES:
   9680                     extraPtr = &aidxresExtras;
   9681                     aidxresExtras.blocking_factor = 7;
   9682                     break;
   9683                 case SHR_RES_ALLOCATOR_MDB:
   9684                     extraPtr = &mdbExtras;
   9685                     mdbExtras.bank_size = 1024;
   9686                     mdbExtras.free_lists = 10;
   9687                     mdbExtras.free_counts[0] = 2;
   9688                     mdbExtras.free_counts[1] = 4;
   9689                     mdbExtras.free_counts[2] = 8;
   9690                     mdbExtras.free_counts[3] = 16;
   9691                     mdbExtras.free_counts[4] = 32;
   9692                     mdbExtras.free_counts[5] = 64;
   9693                     mdbExtras.free_counts[6] = 128;
   9694                     mdbExtras.free_counts[7] = 256;
   9695                     mdbExtras.free_counts[8] = 512;
   9696                     mdbExtras.free_counts[9] = 1024;
   9697                     break;
   9698                 default:
   9699                     extraPtr = NULL;
   9700                 } /* switch(index) */
   9701                 sal_snprintf(&(name[0]),
   9702                              sizeof(name) - 1,
   9703                              "test: pool %d",
   9704                              index);
   9705                 result = shr_mres_pool_set(localRes,
   9706                                            index /* as pool ID */,
   9707                                            index /* as manager type */,
   9708                                            1024 /* low ID */,
   9709                                            6144 /* count */,
   9710                                            extraPtr,
   9711                                            &(name[0]));
   9712                 if (BCM_E_CONFIG == result) {
   9713                     /* desired result */
   9714                     result = BCM_E_NONE;
   9715                 } else if (BCM_E_NONE == result) {
   9716                     /* should not have been able to do this */
   9717                     cli_out("should not have been able to remove %p pool %d\n,",
   9718                             (void*)localRes,
   9719                             index);
   9720                     result = BCM_E_INTERNAL;
   9721                 } else {
   9722                     cli_out("unexpected error overwriting %p pool %d: %d (%s)\n",
   9723                             (void*)localRes,
   9724                             index,
   9725                             result,
   9726                             _SHR_ERRMSG(result));
   9727                 }
   9728             }
   9729             /* make sure can not overwrite a type with elements */
   9730             if (BCM_E_NONE == result) {
   9731                 cli_out("overwrite types\n");
   9732             }
   9733             for (res = 0;
   9734                  (BCM_E_NONE == result) &&
   9735                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9736                  res++) {
   9737                 sal_snprintf(&(name[0]),
   9738                              sizeof(name) - 1,
   9739                              "test: type %d",
   9740                              res);
   9741                 result = shr_mres_type_set(localRes,
   9742                                            res /* as type ID */,
   9743                                            res % SHR_RES_ALLOCATOR_COUNT,
   9744                                            1 /* element size */,
   9745                                            &(name[0]));
   9746                 if (BCM_E_NONE != result) {
   9747                     /* should never see other error codes */
   9748                     cli_out("unexpected error trying to overwrite type %d with"
   9749                             " active elements: %d (%s)\n",
   9750                             res,
   9751                             result,
   9752                             _SHR_ERRMSG(result));
   9753                 }
   9754             }
   9755             if (BCM_E_NONE == result) {
   9756                 cli_out("destroy types\n");
   9757             }
   9758             for (res = 0;
   9759                  (BCM_E_NONE == result) &&
   9760                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9761                  res++) {
   9762                 result = shr_mres_type_unset(localRes, res);
   9763                 if (BCM_E_NONE != result) {
   9764                     /* should never see other error codes */
   9765                     cli_out("unexpected error trying to destroy type %d:"
   9766                             " %d (%s)\n",
   9767                             res,
   9768                             result,
   9769                             _SHR_ERRMSG(result));
   9770                 }
   9771             }
   9772             if (BCM_E_NONE == result) {
   9773                 cli_out("recreate types\n");
   9774             }
   9775             for (res = 0;
   9776                  (BCM_E_NONE == result) &&
   9777                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9778                  res++) {
   9779                 sal_snprintf(&(name[0]),
   9780                              sizeof(name) - 1,
   9781                              "test: type %d",
   9782                              res);
   9783                 result = shr_mres_type_set(localRes,
   9784                                            res /* as type ID */,
   9785                                            res % SHR_RES_ALLOCATOR_COUNT,
   9786                                            1 /* element size */,
   9787                                            &(name[0]));
   9788                 if (BCM_E_NONE != result) {
   9789                     /* should never see other error codes */
   9790                     cli_out("unexpected error trying to overwrite type %d"
   9791                             ": %d (%s)\n",
   9792                             res,
   9793                             result,
   9794                             _SHR_ERRMSG(result));
   9795                 }
   9796             }
   9797             if (BCM_E_NONE == result) {
   9798                 cli_out("destroy types\n");
   9799             }
   9800             for (res = 0;
   9801                  (BCM_E_NONE == result) &&
   9802                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9803                  res++) {
   9804                 result = shr_mres_type_unset(localRes, res);
   9805                 if (BCM_E_NONE != result) {
   9806                     /* should never see other error codes */
   9807                     cli_out("unexpected error trying to destroy type %d"
   9808                             ": %d (%s)\n",
   9809                             res,
   9810                             result,
   9811                             _SHR_ERRMSG(result));
   9812                 }
   9813             }
   9814             if (BCM_E_NONE == result) {
   9815                 cli_out("overwrite pools\n");
   9816             }
   9817             for (index = 0;
   9818                  (BCM_E_NONE == result) && (index < SHR_RES_ALLOCATOR_COUNT);
   9819                  index++) {
   9820                 switch (index) {
   9821                 case SHR_RES_ALLOCATOR_BITMAP:
   9822                     extraPtr = NULL;
   9823                     break;
   9824                 case SHR_RES_ALLOCATOR_TAGGED_BITMAP:
   9825                     extraPtr = &tagBitmapExtras;
   9826                     tagBitmapExtras.grain_size = 4;
   9827                     tagBitmapExtras.tag_length = 1;
   9828                     break;
   9829                 case SHR_RES_ALLOCATOR_IDXRES:
   9830                     extraPtr = &idxresExtras;
   9831                     idxresExtras.scaling_factor = 1;
   9832                     break;
   9833                 case SHR_RES_ALLOCATOR_AIDXRES:
   9834                     extraPtr = &aidxresExtras;
   9835                     aidxresExtras.blocking_factor = 7;
   9836                     break;
   9837                 case SHR_RES_ALLOCATOR_MDB:
   9838                     extraPtr = &mdbExtras;
   9839                     mdbExtras.bank_size = 1024;
   9840                     mdbExtras.free_lists = 10;
   9841                     mdbExtras.free_counts[0] = 2;
   9842                     mdbExtras.free_counts[1] = 4;
   9843                     mdbExtras.free_counts[2] = 8;
   9844                     mdbExtras.free_counts[3] = 16;
   9845                     mdbExtras.free_counts[4] = 32;
   9846                     mdbExtras.free_counts[5] = 64;
   9847                     mdbExtras.free_counts[6] = 128;
   9848                     mdbExtras.free_counts[7] = 256;
   9849                     mdbExtras.free_counts[8] = 512;
   9850                     mdbExtras.free_counts[9] = 1024;
   9851                     break;
   9852                 default:
   9853                     extraPtr = NULL;
   9854                 } /* switch(index) */
   9855                 sal_snprintf(&(name[0]),
   9856                              sizeof(name) - 1,
   9857                              "test: pool %d",
   9858                              index);
   9859                 result = shr_mres_pool_set(localRes,
   9860                                            index /* as pool ID */,
   9861                                            index /* as manager type */,
   9862                                            1024 /* low ID */,
   9863                                            6144 /* count */,
   9864                                            extraPtr,
   9865                                            &(name[0]));
   9866                 if (BCM_E_NONE != result) {
   9867                     cli_out("unexpected error overwriting %p pool %d: %d (%s)\n",
   9868                             (void*)localRes,
   9869                             index,
   9870                             result,
   9871                             _SHR_ERRMSG(result));
   9872                 }
   9873             }
   9874             if (BCM_E_NONE == result) {
   9875                 cli_out("destroy pools\n");
   9876             }
   9877             for (index = 0;
   9878                  (BCM_E_NONE == result) && (index < SHR_RES_ALLOCATOR_COUNT);
   9879                  index++) {
   9880                 result = shr_mres_pool_unset(localRes, index);
   9881                 if (BCM_E_NONE != result) {
   9882                     /* should never see other error codes */
   9883                     cli_out("unexpected error trying to destroy pool %d"
   9884                             ": %d (%s)\n",
   9885                             index,
   9886                             result,
   9887                             _SHR_ERRMSG(result));
   9888                 }
   9889             }
   9890             if (BCM_E_NONE == result) {
   9891                 cli_out("recreate pools\n");
   9892             }
   9893             for (index = 0;
   9894                  (BCM_E_NONE == result) && (index < SHR_RES_ALLOCATOR_COUNT);
   9895                  index++) {
   9896                 switch (index) {
   9897                 case SHR_RES_ALLOCATOR_BITMAP:
   9898                     extraPtr = NULL;
   9899                     break;
   9900                 case SHR_RES_ALLOCATOR_TAGGED_BITMAP:
   9901                     extraPtr = &tagBitmapExtras;
   9902                     tagBitmapExtras.grain_size = 4;
   9903                     tagBitmapExtras.tag_length = 1;
   9904                     break;
   9905                 case SHR_RES_ALLOCATOR_IDXRES:
   9906                     extraPtr = &idxresExtras;
   9907                     idxresExtras.scaling_factor = 1;
   9908                     break;
   9909                 case SHR_RES_ALLOCATOR_AIDXRES:
   9910                     extraPtr = &aidxresExtras;
   9911                     aidxresExtras.blocking_factor = 7;
   9912                     break;
   9913                 case SHR_RES_ALLOCATOR_MDB:
   9914                     extraPtr = &mdbExtras;
   9915                     mdbExtras.bank_size = 1024;
   9916                     mdbExtras.free_lists = 10;
   9917                     mdbExtras.free_counts[0] = 2;
   9918                     mdbExtras.free_counts[1] = 4;
   9919                     mdbExtras.free_counts[2] = 8;
   9920                     mdbExtras.free_counts[3] = 16;
   9921                     mdbExtras.free_counts[4] = 32;
   9922                     mdbExtras.free_counts[5] = 64;
   9923                     mdbExtras.free_counts[6] = 128;
   9924                     mdbExtras.free_counts[7] = 256;
   9925                     mdbExtras.free_counts[8] = 512;
   9926                     mdbExtras.free_counts[9] = 1024;
   9927                     break;
   9928                 default:
   9929                     extraPtr = NULL;
   9930                 } /* switch(index) */
   9931                 sal_snprintf(&(name[0]),
   9932                              sizeof(name) - 1,
   9933                              "test: pool %d",
   9934                              index);
   9935                 result = shr_mres_pool_set(localRes,
   9936                                            index /* as pool ID */,
   9937                                            index /* as manager type */,
   9938                                            1024 /* low ID */,
   9939                                            6144 /* count */,
   9940                                            extraPtr,
   9941                                            &(name[0]));
   9942                 if (BCM_E_NONE != result) {
   9943                     cli_out("unexpected error creating %p pool %d: %d (%s)\n",
   9944                             (void*)localRes,
   9945                             index,
   9946                             result,
   9947                             _SHR_ERRMSG(result));
   9948                 }
   9949             }
   9950             if (BCM_E_NONE == result) {
   9951                 cli_out("recreate types\n");
   9952             }
   9953             for (res = 0;
   9954                  (BCM_E_NONE == result) &&
   9955                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9956                  res++) {
   9957                 sal_snprintf(&(name[0]),
   9958                              sizeof(name) - 1,
   9959                              "test: type %d",
   9960                              res);
   9961                 result = shr_mres_type_set(localRes,
   9962                                            res /* as type ID */,
   9963                                            res % SHR_RES_ALLOCATOR_COUNT,
   9964                                            1 /* element size */,
   9965                                            &(name[0]));
   9966                 if (BCM_E_NONE != result) {
   9967                     /* should never see other error codes */
   9968                     cli_out("unexpected error creating type %d: %d (%s)\n",
   9969                             res,
   9970                             result,
   9971                             _SHR_ERRMSG(result));
   9972                 }
   9973             }
   9974         } else { /* if (localRes) */
   9975             cli_out("no resources for testing; use 'ResTest Create' first.\n");
   9976         } /* if (localRes) */
   9977     } else if (!sal_strncasecmp(c, "t9", resTestMax(sal_strlen(c), 2))) {
   9978         if (localRes) {
   9979             /* for types that support WITH_ID and REPLACE, alloc a block */
   9980             for (res = 0;
   9981                  (BCM_E_NONE == result) &&
   9982                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
   9983                  res++) {
   9984                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
   9985                 if (BCM_E_NONE == result) {
   9986                     result = shr_mres_pool_get(localRes, pool, &restype, NULL, NULL, NULL, NULL);
   9987                 }
   9988                 if (BCM_E_NONE == result) {
   9989                     skip[res] = FALSE;
   9990                     if (res < SHR_RES_ALLOCATOR_COUNT) {
   9991                         size[res][0] = 0x0009;
   9992                         base[res][0] = 0x050C;
   9993                     } else {
   9994                         size[res][0] = 0x0008;
   9995                         base[res][0] = 0x0608;
   9996                     }
   9997                     if ((SHR_RES_ALLOCATOR_TAGGED_BITMAP == restype)) {
   9998                         
   9999                         tag[res][0][0] = 0x12;
  10000                         tag[res][0][1] = 0x34;
  10001                     } else {
  10002                         tag[res][0][0] = 0;
  10003                         tag[res][0][1] = 0;
  10004                     }
  10005                     
  10006                     if ((SHR_RES_ALLOCATOR_IDXRES == restype) ||
  10007                         (SHR_RES_ALLOCATOR_AIDXRES == restype)) {
  10008                         skip[res] = TRUE;
  10009                     }
  10010                 } else {
  10011                     skip[res] = TRUE;
  10012                 }
  10013                 if ((BCM_E_NONE == result) && (!skip[res])) {
  10014                     if (tag[res][0][0]) {
  10015                         result = shr_mres_alloc_tag(localRes,
  10016                                                     res,
  10017                                                     SHR_RES_ALLOC_WITH_ID,
  10018                                                     &(tag[res][0][0]),
  10019                                                     size[res][0],
  10020                                                     &(base[res][0]));
  10021                     } else {
  10022                         result = shr_mres_alloc(localRes,
  10023                                                 res,
  10024                                                 SHR_RES_ALLOC_WITH_ID,
  10025                                                 size[res][0],
  10026                                                 &(base[res][0]));
  10027                     }
  10028                     if (BCM_E_NONE != result) {
  10029                         cli_out("unable to allocate %p type %d base %d size %d:"
  10030                                 " %d (%s)\n",
  10031                                 (void*)localRes,
  10032                                 res,
  10033                                 base[res][0],
  10034                                 size[res][0],
  10035                                 result,
  10036                                 _SHR_ERRMSG(result));
  10037                     }
  10038                 }
  10039             }
  10040             /* replace the block directly */
  10041             for (res = 0;
  10042                  (BCM_E_NONE == result) &&
  10043                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10044                  res++) {
  10045                 if (!skip[res]) {
  10046                     if (tag[res][0][0]) {
  10047                         result = shr_mres_alloc_tag(localRes,
  10048                                                     res,
  10049                                                     SHR_RES_ALLOC_WITH_ID |
  10050                                                     SHR_RES_ALLOC_REPLACE,
  10051                                                     &(tag[res][0][0]),
  10052                                                     size[res][0],
  10053                                                     &(base[res][0]));
  10054                     } else {
  10055                         result = shr_mres_alloc(localRes,
  10056                                                 res,
  10057                                                 SHR_RES_ALLOC_WITH_ID |
  10058                                                 SHR_RES_ALLOC_REPLACE,
  10059                                                 size[res][0],
  10060                                                 &(base[res][0]));
  10061                     }
  10062                     if (BCM_E_NONE != result) {
  10063                         cli_out("unable to allocate %p type %d base %d size %d"
  10064                                 " tag %02X%02X: %d (%s)\n",
  10065                                 (void*)localRes,
  10066                                 res,
  10067                                 base[res][0],
  10068                                 size[res][0],
  10069                                 tag[res][0][0],
  10070                                 tag[res][0][1],
  10071                                 result,
  10072                                 _SHR_ERRMSG(result));
  10073                     }
  10074                 } /* if (!skip[res]) */
  10075             } /* for (all types as long as no error) */
  10076             /* try to misalign the replacement - low */
  10077             for (res = 0;
  10078                  (BCM_E_NONE == result) &&
  10079                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10080                  res++) {
  10081                 if (!skip[res]) {
  10082                     size[res][1] = size[res][0];
  10083                     base[res][1] = base[res][0] - 1;
  10084                     tag[res][1][0] = tag[res][0][0];
  10085                     tag[res][1][1] = tag[res][0][1];
  10086                     if (tag[res][0][0]) {
  10087                         result = shr_mres_alloc_tag(localRes,
  10088                                                     res,
  10089                                                     SHR_RES_ALLOC_WITH_ID |
  10090                                                     SHR_RES_ALLOC_REPLACE,
  10091                                                     &(tag[res][1][0]),
  10092                                                     size[res][1],
  10093                                                     &(base[res][1]));
  10094                     } else {
  10095                         result = shr_mres_alloc(localRes,
  10096                                                 res,
  10097                                                 SHR_RES_ALLOC_WITH_ID |
  10098                                                 SHR_RES_ALLOC_REPLACE,
  10099                                                 size[res][1],
  10100                                                 &(base[res][1]));
  10101                     }
  10102                     if (BCM_E_RESOURCE == result) {
  10103                         /* mixed blocks should yield BCM_E_RESOURCE */
  10104                         result = BCM_E_NONE;
  10105                     } else {
  10106                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10107                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10108                                 (void*)localRes,
  10109                                 res,
  10110                                 base[res][0],
  10111                                 size[res][0],
  10112                                 tag[res][0][0],
  10113                                 tag[res][0][1],
  10114                                 base[res][1],
  10115                                 size[res][1],
  10116                                 tag[res][1][0],
  10117                                 tag[res][1][1],
  10118                                 result,
  10119                                 _SHR_ERRMSG(result));
  10120                         result = BCM_E_FAIL;
  10121                     }
  10122                 } /* if (!skip[res]) */
  10123             } /* for (all types as long as no error) */
  10124             /* try to misalign the replacement - high */
  10125             for (res = 0;
  10126                  (BCM_E_NONE == result) &&
  10127                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10128                  res++) {
  10129                 if (!skip[res]) {
  10130                     size[res][1] = size[res][0];
  10131                     base[res][1] = base[res][0] + 1;
  10132                     tag[res][1][0] = tag[res][0][0];
  10133                     tag[res][1][1] = tag[res][0][1];
  10134                     if (tag[res][0][0]) {
  10135                         result = shr_mres_alloc_tag(localRes,
  10136                                                     res,
  10137                                                     SHR_RES_ALLOC_WITH_ID |
  10138                                                     SHR_RES_ALLOC_REPLACE,
  10139                                                     &(tag[res][1][0]),
  10140                                                     size[res][1],
  10141                                                     &(base[res][1]));
  10142                     } else {
  10143                         result = shr_mres_alloc(localRes,
  10144                                                 res,
  10145                                                 SHR_RES_ALLOC_WITH_ID |
  10146                                                 SHR_RES_ALLOC_REPLACE,
  10147                                                 size[res][1],
  10148                                                 &(base[res][1]));
  10149                     }
  10150                     if (BCM_E_RESOURCE == result) {
  10151                         /* mixed blocks should yield BCM_E_RESOURCE */
  10152                         result = BCM_E_NONE;
  10153                     } else {
  10154                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10155                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10156                                 (void*)localRes,
  10157                                 res,
  10158                                 base[res][0],
  10159                                 size[res][0],
  10160                                 tag[res][0][0],
  10161                                 tag[res][0][1],
  10162                                 base[res][1],
  10163                                 size[res][1],
  10164                                 tag[res][1][0],
  10165                                 tag[res][1][1],
  10166                                 result,
  10167                                 _SHR_ERRMSG(result));
  10168                         result = BCM_E_FAIL;
  10169                     }
  10170                 } /* if (!skip[res]) */
  10171             } /* for (all types as long as no error) */
  10172             /* try to add one element - low */
  10173             for (res = 0;
  10174                  (BCM_E_NONE == result) &&
  10175                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10176                  res++) {
  10177                 if (!skip[res]) {
  10178                     size[res][1] = size[res][0] + 1;
  10179                     base[res][1] = base[res][0] - 1;
  10180                     tag[res][1][0] = tag[res][0][0];
  10181                     tag[res][1][1] = tag[res][0][1];
  10182                     if (tag[res][0][0]) {
  10183                         result = shr_mres_alloc_tag(localRes,
  10184                                                     res,
  10185                                                     SHR_RES_ALLOC_WITH_ID |
  10186                                                     SHR_RES_ALLOC_REPLACE,
  10187                                                     &(tag[res][1][0]),
  10188                                                     size[res][1],
  10189                                                     &(base[res][1]));
  10190                     } else {
  10191                         result = shr_mres_alloc(localRes,
  10192                                                 res,
  10193                                                 SHR_RES_ALLOC_WITH_ID |
  10194                                                 SHR_RES_ALLOC_REPLACE,
  10195                                                 size[res][1],
  10196                                                 &(base[res][1]));
  10197                     }
  10198                     if (BCM_E_RESOURCE == result) {
  10199                         /* mixed blocks should yield BCM_E_RESOURCE */
  10200                         result = BCM_E_NONE;
  10201                     } else {
  10202                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10203                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10204                                 (void*)localRes,
  10205                                 res,
  10206                                 base[res][0],
  10207                                 size[res][0],
  10208                                 tag[res][0][0],
  10209                                 tag[res][0][1],
  10210                                 base[res][1],
  10211                                 size[res][1],
  10212                                 tag[res][1][0],
  10213                                 tag[res][1][1],
  10214                                 result,
  10215                                 _SHR_ERRMSG(result));
  10216                         result = BCM_E_FAIL;
  10217                     }
  10218                 } /* if (!skip[res]) */
  10219             } /* for (all types as long as no error) */
  10220             /* try to add one element - high */
  10221             for (res = 0;
  10222                  (BCM_E_NONE == result) &&
  10223                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10224                  res++) {
  10225                 if (!skip[res]) {
  10226                     size[res][1] = size[res][0] + 1;
  10227                     base[res][1] = base[res][0];
  10228                     tag[res][1][0] = tag[res][0][0];
  10229                     tag[res][1][1] = tag[res][0][1];
  10230                     if (tag[res][0][0]) {
  10231                         result = shr_mres_alloc_tag(localRes,
  10232                                                     res,
  10233                                                     SHR_RES_ALLOC_WITH_ID |
  10234                                                     SHR_RES_ALLOC_REPLACE,
  10235                                                     &(tag[res][1][0]),
  10236                                                     size[res][1],
  10237                                                     &(base[res][1]));
  10238                     } else {
  10239                         result = shr_mres_alloc(localRes,
  10240                                                 res,
  10241                                                 SHR_RES_ALLOC_WITH_ID |
  10242                                                 SHR_RES_ALLOC_REPLACE,
  10243                                                 size[res][1],
  10244                                                 &(base[res][1]));
  10245                     }
  10246                     if (BCM_E_RESOURCE == result) {
  10247                         /* mixed blocks should yield BCM_E_RESOURCE */
  10248                         result = BCM_E_NONE;
  10249                     } else {
  10250                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10251                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10252                                 (void*)localRes,
  10253                                 res,
  10254                                 base[res][0],
  10255                                 size[res][0],
  10256                                 tag[res][0][0],
  10257                                 tag[res][0][1],
  10258                                 base[res][1],
  10259                                 size[res][1],
  10260                                 tag[res][1][0],
  10261                                 tag[res][1][1],
  10262                                 result,
  10263                                 _SHR_ERRMSG(result));
  10264                         result = BCM_E_FAIL;
  10265                     }
  10266                 } /* if (!skip[res]) */
  10267             } /* for (all types as long as no error) */
  10268             /* try to add one element - both low and high */
  10269             for (res = 0;
  10270                  (BCM_E_NONE == result) &&
  10271                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10272                  res++) {
  10273                 if (!skip[res]) {
  10274                     size[res][1] = size[res][0] + 2;
  10275                     base[res][1] = base[res][0] - 1;
  10276                     tag[res][1][0] = tag[res][0][0];
  10277                     tag[res][1][1] = tag[res][0][1];
  10278                     if (tag[res][0][0]) {
  10279                         result = shr_mres_alloc_tag(localRes,
  10280                                                     res,
  10281                                                     SHR_RES_ALLOC_WITH_ID |
  10282                                                     SHR_RES_ALLOC_REPLACE,
  10283                                                     &(tag[res][1][0]),
  10284                                                     size[res][1],
  10285                                                     &(base[res][1]));
  10286                     } else {
  10287                         result = shr_mres_alloc(localRes,
  10288                                                 res,
  10289                                                 SHR_RES_ALLOC_WITH_ID |
  10290                                                 SHR_RES_ALLOC_REPLACE,
  10291                                                 size[res][1],
  10292                                                 &(base[res][1]));
  10293                     }
  10294                     if (BCM_E_RESOURCE == result) {
  10295                         /* mixed blocks should yield BCM_E_RESOURCE */
  10296                         result = BCM_E_NONE;
  10297                     } else {
  10298                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10299                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10300                                 (void*)localRes,
  10301                                 res,
  10302                                 base[res][0],
  10303                                 size[res][0],
  10304                                 tag[res][0][0],
  10305                                 tag[res][0][1],
  10306                                 base[res][1],
  10307                                 size[res][1],
  10308                                 tag[res][1][0],
  10309                                 tag[res][1][1],
  10310                                 result,
  10311                                 _SHR_ERRMSG(result));
  10312                         result = BCM_E_FAIL;
  10313                     }
  10314                 } /* if (!skip[res]) */
  10315             } /* for (all types as long as no error) */
  10316             /* alignment good but try to change the tag */
  10317             for (res = 0;
  10318                  (BCM_E_NONE == result) &&
  10319                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10320                  res++) {
  10321                 if ((!skip[res]) && (tag[res][0][0])) {
  10322                     size[res][1] = size[res][0] + 2;
  10323                     base[res][1] = base[res][0] - 1;
  10324                     tag[res][1][0] = tag[res][0][0] + 1;
  10325                     tag[res][1][1] = tag[res][0][1] + 1;
  10326                     result = shr_mres_alloc_tag(localRes,
  10327                                                 res,
  10328                                                 SHR_RES_ALLOC_WITH_ID |
  10329                                                 SHR_RES_ALLOC_REPLACE,
  10330                                                 &(tag[res][1][0]),
  10331                                                 size[res][1],
  10332                                                 &(base[res][1]));
  10333                     if (BCM_E_RESOURCE == result) {
  10334                         /* mixed blocks should yield BCM_E_RESOURCE */
  10335                         result = BCM_E_NONE;
  10336                     } else {
  10337                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10338                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10339                                 (void*)localRes,
  10340                                 res,
  10341                                 base[res][0],
  10342                                 size[res][0],
  10343                                 tag[res][0][0],
  10344                                 tag[res][0][1],
  10345                                 base[res][1],
  10346                                 size[res][1],
  10347                                 tag[res][1][0],
  10348                                 tag[res][1][1],
  10349                                 result,
  10350                                 _SHR_ERRMSG(result));
  10351                         result = BCM_E_FAIL;
  10352                     }
  10353                 } /* if (!skip[res]) */
  10354             } /* for (all types as long as no error) */
  10355             /* try to subtract one element - low */
  10356             for (res = 0;
  10357                  (BCM_E_NONE == result) &&
  10358                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10359                  res++) {
  10360                 if (!skip[res]) {
  10361                     size[res][1] = size[res][0] - 1;
  10362                     base[res][1] = base[res][0] + 1;
  10363                     tag[res][1][0] = tag[res][0][0];
  10364                     tag[res][1][1] = tag[res][0][1];
  10365                     if (tag[res][0][0]) {
  10366                         result = shr_mres_alloc_tag(localRes,
  10367                                                     res,
  10368                                                     SHR_RES_ALLOC_WITH_ID |
  10369                                                     SHR_RES_ALLOC_REPLACE,
  10370                                                     &(tag[res][1][0]),
  10371                                                     size[res][1],
  10372                                                     &(base[res][1]));
  10373                     } else {
  10374                         result = shr_mres_alloc(localRes,
  10375                                                 res,
  10376                                                 SHR_RES_ALLOC_WITH_ID |
  10377                                                 SHR_RES_ALLOC_REPLACE,
  10378                                                 size[res][1],
  10379                                                 &(base[res][1]));
  10380                     }
  10381                     if (BCM_E_RESOURCE == result) {
  10382                         /* mixed blocks should yield BCM_E_RESOURCE */
  10383                         result = BCM_E_NONE;
  10384                     } else {
  10385                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10386                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10387                                 (void*)localRes,
  10388                                 res,
  10389                                 base[res][0],
  10390                                 size[res][0],
  10391                                 tag[res][0][0],
  10392                                 tag[res][0][1],
  10393                                 base[res][1],
  10394                                 size[res][1],
  10395                                 tag[res][1][0],
  10396                                 tag[res][1][1],
  10397                                 result,
  10398                                 _SHR_ERRMSG(result));
  10399                         result = BCM_E_FAIL;
  10400                         /*
  10401                          *  Unhappily the bitmap allocators don't detect this
  10402                          *  condition and so do not return the error.  This is
  10403                          *  a limitation of these allocators, since they do not
  10404                          *  keep track of specific groupings, and so we will
  10405                          *  explicitly allow this to pass the tests, but it
  10406                          *  still prints the msssage above.
  10407                          */
  10408                         result = shr_mres_type_get(localRes,
  10409                                                    res,
  10410                                                    &pool,
  10411                                                    NULL,
  10412                                                    NULL);
  10413                         if (BCM_E_NONE == result) {
  10414                             result = shr_mres_pool_get(localRes,
  10415                                                        pool,
  10416                                                        &restype,
  10417                                                        NULL,
  10418                                                        NULL,
  10419                                                        NULL,
  10420                                                        NULL);
  10421                         }
  10422                         if ((BCM_E_NONE == result) &&
  10423                             ((SHR_RES_ALLOCATOR_BITMAP == restype) ||
  10424                              (SHR_RES_ALLOCATOR_TAGGED_BITMAP == restype))) {
  10425                             cli_out("NOTE: bitmap allocators are not able to"
  10426                                     " detect this condition and so it must be"
  10427                                     " enforced by software discipline\n");
  10428                             result = BCM_E_NONE;
  10429                         } else {
  10430                             result = BCM_E_FAIL;
  10431                         }
  10432                     }
  10433                 } /* if (!skip[res]) */
  10434             } /* for (all types as long as no error) */
  10435             /* try to subtract one element - high */
  10436             for (res = 0;
  10437                  (BCM_E_NONE == result) &&
  10438                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10439                  res++) {
  10440                 if (!skip[res]) {
  10441                     size[res][1] = size[res][0] - 1;
  10442                     base[res][1] = base[res][0];
  10443                     tag[res][1][0] = tag[res][0][0];
  10444                     tag[res][1][1] = tag[res][0][1];
  10445                     if (tag[res][0][0]) {
  10446                         result = shr_mres_alloc_tag(localRes,
  10447                                                     res,
  10448                                                     SHR_RES_ALLOC_WITH_ID |
  10449                                                     SHR_RES_ALLOC_REPLACE,
  10450                                                     &(tag[res][1][0]),
  10451                                                     size[res][1],
  10452                                                     &(base[res][1]));
  10453                     } else {
  10454                         result = shr_mres_alloc(localRes,
  10455                                                 res,
  10456                                                 SHR_RES_ALLOC_WITH_ID |
  10457                                                 SHR_RES_ALLOC_REPLACE,
  10458                                                 size[res][1],
  10459                                                 &(base[res][1]));
  10460                     }
  10461                     if (BCM_E_RESOURCE == result) {
  10462                         /* mixed blocks should yield BCM_E_RESOURCE */
  10463                         result = BCM_E_NONE;
  10464                     } else {
  10465                         cli_out("%p type %d base %d size %d tag %02X%02X ->"
  10466                                 " base %d size %d tag %02X%02X: %d (%s)\n",
  10467                                 (void*)localRes,
  10468                                 res,
  10469                                 base[res][0],
  10470                                 size[res][0],
  10471                                 tag[res][0][0],
  10472                                 tag[res][0][1],
  10473                                 base[res][1],
  10474                                 size[res][1],
  10475                                 tag[res][1][0],
  10476                                 tag[res][1][1],
  10477                                 result,
  10478                                 _SHR_ERRMSG(result));
  10479                         result = BCM_E_FAIL;
  10480                         /*
  10481                          *  Unhappily the bitmap allocators don't detect this
  10482                          *  condition and so do not return the error.  This is
  10483                          *  a limitation of these allocators, since they do not
  10484                          *  keep track of specific groupings, and so we will
  10485                          *  explicitly allow this to pass the tests, but it
  10486                          *  still prints the msssage above.
  10487                          */
  10488                         result = shr_mres_type_get(localRes,
  10489                                                    res,
  10490                                                    &pool,
  10491                                                    NULL,
  10492                                                    NULL);
  10493                         if (BCM_E_NONE == result) {
  10494                             result = shr_mres_pool_get(localRes,
  10495                                                        pool,
  10496                                                        &restype,
  10497                                                        NULL,
  10498                                                        NULL,
  10499                                                        NULL,
  10500                                                        NULL);
  10501                         }
  10502                         if ((BCM_E_NONE == result) &&
  10503                             ((SHR_RES_ALLOCATOR_BITMAP == restype) ||
  10504                              (SHR_RES_ALLOCATOR_TAGGED_BITMAP == restype))) {
  10505                             cli_out("NOTE: bitmap allocators are not able to"
  10506                                     " detect this condition and so it must be"
  10507                                     " enforced by software discipline\n");
  10508                             result = BCM_E_NONE;
  10509                         } else {
  10510                             result = BCM_E_FAIL;
  10511                         }
  10512                     }
  10513                 } /* if (!skip[res]) */
  10514             } /* for (all types as long as no error) */
  10515             /* that's enough; free the blocks */
  10516             for (res = 0;
  10517                  (BCM_E_NONE == result) &&
  10518                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10519                  res++) {
  10520                 if (!skip[res]) {
  10521                     result = shr_mres_free(localRes,
  10522                                            res,
  10523                                            size[res][0],
  10524                                            base[res][0]);
  10525                     if (BCM_E_NONE != result) {
  10526                         cli_out("unable to free %p type %d base %d size %d"
  10527                                 " tag %02X%02X: %d (%s)\n",
  10528                                 (void*)localRes,
  10529                                 res,
  10530                                 base[res][0],
  10531                                 size[res][0],
  10532                                 tag[res][0][0],
  10533                                 tag[res][0][1],
  10534                                 result,
  10535                                 _SHR_ERRMSG(result));
  10536                     }
  10537                 } /* if (!skip[res]) */
  10538             } /* for (all types as long as no error) */
  10539         } else { /* if (localRes) */
  10540             cli_out("no resources for testing; use 'ResTest Create' first.\n");
  10541         } /* if (localRes) */
  10542     } else if (!sal_strncasecmp(c, "ta", resTestMax(sal_strlen(c), 2))) {
  10543         if (localRes) {
  10544             /* for types that support sparse allocation */
  10545             for (res = 0;
  10546                  (BCM_E_NONE == result) &&
  10547                  (res < (SHR_RES_ALLOCATOR_COUNT << 1));
  10548                  res++) {
  10549                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
  10550                 if (BCM_E_NONE == result) {
  10551                     result = shr_mres_pool_get(localRes, pool, &restype, &(size[res][0]), &(size[res][1]), NULL, NULL);
  10552                 }
  10553                 if (BCM_E_NONE == result) {
  10554                     
  10555                     if (res == SHR_RES_ALLOCATOR_BITMAP) {
  10556                         skip[res] = FALSE;
  10557                     } else {
  10558                         skip[res] = TRUE;
  10559                     }
  10560                 } else {
  10561                     skip[res] = TRUE;
  10562                 }
  10563                 if (skip[res]) {
  10564                     continue;
  10565                 }
  10566                 
  10567                 for (length = 4;
  10568                      (BCM_E_NONE == result) && (length < 10);
  10569                      length++) {
  10570                     switch (length) {
  10571                     case 4:
  10572                         pattern =   0xD; /* 1101 */
  10573                         break;
  10574                     case 5:
  10575                         pattern =  0x1D; /* 11101 */
  10576                         break;
  10577                     case 6:
  10578                         pattern =  0x39; /* 111001 */
  10579                         break;
  10580                     case 7:
  10581                         pattern =  0x5B; /* 1011011 */
  10582                         break;
  10583                     case 8:
  10584                         pattern =  0xBB; /* 10111011 */
  10585                         break;
  10586                     case 9:
  10587                         pattern = 0x1DB; /* 111011011 */
  10588                         break;
  10589                     case 10:
  10590                         pattern = 0x3BB; /* 1110111011 */
  10591                         break;
  10592                     default:
  10593                         pattern = 0;
  10594                     }
  10595                     for (repeats = 1;
  10596                          (BCM_E_NONE == result) && (repeats < 7);
  10597                          repeats++) {
  10598                         cli_out("testing %p resource %d with pattern %08X"
  10599                                 " length %d repeast %d\n",
  10600                                 (void*)localRes,
  10601                                 res,
  10602                                 pattern,
  10603                                 length,
  10604                                 repeats);
  10605                         /* allocate a bunch of blocks, aligned */
  10606                         for (index = 0;
  10607                              (BCM_E_NONE == result) && (index < TEST_BLOCKS);
  10608                              index++) {
  10609                             result = shr_mres_alloc_align_sparse(localRes,
  10610                                                                  res,
  10611                                                                  0 /* flags */,
  10612                                                                  length * repeats,
  10613                                                                  0 /* offset */,
  10614                                                                  pattern,
  10615                                                                  length,
  10616                                                                  repeats,
  10617                                                                  &(base[res][index]));
  10618                             if (BCM_E_NONE != result) {
  10619                                 cli_out("alloc_align_sparse(%p,%d,%08X,%d,%d,"
  10620                                         "%08X,%d,%d,%p) failed: %d (%s)\n",
  10621                                         (void*)localRes,
  10622                                         res,
  10623                                         0,
  10624                                         length * repeats,
  10625                                         0,
  10626                                         pattern,
  10627                                         length,
  10628                                         repeats,
  10629                                         (void*)(&(base[res][index])),
  10630                                         result,
  10631                                         _SHR_ERRMSG(result));
  10632                             }
  10633                         } /* for (all test blocks) */
  10634                         /* scan the blocks */
  10635                         for (index = 0;
  10636                              (BCM_E_NONE == result) && (index < TEST_BLOCKS);
  10637                              index++) {
  10638                             for (repeat = 0, elem = base[res][index];
  10639                                  repeat < repeats;
  10640                                  repeat++) {
  10641                                 for (offset = 0;
  10642                                      offset < length;
  10643                                      offset++, elem++) {
  10644                                     xresult = shr_mres_check(localRes,
  10645                                                              res,
  10646                                                              1,
  10647                                                              elem);
  10648                                     if (pattern & (1 << offset)) {
  10649                                         /* element should be allocated */
  10650                                         if (BCM_E_NOT_FOUND == xresult) {
  10651                                             cli_out("base %d pattern %08X length"
  10652                                                     " %d repeats %d implies"
  10653                                                     " element %d should be"
  10654                                                     " allocated but it is"
  10655                                                     " not\n",
  10656                                                     base[res][index],
  10657                                                     pattern,
  10658                                                     length,
  10659                                                     repeats,
  10660                                                     elem);
  10661                                             result = BCM_E_FAIL;
  10662                                         } else if (BCM_E_EXISTS != xresult) {
  10663                                             cli_out("unexpected result %d (%s)"
  10664                                                     " reading base %d pattern"
  10665                                                     " %08X length %d repeats"
  10666                                                     " %d at %d\n",
  10667                                                     xresult,
  10668                                                     _SHR_ERRMSG(xresult),
  10669                                                     base[res][index],
  10670                                                     pattern,
  10671                                                     length,
  10672                                                     repeats,
  10673                                                     elem);
  10674                                             result = BCM_E_FAIL;
  10675                                         }
  10676                                     } else { /* if (pattern & (1 << offset)) */
  10677                                         /* element should not be allocated */
  10678                                         if (BCM_E_EXISTS == xresult) {
  10679                                             cli_out("base %d pattern %08X length"
  10680                                                     " %d repeats %d implies"
  10681                                                     " element %d should not be"
  10682                                                     " allocated but it is\n",
  10683                                                     base[res][index],
  10684                                                     pattern,
  10685                                                     length,
  10686                                                     repeats,
  10687                                                     elem);
  10688                                             result = BCM_E_FAIL;
  10689                                         } else if (BCM_E_NOT_FOUND != xresult) {
  10690                                             cli_out("unexpected result %d (%s)"
  10691                                                     " reading base %d pattern"
  10692                                                     " %08X length %d repeats"
  10693                                                     " %d at %d\n",
  10694                                                     xresult,
  10695                                                     _SHR_ERRMSG(xresult),
  10696                                                     base[res][index],
  10697                                                     pattern,
  10698                                                     length,
  10699                                                     repeats,
  10700                                                     elem);
  10701                                             result = BCM_E_FAIL;
  10702                                         }
  10703                                     } /* if (pattern & (1 << offset)) */
  10704                                 } /* for (all elements in this repeat) */
  10705                             } /* for (all repeats in a block) */
  10706                         } /* for (all test blocks) */
  10707                         for (index = 0;
  10708                              (BCM_E_NONE == result) && (index < TEST_BLOCKS);
  10709                              index++) {
  10710                             result = shr_mres_free_sparse(localRes,
  10711                                                           res,
  10712                                                           pattern,
  10713                                                           length,
  10714                                                           repeats,
  10715                                                           base[res][index]);
  10716                             if (BCM_E_NONE != result) {
  10717                                 cli_out("free_sparse(%p,%d,%08X,"
  10718                                         "%d,%d,%d) index %d/%d failed: %d (%s)\n",
  10719                                         (void*)localRes,
  10720                                         res,
  10721                                         pattern,
  10722                                         length,
  10723                                         repeats,
  10724                                         base[res][index],
  10725                                         index,
  10726                                         TEST_BLOCKS,
  10727                                         result,
  10728                                         _SHR_ERRMSG(result));
  10729                             }
  10730                         } /* for (all test blocks) */
  10731                         /* allocate a bunch of blocks, unaligned */
  10732                         for (index = 0;
  10733                              (BCM_E_NONE == result) && (index < TEST_BLOCKS);
  10734                              index++) {
  10735                             result = shr_mres_alloc_align_sparse(localRes,
  10736                                                                  res,
  10737                                                                  0 /* flags */,
  10738                                                                  1,
  10739                                                                  0 /* offset */,
  10740                                                                  pattern,
  10741                                                                  length,
  10742                                                                  repeats,
  10743                                                                  &(base[res][index]));
  10744                             if (BCM_E_NONE != result) {
  10745                                 cli_out("alloc_align_sparse(%p,%d,%08X,%d,%d,"
  10746                                         "%08X,%d,%d,%p) failed: %d (%s)\n",
  10747                                         (void*)localRes,
  10748                                         res,
  10749                                         0,
  10750                                         length * repeats,
  10751                                         0,
  10752                                         pattern,
  10753                                         length,
  10754                                         repeats,
  10755                                         (void*)(&(base[res][index])),
  10756                                         result,
  10757                                         _SHR_ERRMSG(result));
  10758                             }
  10759                         } /* for (all test blocks) */
  10760                         /* scan the blocks */
  10761                         for (index = 0;
  10762                              (BCM_E_NONE == result) && (index < TEST_BLOCKS);
  10763                              index++) {
  10764                             for (repeat = 0, elem = base[res][index];
  10765                                  repeat < repeats;
  10766                                  repeat++) {
  10767                                 for (offset = 0;
  10768                                      offset < length;
  10769                                      offset++, elem++) {
  10770                                     xresult = shr_mres_check(localRes,
  10771                                                              res,
  10772                                                              1,
  10773                                                              elem);
  10774                                     if (pattern & (1 << offset)) {
  10775                                         /* element should be allocated */
  10776                                         if (BCM_E_NOT_FOUND == xresult) {
  10777                                             cli_out("base %d pattern %08X length"
  10778                                                     " %d repeats %d implies"
  10779                                                     " element %d should be"
  10780                                                     " allocated but it is"
  10781                                                     " not\n",
  10782                                                     base[res][index],
  10783                                                     pattern,
  10784                                                     length,
  10785                                                     repeats,
  10786                                                     elem);
  10787                                             result = BCM_E_FAIL;
  10788                                         } else if (BCM_E_EXISTS != xresult) {
  10789                                             cli_out("unexpected result %d (%s)"
  10790                                                     " reading base %d pattern"
  10791                                                     " %08X length %d repeats"
  10792                                                     " %d at %d\n",
  10793                                                     xresult,
  10794                                                     _SHR_ERRMSG(xresult),
  10795                                                     base[res][index],
  10796                                                     pattern,
  10797                                                     length,
  10798                                                     repeats,
  10799                                                     elem);
  10800                                             result = BCM_E_FAIL;
  10801                                         }
  10802                                     } else { /* if (pattern & (1 << offset)) */
  10803                                         /* element should not be allocated */
  10804                                         if (BCM_E_EXISTS == xresult) {
  10805                                             cli_out("base %d pattern %08X length"
  10806                                                     " %d repeats %d implies"
  10807                                                     " element %d should not be"
  10808                                                     " allocated but it is\n",
  10809                                                     base[res][index],
  10810                                                     pattern,
  10811                                                     length,
  10812                                                     repeats,
  10813                                                     elem);
  10814                                             result = BCM_E_FAIL;
  10815                                         } else if (BCM_E_NOT_FOUND != xresult) {
  10816                                             cli_out("unexpected result %d (%s)"
  10817                                                     " reading base %d pattern"
  10818                                                     " %08X length %d repeats"
  10819                                                     " %d at %d\n",
  10820                                                     xresult,
  10821                                                     _SHR_ERRMSG(xresult),
  10822                                                     base[res][index],
  10823                                                     pattern,
  10824                                                     length,
  10825                                                     repeats,
  10826                                                     elem);
  10827                                             result = BCM_E_FAIL;
  10828                                         }
  10829                                     } /* if (pattern & (1 << offset)) */
  10830                                 } /* for (all elements in this repeat) */
  10831                             } /* for (all repeats in a block) */
  10832                         } /* for (all test blocks) */
  10833                         for (index = 0;
  10834                              (BCM_E_NONE == result) && (index < TEST_BLOCKS);
  10835                              index++) {
  10836                             result = shr_mres_free_sparse(localRes,
  10837                                                           res,
  10838                                                           pattern,
  10839                                                           length,
  10840                                                           repeats,
  10841                                                           base[res][index]);
  10842                             if (BCM_E_NONE != result) {
  10843                                 cli_out("free_sparse(%p,%d,%08X,"
  10844                                         "%d,%d,%d) index %d/%d failed: %d (%s)\n",
  10845                                         (void*)localRes,
  10846                                         res,
  10847                                         pattern,
  10848                                         length,
  10849                                         repeats,
  10850                                         base[res][index],
  10851                                         index,
  10852                                         TEST_BLOCKS,
  10853                                         result,
  10854                                         _SHR_ERRMSG(result));
  10855                             }
  10856                         } /* for (all test blocks) */
  10857                         if (BCM_E_NONE == result) {
  10858                             result = shr_mres_alloc_align_sparse(localRes,
  10859                                                                  res,
  10860                                                                  0 /* flags */,
  10861                                                                  1,
  10862                                                                  0 /* offset */,
  10863                                                                  pattern,
  10864                                                                  length,
  10865                                                                  repeats,
  10866                                                                  &(base[res][0]));
  10867 
  10868                             for (elem = size[res][0];
  10869                                  elem < base[res][0];
  10870                                  elem++) {
  10871                                 xresult = shr_mres_check(localRes,
  10872                                                          res,
  10873                                                          1,
  10874                                                          elem);
  10875                                 if (BCM_E_EXISTS == xresult) {
  10876                                     cli_out("unexpected allocated element in"
  10877                                             " %p %d element %d\n",
  10878                                             (void*)localRes,
  10879                                             res,
  10880                                             elem);
  10881                                     result = BCM_E_FAIL;
  10882                                 } else if (BCM_E_NOT_FOUND != xresult) {
  10883                                     cli_out("unexpected result checking %p %d"
  10884                                             " element %d: %d (%s)\n",
  10885                                             (void*)localRes,
  10886                                             res,
  10887                                             elem,
  10888                                             xresult,
  10889                                             _SHR_ERRMSG(xresult));
  10890                                     result = BCM_E_FAIL;
  10891                                 }
  10892                             } /* for (all elements before the block) */
  10893                             for (index = 0; index < repeats; index++) {
  10894                                 for (offset = 0;
  10895                                      offset < length;
  10896                                      offset++, elem++) {
  10897                                     xresult = shr_mres_check(localRes,
  10898                                                              res,
  10899                                                              1,
  10900                                                              elem);
  10901                                     if (pattern & (1 << offset)) {
  10902                                         /* element should be allocated */
  10903                                         if (BCM_E_NOT_FOUND == xresult) {
  10904                                             cli_out("base %d pattern %08X length"
  10905                                                     " %d repeats %d implies"
  10906                                                     " element %d should be"
  10907                                                     " allocated but it is"
  10908                                                     " not\n",
  10909                                                     base[res][index],
  10910                                                     pattern,
  10911                                                     length,
  10912                                                     repeats,
  10913                                                     elem);
  10914                                             result = BCM_E_FAIL;
  10915                                         } else if (BCM_E_EXISTS != xresult) {
  10916                                             cli_out("unexpected result %d (%s)"
  10917                                                     " reading base %d pattern"
  10918                                                     " %08X length %d repeats"
  10919                                                     " %d at %d\n",
  10920                                                     xresult,
  10921                                                     _SHR_ERRMSG(xresult),
  10922                                                     base[res][index],
  10923                                                     pattern,
  10924                                                     length,
  10925                                                     repeats,
  10926                                                     elem);
  10927                                             result = BCM_E_FAIL;
  10928                                         }
  10929                                     } else { /* if (pattern & (1 << offset)) */
  10930                                         /* element should not be allocated */
  10931                                         if (BCM_E_EXISTS == xresult) {
  10932                                             cli_out("base %d pattern %08X length"
  10933                                                     " %d repeats %d implies"
  10934                                                     " element %d should not be"
  10935                                                     " allocated but it is\n",
  10936                                                     base[res][index],
  10937                                                     pattern,
  10938                                                     length,
  10939                                                     repeats,
  10940                                                     elem);
  10941                                             result = BCM_E_FAIL;
  10942                                         } else if (BCM_E_NOT_FOUND != xresult) {
  10943                                             cli_out("unexpected result %d (%s)"
  10944                                                     " reading base %d pattern"
  10945                                                     " %08X length %d repeats"
  10946                                                     " %d at %d\n",
  10947                                                     xresult,
  10948                                                     _SHR_ERRMSG(xresult),
  10949                                                     base[res][index],
  10950                                                     pattern,
  10951                                                     length,
  10952                                                     repeats,
  10953                                                     elem);
  10954                                             result = BCM_E_FAIL;
  10955                                         }
  10956                                     } /* if (pattern & (1 << offset)) */
  10957                                 } /* for (all elements in the pattern) */
  10958                             } /* for (all repeats of the pattern) */
  10959                             for (/* init already done */;
  10960                                  elem < size[res][1];
  10961                                  elem++) {
  10962                                 xresult = shr_mres_check(localRes,
  10963                                                          res,
  10964                                                          1,
  10965                                                          elem);
  10966                                 if (BCM_E_EXISTS == xresult) {
  10967                                     cli_out("unexpected allocated element in"
  10968                                             " %p %d element %d\n",
  10969                                             (void*)localRes,
  10970                                             res,
  10971                                             elem);
  10972                                     result = BCM_E_FAIL;
  10973                                 } else if (BCM_E_NOT_FOUND != xresult) {
  10974                                     cli_out("unexpected result checking %p %d"
  10975                                             " element %d: %d (%s)\n",
  10976                                             (void*)localRes,
  10977                                             res,
  10978                                             elem,
  10979                                             xresult,
  10980                                             _SHR_ERRMSG(xresult));
  10981                                     result = BCM_E_FAIL;
  10982                                 }
  10983                             } /* for (all elements after the block) */
  10984                             xresult = shr_mres_free_sparse(localRes,
  10985                                                            res,
  10986                                                            pattern,
  10987                                                            length,
  10988                                                            repeats,
  10989                                                            base[res][0]);
  10990                             if (BCM_E_NONE != xresult) {
  10991                                 cli_out("free_sparse(%p,%d,%08X,"
  10992                                         "%d,%d,%d) failed: %d (%s)\n",
  10993                                         (void*)localRes,
  10994                                         res,
  10995                                         pattern,
  10996                                         length,
  10997                                         repeats,
  10998                                         base[res][0],
  10999                                         result,
  11000                                         _SHR_ERRMSG(result));
  11001                                 result = xresult;
  11002                             }
  11003                         } /* if (BCM_E_NONE == result) */
  11004                     } /* for (several different repeat counts) */
  11005                 } /* for (several different pattern lengths) */
  11006                 if (BCM_E_NONE == result) {
  11007                     cli_out("testing %p resource %d -- entirely fill with"
  11008                             " interlocking sparse pattern\n",
  11009                             (void*)localRes,
  11010                             res);
  11011                     pattern = 0x5;
  11012                     length = 4;
  11013                     repeats = 1;
  11014                     base[res][0] = (size[res][1] >> 2);
  11015                     for (index = 0;
  11016                          (BCM_E_NONE == result) && (index < base[res][0]);
  11017                          index++) {
  11018                         result = shr_mres_alloc_align_sparse(localRes,
  11019                                                              res,
  11020                                                              0 /* flags */,
  11021                                                              4 /* align */,
  11022                                                              0 /* offset */,
  11023                                                              pattern,
  11024                                                              length,
  11025                                                              repeats,
  11026                                                              &(base[res][2]));
  11027                         if (BCM_E_NONE != result) {
  11028                             cli_out("alloc_align_sparse(%p,%d,%08X,%d,%d,"
  11029                                     "%08X,%d,%d,%p) %d/%d failed: %d (%s)\n",
  11030                                     (void*)localRes,
  11031                                     res,
  11032                                     0,
  11033                                     1,
  11034                                     0,
  11035                                     pattern,
  11036                                     length,
  11037                                     repeats,
  11038                                     (void*)(&(base[res][index])),
  11039                                     index,
  11040                                     base[res][0],
  11041                                     result,
  11042                                     _SHR_ERRMSG(result));
  11043                             shr_mres_dump(localRes);
  11044                         }
  11045                     }
  11046                     for (index = 0;
  11047                          (BCM_E_NONE == result) && (index < base[res][0]);
  11048                          index++) {
  11049                         result = shr_mres_alloc_align_sparse(localRes,
  11050                                                              res,
  11051                                                              0 /* flags */,
  11052                                                              4 /* align */,
  11053                                                              1 /* offset */,
  11054                                                              pattern,
  11055                                                              length,
  11056                                                              repeats,
  11057                                                              &(base[res][2]));
  11058                         if (BCM_E_NONE != result) {
  11059                             cli_out("alloc_align_sparse(%p,%d,%08X,%d,%d,"
  11060                                     "%08X,%d,%d,%p) %d/%d failed: %d (%s)\n",
  11061                                     (void*)localRes,
  11062                                     res,
  11063                                     0,
  11064                                     1,
  11065                                     0,
  11066                                     pattern,
  11067                                     length,
  11068                                     repeats,
  11069                                     (void*)(&(base[res][index])),
  11070                                     index,
  11071                                     base[res][0],
  11072                                     result,
  11073                                     _SHR_ERRMSG(result));
  11074                             shr_mres_dump(localRes);
  11075                         }
  11076                     }
  11077                     for (elem = size[res][0];
  11078                          elem < size[res][0] + size[res][1];
  11079                          elem++) {
  11080                         xresult = shr_mres_check(localRes,
  11081                                                  res,
  11082                                                  1,
  11083                                                  elem);
  11084                         if (BCM_E_NOT_FOUND == xresult) {
  11085                             cli_out("unexpected free element in"
  11086                                     " %p %d element %d\n",
  11087                                     (void*)localRes,
  11088                                     res,
  11089                                     elem);
  11090                             result = BCM_E_FAIL;
  11091                         } else if (BCM_E_EXISTS != xresult) {
  11092                             cli_out("unexpected result checking %p %d"
  11093                                     " element %d: %d (%s)\n",
  11094                                     (void*)localRes,
  11095                                     res,
  11096                                     elem,
  11097                                     xresult,
  11098                                     _SHR_ERRMSG(xresult));
  11099                             result = BCM_E_FAIL;
  11100                         }
  11101                     } /* for (all elements before the block) */
  11102                     for (elem = size[res][0];
  11103                          (BCM_E_NONE == result) &&
  11104                          (elem < (size[res][1] + size[res][0]) - 2);
  11105                          elem++) {
  11106                         if ((elem - size[res][0]) & 2) {
  11107                             elem += 2;
  11108                         }
  11109                         xresult = shr_mres_check_all_sparse(localRes,
  11110                                                             res,
  11111                                                             pattern,
  11112                                                             length,
  11113                                                             repeats,
  11114                                                             elem);
  11115                         if (BCM_E_FULL == xresult) {
  11116                             result = shr_mres_free_sparse(localRes,
  11117                                                           res,
  11118                                                           pattern,
  11119                                                           length,
  11120                                                           repeats,
  11121                                                           elem);
  11122                             if (BCM_E_NONE != result) {
  11123                                 cli_out("free_sparse(%p,%d,%08X,"
  11124                                         "%d,%d,%d) failed: %d (%s)\n",
  11125                                         (void*)localRes,
  11126                                         res,
  11127                                         pattern,
  11128                                         length,
  11129                                         repeats,
  11130                                         elem,
  11131                                         result,
  11132                                         _SHR_ERRMSG(result));
  11133                             }
  11134                         } else if (((BCM_E_EXISTS == xresult) ||
  11135                                     (BCM_E_CONFIG == xresult)) &&
  11136                                    (elem == size[res][0])) {
  11137                             /* this is okay: initial might be misaligned */
  11138                         } else if (BCM_E_EMPTY != xresult) {
  11139                             cli_out("unexpected result from check_all_sparse("
  11140                                     "%p,%d,%08X,%d,%d,%d) : %d (%s)\n",
  11141                                     (void*)localRes,
  11142                                     res,
  11143                                     pattern,
  11144                                     length,
  11145                                     repeats,
  11146                                     elem,
  11147                                     xresult,
  11148                                     _SHR_ERRMSG(xresult));
  11149                             result = xresult;
  11150                         }
  11151                     } /* for (all possible positions for the pattern) */
  11152                 } /* if (BCM_E_NONE == result) */
  11153             } /* for (all types as long as no error) */
  11154         } else { /* if (localRes) */
  11155             cli_out("no resources for testing; use 'ResTest Create' first.\n");
  11156         } /* if (localRes) */
  11157     } else if (!sal_strncasecmp(c, "t", 1)) {
  11158         /* any other 'Tsomething' argument */
  11159         if (localRes) {
  11160             result = shr_mres_get(localRes, &rescount, NULL);
  11161             if (BCM_E_NONE == result) {
  11162                 if (rescount > SHR_RES_ALLOCATOR_COUNT << 1) {
  11163                     rescount = SHR_RES_ALLOCATOR_COUNT << 1;
  11164                 }
  11165             } else {
  11166                 cli_out("unable to retrieve %p resource type count : %d (%s)\n",
  11167                         (void*)localRes,
  11168                         result,
  11169                         _SHR_ERRMSG(result));
  11170                 rescount = 0;
  11171             }
  11172             for (res = 0;
  11173                  (BCM_E_NONE == result) && (res < rescount);
  11174                  res++) {
  11175                 skip[res] = FALSE;
  11176                 result = shr_mres_type_get(localRes, res, &pool, NULL, NULL);
  11177                 if (BCM_E_NONE == result) {
  11178                     result = shr_mres_pool_get(localRes,
  11179                                                pool,
  11180                                                &restype,
  11181                                                &(base[res][0]),
  11182                                                &(size[res][0]),
  11183                                                &extraGet,
  11184                                                NULL);
  11185                     if (BCM_E_NONE == result) {
  11186                         result = shr_mres_check(localRes,
  11187                                                 res,
  11188                                                 base[res][0],
  11189                                                 size[res][0]);
  11190                         if (BCM_E_EXISTS == result) {
  11191                             cli_out("%p res %d has allocated elements that"
  11192                                     " it should not have",
  11193                                     (void*)localRes,
  11194                                     res);
  11195                         } else if (BCM_E_NOT_FOUND == result) {
  11196                             /* this is the expected condition */
  11197                             result = BCM_E_NONE;
  11198                         } else {
  11199                             cli_out("%p res %d unexpected result checking for"
  11200                                     " residual allocated elements\n",
  11201                                     (void*)localRes,
  11202                                     res);
  11203                         }
  11204                     }
  11205                 }
  11206             }
  11207         } else { /* if (localRes) */
  11208             cli_out("no resources for testing; use 'ResTest Create' first.\n");
  11209         } /* if (localRes) */
  11210     } else {
  11211         return CMD_USAGE;
  11212     }
  11213     if (BCM_E_NONE != result) {
  11214         return CMD_FAIL;
  11215     } else {
  11216         return CMD_OK;
  11217     }
  11218 }
  11219