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