1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * bscv.c - multi-threaded lom driver for the Stiletto platform. 29 */ 30 31 /* 32 * Included files. 33 */ 34 35 #include <sys/note.h> 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/uio.h> 39 #include <sys/open.h> 40 #include <sys/cred.h> 41 #include <sys/stream.h> 42 #include <sys/systm.h> 43 #include <sys/conf.h> 44 #include <sys/reboot.h> 45 #include <sys/modctl.h> 46 #include <sys/mkdev.h> 47 #include <sys/errno.h> 48 #include <sys/debug.h> 49 #include <sys/kmem.h> 50 #include <sys/consdev.h> 51 #include <sys/file.h> 52 #include <sys/stat.h> 53 #include <sys/disp.h> 54 #include <sys/ddi.h> 55 #include <sys/sunddi.h> 56 #include <sys/stream.h> 57 #include <sys/strlog.h> 58 #include <sys/log.h> 59 #include <sys/utsname.h> 60 #include <sys/callb.h> 61 #include <sys/sysevent.h> 62 #include <sys/nvpair.h> 63 #include <sys/sysevent/eventdefs.h> 64 #include <sys/sysevent/domain.h> 65 #include <sys/sysevent/env.h> 66 #include <sys/sysevent/dr.h> 67 68 #include <sys/lom_io.h> 69 #include <sys/bscbus.h> 70 #include <sys/bscv_impl.h> 71 72 /* 73 * Variables defined here and visible internally only 74 */ 75 76 static void *bscv_statep = NULL; 77 78 /* 79 * Forward declarations 80 */ 81 82 static int bscv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 83 static int bscv_attach(dev_info_t *, ddi_attach_cmd_t); 84 static int bscv_detach(dev_info_t *, ddi_detach_cmd_t); 85 static int bscv_reset(dev_info_t *, ddi_reset_cmd_t); 86 static int bscv_quiesce(dev_info_t *); 87 static int bscv_map_regs(bscv_soft_state_t *); 88 static void bscv_unmap_regs(bscv_soft_state_t *); 89 static void bscv_map_chan_logical_physical(bscv_soft_state_t *); 90 91 static int bscv_open(dev_t *, int, int, cred_t *); 92 static int bscv_close(dev_t, int, int, cred_t *); 93 static void bscv_full_stop(bscv_soft_state_t *); 94 95 static void bscv_enter(bscv_soft_state_t *); 96 static void bscv_exit(bscv_soft_state_t *); 97 #ifdef DEBUG 98 static int bscv_held(bscv_soft_state_t *); 99 #endif /* DEBUG */ 100 101 static void bscv_put8(bscv_soft_state_t *, int, bscv_addr_t, uint8_t); 102 static void bscv_put16(bscv_soft_state_t *, int, bscv_addr_t, uint16_t); 103 static void bscv_put32(bscv_soft_state_t *, int, bscv_addr_t, uint32_t); 104 static uint8_t bscv_get8(bscv_soft_state_t *, int, bscv_addr_t); 105 static uint16_t bscv_get16(bscv_soft_state_t *, int, bscv_addr_t); 106 static uint32_t bscv_get32(bscv_soft_state_t *, int, bscv_addr_t); 107 static void bscv_setclear8(bscv_soft_state_t *, int, 108 bscv_addr_t, uint8_t, uint8_t); 109 static void bscv_setclear8_volatile(bscv_soft_state_t *, int, 110 bscv_addr_t, uint8_t, uint8_t); 111 static void bscv_rep_rw8(bscv_soft_state_t *, int, 112 uint8_t *, bscv_addr_t, size_t, uint_t, boolean_t); 113 static uint8_t bscv_get8_cached(bscv_soft_state_t *, bscv_addr_t); 114 115 static uint8_t bscv_get8_locked(bscv_soft_state_t *, int, bscv_addr_t, int *); 116 static void bscv_rep_get8_locked(bscv_soft_state_t *, int, 117 uint8_t *, bscv_addr_t, size_t, uint_t, int *); 118 119 static boolean_t bscv_faulty(bscv_soft_state_t *); 120 static void bscv_clear_fault(bscv_soft_state_t *); 121 static void bscv_set_fault(bscv_soft_state_t *); 122 static boolean_t bscv_session_error(bscv_soft_state_t *); 123 static int bscv_retcode(bscv_soft_state_t *); 124 static int bscv_should_retry(bscv_soft_state_t *); 125 static void bscv_locked_result(bscv_soft_state_t *, int *); 126 127 static void bscv_put8_once(bscv_soft_state_t *, int, bscv_addr_t, uint8_t); 128 static uint8_t bscv_get8_once(bscv_soft_state_t *, int, bscv_addr_t); 129 static uint32_t bscv_probe(bscv_soft_state_t *, int, uint32_t *); 130 static void bscv_resync_comms(bscv_soft_state_t *, int); 131 132 static boolean_t bscv_window_setup(bscv_soft_state_t *); 133 static int bscv_eerw(bscv_soft_state_t *, uint32_t, uint8_t *, 134 unsigned, boolean_t); 135 136 static int bscv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 137 static int bscv_ioc_dogstate(bscv_soft_state_t *, intptr_t, int); 138 static int bscv_ioc_psustate(bscv_soft_state_t *, intptr_t, int); 139 static int bscv_ioc_fanstate(bscv_soft_state_t *, intptr_t, int); 140 static int bscv_ioc_fledstate(bscv_soft_state_t *, intptr_t, int); 141 static int bscv_ioc_ledstate(bscv_soft_state_t *, intptr_t, int); 142 static int bscv_ioc_info(bscv_soft_state_t *, intptr_t, int); 143 static int bscv_ioc_mread(bscv_soft_state_t *, intptr_t, int); 144 static int bscv_ioc_volts(bscv_soft_state_t *, intptr_t, int); 145 static int bscv_ioc_stats(bscv_soft_state_t *, intptr_t, int); 146 static int bscv_ioc_temp(bscv_soft_state_t *, intptr_t, int); 147 static int bscv_ioc_cons(bscv_soft_state_t *, intptr_t, int); 148 static int bscv_ioc_eventlog2(bscv_soft_state_t *, intptr_t, int); 149 static int bscv_ioc_info2(bscv_soft_state_t *, intptr_t, int); 150 static int bscv_ioc_test(bscv_soft_state_t *, intptr_t, int); 151 static int bscv_ioc_mprog2(bscv_soft_state_t *, intptr_t, int); 152 static int bscv_ioc_mread2(bscv_soft_state_t *, intptr_t, int); 153 154 static void bscv_event_daemon(void *); 155 static void bscv_start_event_daemon(bscv_soft_state_t *); 156 static int bscv_stop_event_daemon(bscv_soft_state_t *); 157 static int bscv_pause_event_daemon(bscv_soft_state_t *); 158 static void bscv_resume_event_daemon(bscv_soft_state_t *); 159 static void bscv_event_process(bscv_soft_state_t *ssp, boolean_t); 160 static int bscv_event_validate(bscv_soft_state_t *, uint32_t, uint8_t); 161 static void bscv_event_process_one(bscv_soft_state_t *, lom_event_t *); 162 static void bscv_build_eventstring(bscv_soft_state_t *, 163 lom_event_t *, char *, char *); 164 static int bscv_level_of_event(lom_event_t *); 165 static void bscv_status(bscv_soft_state_t *, uint8_t, uint8_t); 166 char *bscv_get_label(char [][MAX_LOM2_NAME_STR], int, int); 167 static void bscv_generic_sysevent(bscv_soft_state_t *, char *, char *, char *, 168 char *, int32_t, char *); 169 static void bscv_sysevent(bscv_soft_state_t *, lom_event_t *); 170 171 static int bscv_prog(bscv_soft_state_t *, intptr_t, int); 172 static int bscv_prog_image(bscv_soft_state_t *, boolean_t, 173 uint8_t *, int, uint32_t); 174 static int bscv_prog_receive_image(bscv_soft_state_t *, lom_prog_t *, 175 uint8_t *, int); 176 static void bscv_leave_programming_mode(bscv_soft_state_t *, boolean_t); 177 static int bscv_prog_stop_lom(bscv_soft_state_t *); 178 static int bscv_prog_start_lom(bscv_soft_state_t *); 179 180 static int bscv_attach_common(bscv_soft_state_t *); 181 static int bscv_cleanup(bscv_soft_state_t *); 182 static void bscv_setup_capability(bscv_soft_state_t *); 183 static int bscv_probe_check(bscv_soft_state_t *); 184 static void bscv_setup_hostname(bscv_soft_state_t *); 185 static void bscv_read_hostname(bscv_soft_state_t *, char *); 186 static void bscv_write_hostname(bscv_soft_state_t *, char *, uint8_t); 187 static void bscv_setup_static_info(bscv_soft_state_t *); 188 static uint8_t bscv_read_env_name(bscv_soft_state_t *, uint8_t, 189 uint8_t, uint8_t, char [][MAX_LOM2_NAME_STR], int); 190 static void bscv_setup_events(bscv_soft_state_t *); 191 192 static void bscv_trace(bscv_soft_state_t *, char, const char *, 193 const char *, ...); 194 195 #ifdef __sparc 196 static void bscv_idi_init(); 197 static void bscv_idi_fini(); 198 static void bscv_idi_new_instance(dev_info_t *dip); 199 static void bscv_idi_clear_err(); 200 void bscv_idi_set(struct bscv_idi_info info); 201 static boolean_t bscv_idi_err(); 202 static boolean_t bscv_nodename_set(struct bscv_idi_info info); 203 static boolean_t bscv_sig_set(struct bscv_idi_info info); 204 static boolean_t bscv_wdog_pat(struct bscv_idi_info info); 205 static boolean_t bscv_wdog_cfg(struct bscv_idi_info info); 206 static void bscv_write_sig(bscv_soft_state_t *ssp, bscv_sig_t s); 207 #endif /* __sparc */ 208 209 static void bscv_setup_watchdog(bscv_soft_state_t *ssp); 210 static void bscv_write_wdog_cfg(bscv_soft_state_t *, 211 uint_t, boolean_t, uint8_t); 212 213 #if defined(__i386) || defined(__amd64) 214 static void bscv_inform_bsc(bscv_soft_state_t *, uint32_t); 215 static void bscv_watchdog_pat_request(void *); 216 static void bscv_watchdog_cfg_request(bscv_soft_state_t *, uint8_t); 217 static uint_t bscv_set_watchdog_timer(bscv_soft_state_t *, uint_t); 218 static void bscv_clear_watchdog_timer(bscv_soft_state_t *); 219 220 static boolean_t bscv_panic_callback(void *, int); 221 static void bscv_watchdog_cyclic_add(bscv_soft_state_t *); 222 static void bscv_watchdog_cyclic_remove(bscv_soft_state_t *); 223 224 static uint8_t wdog_reset_on_timeout = 1; 225 226 #define WDOG_ON 1 227 #define WDOG_OFF 0 228 #define CLK_WATCHDOG_DEFAULT 10 /* 10 seconds */ 229 #define WATCHDOG_PAT_INTERVAL 1000000000 /* 1 second */ 230 231 static int bscv_watchdog_enable; 232 static int bscv_watchdog_available; 233 static int watchdog_activated; 234 static uint_t bscv_watchdog_timeout_seconds; 235 #endif /* __i386 || __amd64 */ 236 237 #ifdef __sparc 238 struct bscv_idi_callout bscv_idi_callout_table[] = { 239 {BSCV_IDI_NODENAME, &bscv_nodename_set }, 240 {BSCV_IDI_SIG, &bscv_sig_set }, 241 {BSCV_IDI_WDOG_PAT, &bscv_wdog_pat }, 242 {BSCV_IDI_WDOG_CFG, &bscv_wdog_cfg }, 243 {BSCV_IDI_NULL, NULL } 244 }; 245 246 static struct bscv_idi_callout_mgr bscv_idi_mgr; 247 #endif /* __sparc */ 248 249 /* 250 * Local Definitions 251 */ 252 #define STATUS_READ_LIMIT 8 /* Read up to 8 status changes at a time */ 253 #define MYNAME "bscv" 254 #define BSCV_INST_TO_MINOR(i) (i) 255 #define BSCV_MINOR_TO_INST(m) (m) 256 257 /* 258 * Strings for daemon event reporting 259 */ 260 261 static char *eventSubsysStrings[] = 262 { "", /* 00 */ 263 "Alarm ", /* 01 */ 264 "temperature sensor ", /* 02 */ 265 "overheat sensor ", /* 03 */ 266 "Fan ", /* 04 */ 267 "supply rail ", /* 05 */ 268 "circuit breaker ", /* 06 */ 269 "PSU ", /* 07 */ 270 "user ", /* 08 */ 271 "phonehome ", /* 09; unutilized */ 272 "LOM ", /* 0a */ 273 "host ", /* 0b */ 274 "event log ", /* 0c */ 275 "", /* 0d; EVENT_SUBSYS_EXTRA unutilized */ 276 "LED ", /* 0e */ 277 }; 278 279 static char *eventTypeStrings[] = 280 { 281 "[null event]", /* 00 */ 282 "ON", /* 01 */ 283 "OFF", /* 02 */ 284 "state change", /* 03 */ 285 "power on", /* 04 */ 286 "power off", /* 05 */ 287 "powered off unexpectedly", /* 06 */ 288 "reset unexpectedly", /* 07 */ 289 "booted", /* 08 */ 290 "watchdog enabled", /* 09 */ 291 "watchdog disabled", /* 0a */ 292 "watchdog triggered", /* 0b */ 293 "failed", /* 0c */ 294 "recovered", /* 0d */ 295 "reset", /* 0e */ 296 "XIR reset", /* 0f */ 297 "console selected", /* 10 */ 298 "time reference", /* 11 */ 299 "script failure", /* 12 */ 300 "modem access failure", /* 13 */ 301 "modem dialing failure", /* 14 */ 302 "bad checksum", /* 15 */ 303 "added", /* 16 */ 304 "removed", /* 17 */ 305 "changed", /* 18 */ 306 "login", /* 19 */ 307 "password changed", /* 1a */ 308 "login failed", /* 1b */ 309 "logout", /* 1c */ 310 "flash download", /* 1d */ 311 "data lost", /* 1e */ 312 "device busy", /* 1f */ 313 "fault led state", /* 20 */ 314 "overheat", /* 21 */ 315 "severe overheat", /* 22 */ 316 "no overheat", /* 23 */ 317 "SCC", /* 24 */ 318 "device inaccessible", /* 25 */ 319 "Hostname change", /* 26 */ 320 "CPU signature timeout", /* 27 */ 321 "Bootmode change", /* 28 */ 322 "Watchdog change policy", /* 29 */ 323 "Watchdog change timeout", /* 2a */ 324 }; 325 326 /* 327 * These store to mapping between the logical service, e.g. chan_prog for 328 * programming, and the actual Xbus channel which carries that traffic. 329 * Any services can be shared on the same channel apart from chan_wdogpat. 330 */ 331 static int chan_general; /* General Traffic */ 332 static int chan_wdogpat; /* Watchdog Patting */ 333 static int chan_cpusig; /* CPU signatures */ 334 static int chan_eeprom; /* EEPROM I/O */ 335 static int chan_prog; /* Programming */ 336 337 /* 338 * cb_ops structure defining the driver entry points 339 */ 340 341 static struct cb_ops bscv_cb_ops = { 342 bscv_open, /* open */ 343 bscv_close, /* close */ 344 nodev, /* strategy */ 345 nodev, /* print */ 346 nodev, /* dump */ 347 nodev, /* read */ 348 nodev, /* write */ 349 bscv_ioctl, /* ioctl */ 350 nodev, /* devmap */ 351 nodev, /* mmap */ 352 nodev, /* segmap */ 353 nochpoll, /* poll */ 354 ddi_prop_op, /* prop op */ 355 NULL, /* ! STREAMS */ 356 D_NEW | D_MP /* MT/MP Safe */ 357 }; 358 359 /* 360 * dev_ops structure defining autoconfiguration driver autoconfiguration 361 * routines 362 */ 363 364 static struct dev_ops bscv_dev_ops = { 365 DEVO_REV, /* devo_rev */ 366 0, /* devo_refcnt */ 367 bscv_getinfo, /* devo_getinfo */ 368 nulldev, /* devo_identify */ 369 nulldev, /* devo_probe */ 370 bscv_attach, /* devo_attach */ 371 bscv_detach, /* devo_detach */ 372 bscv_reset, /* devo_reset */ 373 &bscv_cb_ops, /* devo_cb_ops */ 374 (struct bus_ops *)0, /* devo_bus_ops */ 375 NULL, /* devo_power */ 376 bscv_quiesce, /* devo_quiesce */ 377 }; 378 379 /* 380 * module configuration section 381 */ 382 383 #ifdef DEBUG 384 #define BSCV_VERSION_STRING "bscv driver - Debug" 385 #else /* DEBUG */ 386 #define BSCV_VERSION_STRING "bscv driver" 387 #endif /* DEBUG */ 388 389 static struct modldrv modldrv = { 390 &mod_driverops, 391 BSCV_VERSION_STRING, 392 &bscv_dev_ops, 393 }; 394 395 static struct modlinkage modlinkage = { 396 MODREV_1, 397 &modldrv, 398 NULL 399 }; 400 401 /* 402 * kernel accessible routines. These routines are necessarily global so the 403 * driver can be loaded, and unloaded successfully 404 */ 405 406 /* 407 * function - _init 408 * description - initializes the driver state structure and installs the 409 * driver module into the kernel 410 * inputs - none 411 * outputs - success or failure of module installation 412 */ 413 414 int 415 _init(void) 416 { 417 register int e; 418 419 if ((e = ddi_soft_state_init(&bscv_statep, 420 sizeof (bscv_soft_state_t), 1)) != 0) { 421 return (e); 422 } 423 424 if ((e = mod_install(&modlinkage)) != 0) { 425 ddi_soft_state_fini(&bscv_statep); 426 } 427 428 #ifdef __sparc 429 if (e == 0) bscv_idi_init(); 430 #endif /* __sparc */ 431 return (e); 432 } 433 434 /* 435 * function - _info 436 * description - provide information about a kernel loaded module 437 * inputs - module infomation 438 * outputs - success or failure of information request 439 */ 440 441 int 442 _info(struct modinfo *modinfop) 443 { 444 return (mod_info(&modlinkage, modinfop)); 445 } 446 447 /* 448 * function - _fini 449 * description - removes a module from the kernel and frees the driver soft 450 * state memory 451 * inputs - none 452 * outputs - success or failure of module removal 453 */ 454 455 int 456 _fini(void) 457 { 458 register int e; 459 460 if ((e = mod_remove(&modlinkage)) != 0) { 461 return (e); 462 } 463 464 #ifdef __sparc 465 bscv_idi_fini(); 466 #endif /* __sparc */ 467 ddi_soft_state_fini(&bscv_statep); 468 469 return (e); 470 } 471 472 /* 473 * function - bscv_getinfo 474 * description - routine used to provide information on the driver 475 * inputs - device information structure, command, command arg, storage 476 * area for the result 477 * outputs - DDI_SUCCESS or DDI_FAILURE 478 */ 479 480 /*ARGSUSED*/ 481 static int 482 bscv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 483 { 484 bscv_soft_state_t *ssp; 485 dev_t dev = (dev_t)arg; 486 int instance; 487 int error; 488 489 instance = DEVICETOINSTANCE(dev); 490 491 switch (cmd) { 492 case DDI_INFO_DEVT2INSTANCE: 493 *result = (void *)(uintptr_t)instance; 494 error = DDI_SUCCESS; 495 break; 496 497 case DDI_INFO_DEVT2DEVINFO: 498 ssp = ddi_get_soft_state(bscv_statep, instance); 499 if (ssp == NULL) 500 return (DDI_FAILURE); 501 *result = (void *) ssp->dip; 502 error = DDI_SUCCESS; 503 break; 504 505 default: 506 error = DDI_FAILURE; 507 break; 508 } 509 510 return (error); 511 } 512 513 #ifdef __sparc 514 void 515 bscv_idi_init() 516 { 517 bscv_idi_mgr.valid_inst = (uint32_t)~0; /* No valid instances */ 518 bscv_idi_mgr.tbl = bscv_idi_callout_table; 519 bscv_idi_mgr.errs = 0; 520 521 /* 522 * Now that all fields are initialized, set the magic flag. This is 523 * a kind of integrity check for the data structure. 524 */ 525 bscv_idi_mgr.magic = BSCV_IDI_CALLOUT_MAGIC; 526 } 527 528 static void 529 bscv_idi_clear_err() 530 { 531 ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC); 532 533 bscv_idi_mgr.errs = 0; 534 } 535 536 /* 537 * function - bscv_idi_err 538 * description - error messaging service which throttles the number of error 539 * messages to avoid overflowing storage 540 * inputs - none 541 * returns - boolean to indicate whether a message should be reported 542 * side-effects - updates the error number counter 543 */ 544 static boolean_t 545 bscv_idi_err() 546 { 547 ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC); 548 549 bscv_idi_mgr.errs++; 550 551 if (bscv_idi_mgr.errs++ < BSCV_IDI_ERR_MSG_THRESHOLD) 552 return (B_TRUE); 553 554 return (B_FALSE); 555 } 556 557 void 558 bscv_idi_new_instance(dev_info_t *dip) 559 { 560 ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC); 561 562 /* 563 * We don't care how many instances we have, or their value, so long 564 * as we have at least one valid value. This is so service routines 565 * can get any required locks via a soft state pointer. 566 */ 567 if (bscv_idi_mgr.valid_inst == (uint32_t)~0) { 568 bscv_idi_mgr.valid_inst = ddi_get_instance(dip); 569 } 570 } 571 572 void 573 bscv_idi_fini() 574 { 575 bscv_idi_mgr.valid_inst = (uint32_t)~0; /* No valid instances */ 576 bscv_idi_mgr.tbl = NULL; 577 } 578 #endif /* __sparc */ 579 580 /* 581 * function - bscv_attach 582 * description - this routine is responsible for setting aside memory for the 583 * driver data structures, initialising the mutexes and creating 584 * the device minor nodes. Additionally, this routine calls the 585 * the callback routine. 586 * inputs - device information structure, DDI_ATTACH command 587 * outputs - DDI_SUCCESS or DDI_FAILURE 588 */ 589 590 int 591 bscv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 592 { 593 bscv_soft_state_t *ssp; 594 int instance; 595 596 switch (cmd) { 597 case DDI_ATTACH: 598 599 instance = ddi_get_instance(dip); 600 601 if (ddi_soft_state_zalloc(bscv_statep, instance) != 602 DDI_SUCCESS) { 603 return (DDI_FAILURE); 604 } 605 606 607 ssp = ddi_get_soft_state(bscv_statep, instance); 608 609 ssp->progress = 0; 610 611 ssp->dip = dip; 612 ssp->instance = instance; 613 ssp->event_waiting = B_FALSE; 614 ssp->status_change = B_FALSE; 615 ssp->nodename_change = B_FALSE; 616 ssp->cap0 = 0; 617 ssp->cap1 = 0; 618 ssp->cap2 = 0; 619 ssp->prog_mode_only = B_FALSE; 620 ssp->programming = B_FALSE; 621 ssp->cssp_prog = B_FALSE; 622 ssp->task_flags = 0; 623 ssp->debug = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 624 DDI_PROP_DONTPASS, "debug", 0); 625 ssp->majornum = ddi_driver_major(dip); 626 ssp->minornum = BSCV_INST_TO_MINOR(instance); 627 #if defined(__i386) || defined(__amd64) 628 ssp->last_nodename[0] = '\0'; 629 #endif /* __i386 || __amd64 */ 630 631 /* 632 * initialise the mutexes 633 */ 634 635 mutex_init(&ssp->cmd_mutex, NULL, MUTEX_DRIVER, NULL); 636 637 mutex_init(&ssp->task_mu, NULL, MUTEX_DRIVER, NULL); 638 cv_init(&ssp->task_cv, NULL, CV_DRIVER, NULL); 639 cv_init(&ssp->task_evnt_cv, NULL, CV_DRIVER, NULL); 640 mutex_init(&ssp->prog_mu, NULL, MUTEX_DRIVER, NULL); 641 ssp->progress |= BSCV_LOCKS; 642 643 bscv_trace(ssp, 'A', "bscv_attach", 644 "bscv_attach: mutexes and condition vars initialised"); 645 646 /* Map in physical communication channels */ 647 648 if (bscv_map_regs(ssp) != DDI_SUCCESS) { 649 (void) bscv_cleanup(ssp); 650 return (DDI_FAILURE); 651 } 652 ssp->progress |= BSCV_MAPPED_REGS; 653 654 /* Associate logical channels to physical channels */ 655 656 bscv_map_chan_logical_physical(ssp); 657 658 bscv_enter(ssp); 659 660 bscv_leave_programming_mode(ssp, B_FALSE); 661 662 if (bscv_attach_common(ssp) == DDI_FAILURE) { 663 bscv_exit(ssp); 664 (void) bscv_cleanup(ssp); 665 return (DDI_FAILURE); 666 } 667 668 #ifdef __sparc 669 /* 670 * At this point the inter-driver-interface is made available. 671 * The IDI uses the event thread service which 672 * bscv_attach_common() sets up. 673 */ 674 bscv_idi_new_instance(dip); 675 #endif /* __sparc */ 676 677 bscv_exit(ssp); 678 679 /* 680 * now create the minor nodes 681 */ 682 if (ddi_create_minor_node(ssp->dip, "lom", S_IFCHR, 683 BSCV_INST_TO_MINOR(instance), 684 DDI_PSEUDO, 0) != DDI_SUCCESS) { 685 (void) bscv_cleanup(ssp); 686 return (DDI_FAILURE); 687 } 688 bscv_trace(ssp, 'A', "bscv_attach", 689 "bscv_attach: device minor nodes created"); 690 ssp->progress |= BSCV_NODES; 691 692 if (!ssp->prog_mode_only) 693 bscv_start_event_daemon(ssp); 694 695 #if defined(__i386) || defined(__amd64) 696 bscv_watchdog_enable = 1; 697 bscv_watchdog_available = 1; 698 watchdog_activated = 0; 699 bscv_watchdog_timeout_seconds = CLK_WATCHDOG_DEFAULT; 700 701 if (bscv_watchdog_enable && (boothowto & RB_DEBUG)) { 702 bscv_watchdog_available = 0; 703 cmn_err(CE_WARN, "bscv: kernel debugger " 704 "detected: hardware watchdog disabled"); 705 } 706 707 /* 708 * Before we enable the watchdog - register the panic 709 * callback so that we get called to stop the watchdog 710 * in the case of a panic. 711 */ 712 ssp->callb_id = callb_add(bscv_panic_callback, 713 (void *)ssp, CB_CL_PANIC, ""); 714 715 if (bscv_watchdog_available) { 716 (void) bscv_set_watchdog_timer(ssp, 717 CLK_WATCHDOG_DEFAULT); 718 bscv_enter(ssp); 719 bscv_setup_watchdog(ssp); /* starts cyclic callback */ 720 bscv_exit(ssp); 721 } 722 #endif /* __i386 || __amd64 */ 723 ddi_report_dev(dip); 724 return (DDI_SUCCESS); 725 default: 726 return (DDI_FAILURE); 727 } 728 } 729 730 /* 731 * function - bscv_detach 732 * description - routine that prepares a module to be unloaded. It undoes all 733 * the work done by the bscv_attach)() routine. This is 734 * facilitated by the use of the progress indicator 735 * inputs - device information structure, DDI_DETACH command 736 * outputs - DDI_SUCCESS or DDI_FAILURE 737 */ 738 739 /*ARGSUSED*/ 740 static int 741 bscv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 742 { 743 return (DDI_FAILURE); 744 } 745 746 /* 747 * function - bscv_reset 748 * description - routine called when system is being stopped - used to disable 749 * the watchdog. 750 * inputs - device information structure, DDI_RESET command 751 * outputs - DDI_SUCCESS or DDI_FAILURE 752 */ 753 static int 754 bscv_reset(dev_info_t *dip, ddi_reset_cmd_t cmd) 755 { 756 bscv_soft_state_t *ssp; 757 int instance; 758 759 switch (cmd) { 760 case DDI_RESET_FORCE: 761 762 instance = ddi_get_instance(dip); 763 ssp = ddi_get_soft_state(bscv_statep, instance); 764 if (ssp == NULL) { 765 return (DDI_FAILURE); 766 } 767 bscv_full_stop(ssp); 768 return (DDI_SUCCESS); 769 770 default: 771 return (DDI_FAILURE); 772 } 773 } 774 775 /* 776 * quiesce(9E) entry point. 777 * 778 * This function is called when the system is single-threaded at high 779 * PIL with preemption disabled. Therefore, this function must not be 780 * blocked. 781 * 782 * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure. 783 * DDI_FAILURE indicates an error condition and should almost never happen. 784 */ 785 static int 786 bscv_quiesce(dev_info_t *dip) 787 { 788 bscv_soft_state_t *ssp; 789 int instance; 790 791 792 instance = ddi_get_instance(dip); 793 ssp = ddi_get_soft_state(bscv_statep, instance); 794 if (ssp == NULL) { 795 return (DDI_FAILURE); 796 } 797 bscv_full_stop(ssp); 798 return (DDI_SUCCESS); 799 } 800 801 /* 802 * cb_ops routines 803 */ 804 805 /* 806 * function - bscv_open 807 * description - routine to provide association between user fd and device 808 * minor number. This routine is necessarily simple since a 809 * read/write interface is not provided. Additionally, the 810 * driver does not enforce exclusive access (FEXCL) or 811 * non-blocking during an open (FNDELAY). Deferred attach is 812 * supported. 813 * inputs - device number, flag specifying open type, device type, 814 * permissions 815 * outputs - success or failure of operation 816 */ 817 818 /*ARGSUSED*/ 819 static int 820 bscv_open(dev_t *devp, int flag, int otype, cred_t *cred) 821 { 822 bscv_soft_state_t *ssp; 823 int instance; 824 825 instance = DEVICETOINSTANCE(*devp); 826 ssp = ddi_get_soft_state(bscv_statep, instance); 827 if (ssp == NULL) { 828 return (ENXIO); /* not attached yet */ 829 } 830 bscv_trace(ssp, 'O', "bscv_open", "instance 0x%x", instance); 831 832 if (otype != OTYP_CHR) { 833 return (EINVAL); 834 } 835 836 return (0); 837 } 838 839 /* 840 * function - bscv_close 841 * description - routine to perform the final close on the device. As per the 842 * open routine, neither FEXCL or FNDELAY accesses are enforced 843 * by the driver. 844 * inputs - device number,flag specifying open type, device type, 845 * permissions 846 * outputs - success or failure of operation 847 */ 848 849 /*ARGSUSED1*/ 850 static int 851 bscv_close(dev_t dev, int flag, int otype, cred_t *cred) 852 { 853 bscv_soft_state_t *ssp; 854 int instance; 855 856 instance = DEVICETOINSTANCE(dev); 857 ssp = ddi_get_soft_state(bscv_statep, instance); 858 if (ssp == NULL) { 859 return (ENXIO); 860 } 861 bscv_trace(ssp, 'O', "bscv_close", "instance 0x%x", instance); 862 863 return (0); 864 } 865 866 static int 867 bscv_map_regs(bscv_soft_state_t *ssp) 868 { 869 int i; 870 int retval; 871 int *props; 872 unsigned int nelements; 873 874 ASSERT(ssp); 875 876 ssp->nchannels = 0; 877 878 /* 879 * Work out how many channels are available by looking at the number 880 * of elements of the regs property array. 881 */ 882 retval = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, ssp->dip, 883 DDI_PROP_DONTPASS, "reg", &props, &nelements); 884 885 /* We don't need props anymore. Free memory if it was allocated */ 886 if (retval == DDI_PROP_SUCCESS) 887 ddi_prop_free(props); 888 889 /* Check for sanity of nelements */ 890 if (retval != DDI_PROP_SUCCESS) { 891 bscv_trace(ssp, 'A', "bscv_map_regs", "lookup reg returned" 892 " 0x%x", retval); 893 goto cleanup_exit; 894 } else if (nelements % LOMBUS_REGSPEC_SIZE != 0) { 895 bscv_trace(ssp, 'A', "bscv_map_regs", "nelements %d not" 896 " a multiple of %d", nelements, LOMBUS_REGSPEC_SIZE); 897 goto cleanup_exit; 898 } else if (nelements > BSCV_MAXCHANNELS * LOMBUS_REGSPEC_SIZE) { 899 bscv_trace(ssp, 'A', "bscv_map_regs", "nelements %d too large" 900 ", probably a misconfiguration", nelements); 901 goto cleanup_exit; 902 } else if (nelements < BSCV_MINCHANNELS * LOMBUS_REGSPEC_SIZE) { 903 bscv_trace(ssp, 'A', "bscv_map_regs", "nelements %d too small" 904 ", need to have at least a general and a wdog channel", 905 nelements); 906 goto cleanup_exit; 907 } 908 909 ssp->nchannels = nelements / LOMBUS_REGSPEC_SIZE; 910 911 ssp->attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 912 ssp->attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 913 ssp->attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 914 915 for (i = 0; i < ssp->nchannels; i++) { 916 retval = ddi_regs_map_setup(ssp->dip, i, 917 (caddr_t *)&ssp->channel[i].regs, 918 0, 0, &ssp->attr, &ssp->channel[i].handle); 919 if (retval != DDI_SUCCESS) { 920 bscv_trace(ssp, 'A', "bscv_map_regs", "map failure" 921 " 0x%x on space %d", retval, i); 922 923 /* Rewind all current mappings - avoiding failed one */ 924 i--; 925 for (; i >= 0; i--) { 926 ddi_regs_map_free(&ssp->channel[i].handle); 927 } 928 929 goto cleanup_exit; 930 } 931 } 932 933 return (DDI_SUCCESS); 934 935 cleanup_exit: 936 /* 937 * It is important to set nchannels to 0 even if, say, only one of 938 * the two required handles was mapped. If we cannot achieve our 939 * minimum config its not safe to do any IO; this keeps our failure 940 * mode handling simpler. 941 */ 942 ssp->nchannels = 0; 943 return (DDI_FAILURE); 944 } 945 946 static void 947 bscv_unmap_regs(bscv_soft_state_t *ssp) 948 { 949 int i; 950 951 ASSERT(ssp); 952 953 for (i = 0; i < ssp->nchannels; i++) { 954 ddi_regs_map_free(&ssp->channel[i].handle); 955 } 956 } 957 958 /* 959 * Map logical services onto physical XBus channels. 960 */ 961 static void 962 bscv_map_chan_logical_physical(bscv_soft_state_t *ssp) 963 { 964 ASSERT(ssp); 965 966 /* 967 * We can assert that there will always be at least two channels, 968 * to allow watchdog pats to be segregated from all other traffic. 969 */ 970 chan_general = 0; 971 chan_wdogpat = 1; 972 973 /* 974 * By default move all other services onto the generic channel unless 975 * the hardware supports additional channels. 976 */ 977 978 chan_cpusig = chan_eeprom = chan_prog = chan_general; 979 980 if (ssp->nchannels > 2) 981 chan_cpusig = 2; 982 if (ssp->nchannels > 3) 983 chan_eeprom = 3; 984 if (ssp->nchannels > 4) 985 chan_prog = 4; 986 } 987 988 989 /* 990 * function - bscv_full_stop 991 * description - gracefully shut the lom down during panic or reboot. 992 * Disables the watchdog, setup up serial event reporting 993 * and stops the event daemon running. 994 * inputs - soft state pointer 995 * outputs - none 996 */ 997 void 998 bscv_full_stop(bscv_soft_state_t *ssp) 999 { 1000 uint8_t bits2set = 0; 1001 uint8_t bits2clear = 0; 1002 1003 bscv_trace(ssp, 'W', "bscv_full_stop", 1004 "turning off watchdog"); 1005 1006 if (!ddi_in_panic()) { 1007 /* Stop the event daemon if we are not panicking. */ 1008 (void) bscv_pause_event_daemon(ssp); 1009 } 1010 1011 bscv_enter(ssp); 1012 1013 #if defined(__i386) || defined(__amd64) 1014 if (ddi_in_panic()) { 1015 bscv_inform_bsc(ssp, BSC_INFORM_PANIC); 1016 } else { 1017 bscv_inform_bsc(ssp, BSC_INFORM_OFFLINE); 1018 } 1019 #endif /* __i386 || __amd64 */ 1020 1021 /* set serial event reporting */ 1022 switch (ssp->serial_reporting) { 1023 case LOM_SER_EVENTS_ON: 1024 case LOM_SER_EVENTS_DEF: 1025 /* Make sure serial event reporting is on */ 1026 bits2clear = EBUS_ALARM_NOEVENTS; 1027 break; 1028 case LOM_SER_EVENTS_OFF: 1029 /* Make sure serial event reporting is on */ 1030 bits2set = EBUS_ALARM_NOEVENTS; 1031 break; 1032 default: 1033 break; 1034 } 1035 bscv_setclear8_volatile(ssp, chan_general, 1036 EBUS_IDX_ALARM, bits2set, bits2clear); 1037 1038 bscv_exit(ssp); 1039 } 1040 1041 /* 1042 * LOM I/O routines. 1043 * 1044 * locking 1045 * 1046 * Two sets of routines are provided: 1047 * normal - must be called after acquiring an appropriate lock. 1048 * locked - perform all the locking required and return any error 1049 * code in the supplied 'res' argument. If there is no 1050 * error 'res' is not changed. 1051 * The locked routines are designed for use in ioctl commands where 1052 * only a single operation needs to be performed and the overhead of 1053 * locking and result checking adds significantly to code complexity. 1054 * 1055 * locking primitives 1056 * 1057 * bscv_enter() - acquires an I/O lock for the calling thread. 1058 * bscv_exit() - releases an I/O lock acquired by bscv_enter(). 1059 * bscv_held() - used to assert ownership of an I/O lock. 1060 * 1061 * normal I/O routines 1062 * 1063 * Note bscv_{put|get}{16|32} routines are big-endian. This assumes that 1064 * the firmware works that way too. 1065 * 1066 * bscv_put8(), bscv_put16, bscv_put32 - write values to the LOM 1067 * and handle any retries if necessary. 1068 * 16 and 32 bit values are big-endian. 1069 * bscv_get8(), bscv_get16, bscv_get32 - read values from the LOM 1070 * and handle any retries if necessary. 1071 * 16 and 32 bit values are big-endian. 1072 * bscv_setclear8() - set or clear the specified bits in the register 1073 * at the supplied address. 1074 * bscv_setclear8_volatile() - set or clear the specified bits in the 1075 * register at the supplied address. If the lom reports 1076 * that the registers has changed since the last read 1077 * re-read and apply the set or clear to the new bits. 1078 * bscv_get8_cached() - Return a cached register value (addr < 0x80). 1079 * Does not access the hardware. A read of the hardware 1080 * automatically updates this cache. 1081 * 1082 * locked I/O routines 1083 * 1084 * bscv_get8_locked(), bscv_rep_get8_locked(). 1085 * 1086 * Call the indicated function from above, but wrapping it with 1087 * bscv_enter()/bscv_exit(). 1088 * 1089 * 1090 * Fault management 1091 * 1092 * LOM communications fault are grouped into three categories: 1093 * 1) Faulty - the LOM is not responding and no attempt to communicate 1094 * with it should be made. 1095 * 2) Transient fault - something which might recover after a retry 1096 * but which doesn't affect our ability to perform other 1097 * commands. 1098 * 3) Command error - an inappropriate command was executed. A retry 1099 * will not fix it but the command failed. 1100 * 1101 * The current implementation of the bscv driver is not very good at 1102 * noticing command errors due to the structure of the original code 1103 * that it is based on. It is possible to extend the driver to do this 1104 * and would probably involve having a concept of a "session error" 1105 * which is less severe than a fault but means that a sequence of 1106 * commands had some fault which cannot be recovered. 1107 * 1108 * 1109 * faults 1110 * 1111 * bscv_faulty() - returns B_TRUE if the LOM (communications) have been 1112 * declared faulty. 1113 * bscv_clear_fault() - marks the LOM as not faulty. 1114 * bscv_set_fault() - marks the LOM as being faulty. 1115 * 1116 * bscv_clear_fault and bscv_set_fault should generally not be called 1117 * directly. 1118 * 1119 * command errors/transient faults 1120 * 1121 * bscv_retcode() - returns the actual error code of the last operation. 1122 * bscv_should_retry() - determines if last operation may suceed if 1123 * retried. 1124 * bscv_locked_result() - Set the result of a locked register access. 1125 * 1126 * low level I/O primitives 1127 * 1128 * These are generally not called directly. These perform a single 1129 * access to the LOM device. They do not handle retries. 1130 * 1131 * bscv_put8_once() 1132 * bscv_get8_once() 1133 * bscv_probe() - perform a probe (NOP) operation to check out lom comms. 1134 * bscv_resync_comms() - resynchronise communications after a transient fault. 1135 */ 1136 1137 static void 1138 bscv_enter(bscv_soft_state_t *ssp) 1139 { 1140 bscv_trace(ssp, '@', "bscv_enter", ""); 1141 mutex_enter(&ssp->cmd_mutex); 1142 ssp->had_session_error = B_FALSE; 1143 } 1144 1145 static void 1146 bscv_exit(bscv_soft_state_t *ssp) 1147 { 1148 mutex_exit(&ssp->cmd_mutex); 1149 bscv_trace(ssp, '@', "bscv_exit", ""); 1150 } 1151 1152 #ifdef DEBUG 1153 static int 1154 bscv_held(bscv_soft_state_t *ssp) 1155 { 1156 return (mutex_owned(&ssp->cmd_mutex)); 1157 } 1158 #endif /* DEBUG */ 1159 1160 static void 1161 bscv_put8(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint8_t val) 1162 { 1163 boolean_t needretry; 1164 int num_failures; 1165 1166 ASSERT(bscv_held(ssp)); 1167 1168 if (bscv_faulty(ssp)) { 1169 return; 1170 } 1171 1172 bscv_trace(ssp, '@', "bscv_put8", 1173 "addr 0x%x.%02x <= 0x%02x", addr >> 8, addr & 0xff, val); 1174 1175 for (num_failures = 0; 1176 num_failures < BSC_FAILURE_RETRY_LIMIT; 1177 num_failures++) { 1178 bscv_put8_once(ssp, chan, addr, val); 1179 needretry = bscv_should_retry(ssp); 1180 if (!needretry) { 1181 break; 1182 } 1183 } 1184 if (ssp->command_error != 0) { 1185 ssp->had_session_error = B_TRUE; 1186 } 1187 1188 if (needretry) { 1189 /* Failure - we ran out of retries */ 1190 cmn_err(CE_WARN, "bscv_put8: addr 0x%x.%02x retried " 1191 "write %d times, giving up", 1192 addr >> 8, addr & 0xff, num_failures); 1193 bscv_set_fault(ssp); 1194 } else if (num_failures > 0) { 1195 bscv_trace(ssp, 'R', "bscv_put8", 1196 "addr 0x%x.%02x retried write %d times, succeeded", 1197 addr >> 8, addr & 0xff, num_failures); 1198 } 1199 } 1200 1201 static void 1202 bscv_put16(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint16_t val) 1203 { 1204 ASSERT(bscv_held(ssp)); 1205 bscv_trace(ssp, '@', "bscv_put16", 1206 "addr 0x%x.%02x <= %04x", addr >> 8, addr & 0xff, val); 1207 bscv_put8(ssp, chan, addr, val >> 8); 1208 bscv_put8(ssp, chan, addr + 1, val & 0xff); 1209 } 1210 1211 static void 1212 bscv_put32(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint32_t val) 1213 { 1214 ASSERT(bscv_held(ssp)); 1215 bscv_trace(ssp, '@', "bscv_put32", 1216 "addr 0x%x.%02x <= %08x", addr >> 8, addr & 0xff, val); 1217 bscv_put8(ssp, chan, addr, (val >> 24) & 0xff); 1218 bscv_put8(ssp, chan, addr + 1, (val >> 16) & 0xff); 1219 bscv_put8(ssp, chan, addr + 2, (val >> 8) & 0xff); 1220 bscv_put8(ssp, chan, addr + 3, val & 0xff); 1221 } 1222 1223 static uint8_t 1224 bscv_get8(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr) 1225 { 1226 uint8_t retval; 1227 boolean_t needretry; 1228 int num_failures; 1229 1230 ASSERT(bscv_held(ssp)); 1231 1232 if (bscv_faulty(ssp)) { 1233 return (0); 1234 } 1235 1236 for (num_failures = 0; 1237 num_failures < BSC_FAILURE_RETRY_LIMIT; 1238 num_failures++) { 1239 retval = bscv_get8_once(ssp, chan, addr); 1240 needretry = bscv_should_retry(ssp); 1241 if (!needretry) { 1242 break; 1243 } 1244 } 1245 if (ssp->command_error != 0) { 1246 ssp->had_session_error = B_TRUE; 1247 } 1248 1249 if (needretry) { 1250 /* Failure */ 1251 cmn_err(CE_WARN, "bscv_get8: addr 0x%x.%02x retried " 1252 "read %d times, giving up", 1253 addr >> 8, addr & 0xff, num_failures); 1254 bscv_set_fault(ssp); 1255 } else if (num_failures > 0) { 1256 bscv_trace(ssp, 'R', "bscv_get8", 1257 "addr 0x%x.%02x retried read %d times, succeeded", 1258 addr >> 8, addr & 0xff, num_failures); 1259 } 1260 1261 bscv_trace(ssp, '@', "bscv_get8", 1262 "addr 0x%x.%02x => %02x", addr >> 8, addr & 0xff, retval); 1263 return (retval); 1264 } 1265 1266 static uint16_t 1267 bscv_get16(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr) 1268 { 1269 uint16_t retval; 1270 1271 ASSERT(bscv_held(ssp)); 1272 1273 retval = bscv_get8(ssp, chan, addr) << 8; 1274 retval |= bscv_get8(ssp, chan, addr + 1); 1275 1276 bscv_trace(ssp, '@', "bscv_get16", 1277 "addr 0x%x.%02x => %04x", addr >> 8, addr & 0xff, retval); 1278 return (retval); 1279 } 1280 1281 static uint32_t 1282 bscv_get32(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr) 1283 { 1284 uint32_t retval; 1285 1286 ASSERT(bscv_held(ssp)); 1287 1288 retval = bscv_get8(ssp, chan, addr) << 24; 1289 retval |= bscv_get8(ssp, chan, addr + 1) << 16; 1290 retval |= bscv_get8(ssp, chan, addr + 2) << 8; 1291 retval |= bscv_get8(ssp, chan, addr + 3); 1292 1293 bscv_trace(ssp, '@', "bscv_get32", 1294 "addr 0x%x.%02x => %08x", addr >> 8, addr & 0xff, retval); 1295 return (retval); 1296 } 1297 1298 static void 1299 bscv_setclear8(bscv_soft_state_t *ssp, int chan, 1300 bscv_addr_t addr, uint8_t set, uint8_t clear) 1301 { 1302 uint8_t val; 1303 1304 ASSERT(bscv_held(ssp)); 1305 ASSERT(addr < BSC_ADDR_CACHE_LIMIT); 1306 1307 val = ssp->lom_regs[addr] | set; 1308 val &= ~clear; 1309 1310 bscv_trace(ssp, '@', "bscv_setclear8", 1311 "addr 0x%x.%02x, set %02x, clear %02x => %02x", 1312 addr >> 8, addr & 0xff, 1313 set, clear, val); 1314 1315 bscv_put8(ssp, chan, addr, val); 1316 } 1317 1318 static void 1319 bscv_setclear8_volatile(bscv_soft_state_t *ssp, int chan, 1320 bscv_addr_t addr, uint8_t set, uint8_t clear) 1321 { 1322 uint8_t val; 1323 boolean_t needretry; 1324 int num_failures; 1325 1326 ASSERT(bscv_held(ssp)); 1327 ASSERT(addr < BSC_ADDR_CACHE_LIMIT); 1328 1329 if (bscv_faulty(ssp)) { 1330 return; 1331 } 1332 1333 bscv_trace(ssp, '@', "bscv_setclear8_volatile", 1334 "addr 0x%x.%02x => set %02x clear %02x", 1335 addr >> 8, addr & 0xff, set, clear); 1336 1337 val = bscv_get8_cached(ssp, addr); 1338 for (num_failures = 0; 1339 num_failures < BSC_FAILURE_RETRY_LIMIT; 1340 num_failures++) { 1341 val |= set; 1342 val &= ~clear; 1343 bscv_put8_once(ssp, chan, addr, val); 1344 if (ssp->command_error == EBUS_ERROR_STALEDATA) { 1345 /* Re-read the stale register from the lom */ 1346 val = bscv_get8_once(ssp, chan, addr); 1347 needretry = 1; 1348 } else { 1349 needretry = bscv_should_retry(ssp); 1350 if (!needretry) { 1351 break; 1352 } 1353 } 1354 } 1355 if (ssp->command_error != 0) { 1356 ssp->had_session_error = B_TRUE; 1357 } 1358 1359 if (needretry) { 1360 /* Failure */ 1361 cmn_err(CE_WARN, "bscv_setclear8_volatile: addr 0x%x.%02x " 1362 "retried write %d times, giving up", 1363 addr >> 8, addr & 0xff, num_failures); 1364 if (ssp->command_error != EBUS_ERROR_STALEDATA) { 1365 bscv_set_fault(ssp); 1366 } 1367 } else if (num_failures > 0) { 1368 bscv_trace(ssp, 'R', "bscv_setclear8_volatile", 1369 "addr 0x%x.%02x retried write %d times, succeeded", 1370 addr >> 8, addr & 0xff, num_failures); 1371 } 1372 } 1373 1374 static void 1375 bscv_rep_rw8(bscv_soft_state_t *ssp, int chan, uint8_t *host_addr, 1376 bscv_addr_t dev_addr, size_t repcount, uint_t flags, 1377 boolean_t is_write) 1378 { 1379 size_t inc; 1380 1381 ASSERT(bscv_held(ssp)); 1382 1383 inc = (flags & DDI_DEV_AUTOINCR) ? 1 : 0; 1384 for (; repcount--; dev_addr += inc) { 1385 if (flags & DDI_DEV_AUTOINCR) { 1386 if (is_write) { 1387 bscv_put8(ssp, chan, dev_addr, *host_addr++); 1388 } else { 1389 *host_addr++ = bscv_get8(ssp, chan, dev_addr); 1390 } 1391 } else { 1392 if (is_write) { 1393 bscv_put8_once(ssp, chan, 1394 dev_addr, *host_addr++); 1395 } else { 1396 *host_addr++ = bscv_get8_once(ssp, chan, 1397 dev_addr); 1398 } 1399 /* We need this because _once routines don't do it */ 1400 if (ssp->command_error != 0) { 1401 ssp->had_session_error = B_TRUE; 1402 } 1403 } 1404 if (bscv_faulty(ssp) || bscv_session_error(ssp)) { 1405 /* 1406 * No retry here. If we were AUTOINCR then get/put 1407 * will have retried. For NO_AUTOINCR we cannot retry 1408 * because the data would be corrupted. 1409 */ 1410 break; 1411 } 1412 } 1413 } 1414 1415 static uint8_t 1416 bscv_get8_cached(bscv_soft_state_t *ssp, bscv_addr_t addr) 1417 { 1418 ASSERT(addr < BSC_ADDR_CACHE_LIMIT); 1419 /* Can be called with or without the lock held */ 1420 1421 return (ssp->lom_regs[addr]); 1422 } 1423 1424 static uint8_t 1425 bscv_get8_locked(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, int *res) 1426 { 1427 uint8_t retval; 1428 1429 ASSERT(addr < BSC_ADDR_CACHE_LIMIT); 1430 bscv_enter(ssp); 1431 retval = bscv_get8(ssp, chan, addr); 1432 bscv_locked_result(ssp, res); 1433 bscv_exit(ssp); 1434 bscv_trace(ssp, '@', "bscv_get8_locked", 1435 "addr 0x%x.%02x => %02x", addr >> 8, addr & 0xff, retval); 1436 return (retval); 1437 } 1438 1439 static void 1440 bscv_rep_get8_locked(bscv_soft_state_t *ssp, int chan, uint8_t *host_addr, 1441 bscv_addr_t dev_addr, size_t repcount, uint_t flags, int *res) 1442 { 1443 bscv_enter(ssp); 1444 bscv_rep_rw8(ssp, chan, host_addr, dev_addr, repcount, 1445 flags, B_FALSE /* read */); 1446 bscv_locked_result(ssp, res); 1447 bscv_exit(ssp); 1448 } 1449 1450 static boolean_t 1451 bscv_faulty(bscv_soft_state_t *ssp) 1452 { 1453 ASSERT(bscv_held(ssp)); 1454 return (ssp->had_fault); 1455 } 1456 1457 static void 1458 bscv_clear_fault(bscv_soft_state_t *ssp) 1459 { 1460 ASSERT(bscv_held(ssp)); 1461 bscv_trace(ssp, 'J', "bscv_clear_fault", "clearing fault flag"); 1462 ssp->had_fault = B_FALSE; 1463 ssp->had_session_error = B_FALSE; 1464 } 1465 1466 static void 1467 bscv_set_fault(bscv_soft_state_t *ssp) 1468 { 1469 ASSERT(bscv_held(ssp)); 1470 bscv_trace(ssp, 'J', "bscv_set_fault", "setting fault flag"); 1471 ssp->had_fault = B_TRUE; 1472 } 1473 1474 static boolean_t 1475 bscv_session_error(bscv_soft_state_t *ssp) 1476 { 1477 ASSERT(bscv_held(ssp)); 1478 return (ssp->had_session_error); 1479 } 1480 1481 static int 1482 bscv_retcode(bscv_soft_state_t *ssp) 1483 { 1484 bscv_trace(ssp, '@', "bscv_retcode", 1485 "code 0x%x", ssp->command_error); 1486 return (ssp->command_error); 1487 } 1488 1489 static int 1490 bscv_should_retry(bscv_soft_state_t *ssp) 1491 { 1492 if ((ssp->command_error == EBUS_ERROR_DEVICEFAIL) || 1493 (ssp->command_error >= LOMBUS_ERR_BASE)) { 1494 /* This command is due to an I/O fault - retry might fix */ 1495 return (1); 1496 } else { 1497 /* 1498 * The command itself was bad - there is no point in fixing 1499 * Note. Whatever happens we should know that if we were 1500 * doing EBUS_IDX_SELFTEST0..EBUS_IDX_SELFTEST7 and we 1501 * had 0x80 set then this is a test error not a retry 1502 * error. 1503 */ 1504 return (0); 1505 } 1506 } 1507 1508 static void 1509 bscv_locked_result(bscv_soft_state_t *ssp, int *res) 1510 { 1511 if (bscv_faulty(ssp) || (bscv_retcode(ssp) != 0)) { 1512 *res = EIO; 1513 } 1514 } 1515 1516 static void 1517 bscv_put8_once(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr, uint8_t val) 1518 { 1519 uint32_t fault; 1520 1521 ASSERT(bscv_held(ssp)); 1522 1523 ssp->command_error = 0; 1524 1525 if (bscv_faulty(ssp)) { 1526 /* Bail out things are not working */ 1527 return; 1528 } else if (ssp->nchannels == 0) { 1529 /* Didn't manage to map handles so ddi_{get,put}* broken */ 1530 bscv_trace(ssp, '@', "bscv_put8_once", 1531 "nchannels is 0x0 so cannot do IO"); 1532 return; 1533 } 1534 1535 /* Clear any pending fault */ 1536 ddi_put32(ssp->channel[chan].handle, 1537 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG), 0); 1538 1539 /* Do the access and get fault code - may take a long time */ 1540 ddi_put8(ssp->channel[chan].handle, 1541 &ssp->channel[chan].regs[addr], val); 1542 fault = ddi_get32(ssp->channel[chan].handle, 1543 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG)); 1544 1545 ssp->command_error = fault; 1546 1547 if (fault == 0) { 1548 /* Things were ok - update cache entry */ 1549 if (addr < BSC_ADDR_CACHE_LIMIT) { 1550 /* Store cacheable entries */ 1551 ssp->lom_regs[addr] = val; 1552 } 1553 } else if (fault >= LOMBUS_ERR_BASE) { 1554 /* lombus problem - do a resync session */ 1555 cmn_err(CE_WARN, "!bscv_put8_once: Had comms fault " 1556 "for address 0x%x.%02x - data 0x%x, fault 0x%x", 1557 addr >> 8, addr & 0xff, val, fault); 1558 /* Attempt to resync with the lom */ 1559 bscv_resync_comms(ssp, chan); 1560 /* 1561 * Note: we do not set fault status here. That 1562 * is done if our caller decides to give up talking to 1563 * the lom. The observant might notice that this means 1564 * that if we mend things on the last attempt we still 1565 * get the fault set - we just live with that! 1566 */ 1567 } 1568 1569 bscv_trace(ssp, '@', "bscv_put8_once", 1570 "addr 0x%x.%02x <= 0x%02x", addr >> 8, addr & 0xff, val); 1571 } 1572 1573 static uint8_t 1574 bscv_get8_once(bscv_soft_state_t *ssp, int chan, bscv_addr_t addr) 1575 { 1576 uint8_t val; 1577 uint32_t fault; 1578 1579 ASSERT(bscv_held(ssp)); 1580 1581 ssp->command_error = 0; 1582 1583 if (bscv_faulty(ssp)) { 1584 /* Bail out things are not working */ 1585 return (0xff); 1586 } else if (ssp->nchannels == 0) { 1587 /* Didn't manage to map handles so ddi_{get,put}* broken */ 1588 bscv_trace(ssp, '@', "bscv_get8_once", 1589 "nchannels is 0x0 so cannot do IO"); 1590 return (0xff); 1591 } 1592 1593 /* Clear any pending fault */ 1594 ddi_put32(ssp->channel[chan].handle, 1595 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG), 0); 1596 1597 /* Do the access and get fault code - may take a long time */ 1598 val = ddi_get8(ssp->channel[chan].handle, 1599 &ssp->channel[chan].regs[addr]); 1600 fault = ddi_get32(ssp->channel[chan].handle, 1601 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG)); 1602 ssp->command_error = fault; 1603 1604 if (fault >= LOMBUS_ERR_BASE) { 1605 /* lombus problem - do a resync session */ 1606 cmn_err(CE_WARN, "!bscv_get8_once: Had comms fault " 1607 "for address 0x%x.%02x - data 0x%x, fault 0x%x", 1608 addr >> 8, addr & 0xff, val, fault); 1609 /* Attempt to resync with the lom */ 1610 bscv_resync_comms(ssp, chan); 1611 /* 1612 * Note: we do not set fault status here. That 1613 * is done if our caller decides to give up talking to 1614 * the lom. The observant might notice that this means 1615 * that if we mend things on the last attempt we still 1616 * get the fault set - we just live with that! 1617 */ 1618 } 1619 /* 1620 * FIXME - should report error if you get 1621 * EBUS_ERROR_DEVICEFAIL reported from the BSC. That gets 1622 * logged as a failure in bscv_should_retry and may contribute 1623 * to a permanent failure. Reference issues seen by Mitac. 1624 */ 1625 1626 if (!bscv_faulty(ssp)) { 1627 if (addr < BSC_ADDR_CACHE_LIMIT) { 1628 /* Store cacheable entries */ 1629 ssp->lom_regs[addr] = val; 1630 } 1631 } 1632 1633 bscv_trace(ssp, '@', "bscv_get8_once", 1634 "addr 0x%x.%02x => 0x%02x", addr >> 8, addr & 0xff, val); 1635 return (val); 1636 } 1637 1638 static uint32_t 1639 bscv_probe(bscv_soft_state_t *ssp, int chan, uint32_t *fault) 1640 { 1641 uint32_t async_reg; 1642 1643 if (ssp->nchannels == 0) { 1644 /* 1645 * Failed to map handles, so cannot do any IO. Set the 1646 * fault indicator and return a dummy value. 1647 */ 1648 bscv_trace(ssp, '@', "bscv_probe", 1649 "nchannels is 0x0 so cannot do any IO"); 1650 *fault = LOMBUS_ERR_REG_NUM; 1651 return ((~(int8_t)0)); 1652 } 1653 1654 /* Clear faults */ 1655 ddi_put32(ssp->channel[chan].handle, 1656 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_FAULT_REG), 0); 1657 /* Probe and Check faults */ 1658 *fault = ddi_get32(ssp->channel[chan].handle, 1659 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_PROBE_REG)); 1660 /* Read status */ 1661 async_reg = ddi_get32(ssp->channel[chan].handle, 1662 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, LOMBUS_ASYNC_REG)); 1663 1664 bscv_trace(ssp, '@', "bscv_probe", 1665 "async status 0x%x, fault 0x%x", async_reg, *fault); 1666 return (async_reg); 1667 } 1668 1669 static void 1670 bscv_resync_comms(bscv_soft_state_t *ssp, int chan) 1671 { 1672 int try; 1673 uint32_t command_error = ssp->command_error; 1674 uint32_t fault = 0; 1675 1676 if (ssp->nchannels == 0) { 1677 /* 1678 * Didn't manage to map handles so ddi_{get,put}* broken. 1679 * Therefore, there is no way to resync comms. 1680 */ 1681 bscv_trace(ssp, '@', "bscv_resync_comms", 1682 "nchannels is 0x0 so not possible to resync comms"); 1683 return; 1684 } 1685 if (command_error >= LOMBUS_ERR_BASE && 1686 command_error != LOMBUS_ERR_REG_NUM && 1687 command_error != LOMBUS_ERR_REG_SIZE && 1688 command_error != LOMBUS_ERR_TIMEOUT) { 1689 /* Resync here to make sure that the lom is talking */ 1690 cmn_err(CE_WARN, "!bscv_resync_comms: " 1691 "Attempting comms resync after comms fault 0x%x", 1692 command_error); 1693 for (try = 1; try <= 8; try++) { 1694 /* Probe */ 1695 fault = ddi_get32(ssp->channel[chan].handle, 1696 (uint32_t *)BSC_NEXUS_ADDR(ssp, chan, 0, 1697 LOMBUS_PROBE_REG)); 1698 1699 if (fault == 0) { 1700 break; 1701 } else { 1702 cmn_err(CE_WARN, "!bscv_resync_comms: " 1703 "comms resync (probing) - try 0x%x " 1704 "had fault 0x%x", try, fault); 1705 } 1706 } 1707 if (fault != 0) { 1708 cmn_err(CE_WARN, "!bscv_resync_comms: " 1709 "Failed to resync comms - giving up"); 1710 ssp->bad_resync++; 1711 } else { 1712 cmn_err(CE_WARN, "!bscv_resync_comms: " 1713 "resync comms after 0x%x tries", try); 1714 ssp->bad_resync = 0; 1715 } 1716 } 1717 1718 } 1719 1720 1721 /* 1722 * LOMLite configuration/event eeprom access routines 1723 * 1724 * bscv_window_setup() - Read/Sanity check the eeprom parameters. 1725 * This must be called prior to calling bscv_eerw(). 1726 * bscv_eerw() - Read/write data from/to the eeprom. 1727 */ 1728 1729 /* 1730 * function - bscv_window_setup 1731 * description - this routine reads the eeprom parameters and sanity 1732 * checks them to ensure that the lom is talking sense. 1733 * inputs - soft state ptr 1734 * outputs - B_TRUE if the eeprom is ok, B_FALSE if the eeprom is not OK. 1735 */ 1736 static boolean_t 1737 bscv_window_setup(bscv_soft_state_t *ssp) 1738 { 1739 ASSERT(bscv_held(ssp)); 1740 1741 if (ssp->eeinfo_valid) { 1742 /* Already have good cached values */ 1743 return (ssp->eeinfo_valid); 1744 } 1745 ssp->eeprom_size = 1746 bscv_get8(ssp, chan_general, EBUS_IDX_EEPROM_SIZE_KB) * 1024; 1747 ssp->eventlog_start = bscv_get16(ssp, chan_general, 1748 EBUS_IDX_LOG_START_HI); 1749 1750 /* 1751 * The log does not run to the end of the EEPROM because it is a 1752 * logical partition. The last 8K partition is reserved for FRUID 1753 * usage. 1754 */ 1755 ssp->eventlog_size = EBUS_LOG_END - ssp->eventlog_start; 1756 1757 bscv_trace(ssp, 'I', "bscv_window_setup", "eeprom size 0x%x log_start" 1758 " 0x%x log_size 0x%x", ssp->eeprom_size, ssp->eventlog_start, 1759 ssp->eventlog_size); 1760 1761 if (bscv_faulty(ssp) || bscv_session_error(ssp)) { 1762 ssp->eeinfo_valid = B_FALSE; 1763 } else if ((ssp->eeprom_size == 0) || 1764 (ssp->eventlog_start >= ssp->eeprom_size)) { 1765 /* Sanity check values */ 1766 cmn_err(CE_WARN, 1767 "!bscv_window_setup: read invalid eeprom parameters"); 1768 ssp->eeinfo_valid = B_FALSE; 1769 } else { 1770 ssp->eeinfo_valid = B_TRUE; 1771 } 1772 1773 bscv_trace(ssp, 'I', "bscv_window_setup", "returning eeinfo_valid %s", 1774 ssp->eeinfo_valid ? "true" : "false"); 1775 return (ssp->eeinfo_valid); 1776 } 1777 1778 /* 1779 * function - bscv_eerw 1780 * description - this routine reads/write data from/to the eeprom. 1781 * It takes care of setting the window on the eeprom correctly. 1782 * inputs - soft state ptr, eeprom offset, data buffer, size, read/write 1783 * outputs - B_TRUE if the eeprom is ok, B_FALSE if the eeprom is not OK. 1784 */ 1785 static int 1786 bscv_eerw(bscv_soft_state_t *ssp, uint32_t eeoffset, uint8_t *buf, 1787 unsigned size, boolean_t is_write) 1788 { 1789 uint32_t blk_addr = eeoffset; 1790 unsigned remaining = size; 1791 uint8_t page_idx; 1792 uint8_t this_page; 1793 uint8_t blk_size; 1794 int res = 0; 1795 1796 while (remaining > 0) { 1797 page_idx = blk_addr & 0xff; 1798 if ((page_idx + remaining) > 0x100) { 1799 blk_size = 0x100 - page_idx; 1800 } else { 1801 blk_size = remaining; 1802 } 1803 1804 /* Select correct eeprom page */ 1805 this_page = blk_addr >> 8; 1806 bscv_put8(ssp, chan_eeprom, EBUS_IDX_EEPROM_PAGESEL, this_page); 1807 1808 bscv_trace(ssp, 'M', "lom_eerw", 1809 "%s data @0x%x.%02x, size 0x%x, 0x%x bytes remaining", 1810 is_write ? "writing" : "reading", 1811 this_page, page_idx, blk_size, remaining - blk_size); 1812 1813 bscv_rep_rw8(ssp, chan_eeprom, 1814 buf, BSCVA(EBUS_CMD_SPACE_EEPROM, page_idx), 1815 blk_size, DDI_DEV_AUTOINCR, is_write); 1816 1817 if (bscv_faulty(ssp) || bscv_session_error(ssp)) { 1818 res = EIO; 1819 break; 1820 } 1821 1822 remaining -= blk_size; 1823 blk_addr += blk_size; 1824 buf += blk_size; 1825 } 1826 1827 return (res); 1828 } 1829 1830 static boolean_t 1831 bscv_is_null_event(bscv_soft_state_t *ssp, lom_event_t *e) 1832 { 1833 ASSERT(e != NULL); 1834 1835 if (EVENT_DECODE_SUBSYS(e->ev_subsys) == EVENT_SUBSYS_NONE && 1836 e->ev_event == EVENT_NONE) { 1837 /* 1838 * This marks a NULL event. 1839 */ 1840 bscv_trace(ssp, 'E', "bscv_is_null_event", 1841 "EVENT_SUBSYS_NONE/EVENT_NONE null event"); 1842 return (B_TRUE); 1843 } else if (e->ev_subsys == 0xff && e->ev_event == 0xff) { 1844 /* 1845 * Under some circumstances, we've seen all 1s to represent 1846 * a manually cleared event log at the BSC prompt. Only 1847 * a test/diagnosis environment is likely to show this. 1848 */ 1849 bscv_trace(ssp, 'E', "bscv_is_null_event", "0xffff null event"); 1850 return (B_TRUE); 1851 } else { 1852 /* 1853 * Not a NULL event. 1854 */ 1855 bscv_trace(ssp, 'E', "bscv_is_null_event", "returning False"); 1856 return (B_FALSE); 1857 } 1858 } 1859 1860 /* 1861 * ********************************************************************* 1862 * IOCTL Processing 1863 * ********************************************************************* 1864 */ 1865 1866 /* 1867 * function - bscv_ioctl 1868 * description - routine that acts as a high level manager for ioctls. It 1869 * calls the appropriate handler for ioctls on the alarm:mon and 1870 * alarm:ctl minor nodes respectively 1871 * 1872 * Unsupported ioctls (now deprecated) 1873 * LOMIOCALCTL 1874 * LOMIOCALSTATE 1875 * LOMIOCCLEARLOG 1876 * LOMIOCCTL 1877 * LOMIOCCTL2 1878 * LOMIOCDAEMON 1879 * LOMIOCDMON 1880 * LOMIOCDOGCTL, TSIOCDOGCTL 1881 * LOMIOCDOGPAT, TSIOCDOGPAT 1882 * LOMIOCDOGTIME, TSIOCDOGTIME 1883 * LOMIOCEVENTLOG 1884 * LOMIOCEVNT 1885 * LOMIOCGETMASK 1886 * LOMIOCMPROG 1887 * LOMIOCNBMON, TSIOCNBMON 1888 * LOMIOCSLEEP 1889 * LOMIOCUNLOCK, TSIOCUNLOCK 1890 * LOMIOCWTMON, TSIOCWTMON 1891 * 1892 * Supported ioctls 1893 * LOMIOCDOGSTATE, TSIOCDOGSTATE 1894 * LOMIOCPROG 1895 * LOMIOCPSUSTATE 1896 * LOMIOCFANSTATE 1897 * LOMIOCFLEDSTATE 1898 * LOMIOCINFO 1899 * LOMIOCMREAD 1900 * LOMIOCVOLTS 1901 * LOMIOCSTATS 1902 * LOMIOCTEMP 1903 * LOMIOCCONS 1904 * LOMIOCEVENTLOG2 1905 * LOMIOCINFO2 1906 * LOMIOCTEST 1907 * LOMIOCMPROG2 1908 * LOMIOCMREAD2 1909 * 1910 * inputs - device number, command, user space arg, filemode, user 1911 * credentials, return value 1912 * outputs - the return value propagated back by the lower level routines. 1913 */ 1914 1915 /*ARGSUSED*/ 1916 static int 1917 bscv_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred, int *rvalp) 1918 { 1919 bscv_soft_state_t *ssp; 1920 int instance; 1921 int res = 0; 1922 1923 instance = DEVICETOINSTANCE(dev); 1924 ssp = ddi_get_soft_state(bscv_statep, instance); 1925 if (ssp == NULL) { 1926 return (ENXIO); 1927 } 1928 1929 /* 1930 * The Combined Switch and Service Processor takes care of configuration 1931 * and control. The CSSP tells the BSC chip about it; therefore the 1932 * bscv driver doesn't send such configuration and control to the BSC. 1933 * Additionally Watchdog configuration is no longer done from userland 1934 * lom. 1935 */ 1936 switch (cmd) { 1937 case LOMIOCALCTL: 1938 case LOMIOCALSTATE: 1939 case LOMIOCCLEARLOG: 1940 case LOMIOCCTL: 1941 case LOMIOCCTL2: 1942 case LOMIOCDAEMON: 1943 case LOMIOCDMON: 1944 case LOMIOCDOGCTL: 1945 case LOMIOCDOGPAT: 1946 case LOMIOCDOGTIME: 1947 case LOMIOCEVENTLOG: 1948 case LOMIOCEVNT: 1949 case LOMIOCGETMASK: 1950 case LOMIOCMPROG: 1951 case LOMIOCNBMON: 1952 case LOMIOCSLEEP: 1953 case LOMIOCUNLOCK: 1954 case LOMIOCWTMON: 1955 return (ENOTSUP); 1956 } 1957 1958 /* 1959 * set the default result. 1960 */ 1961 1962 *rvalp = 0; 1963 1964 if (ssp->cssp_prog) { 1965 return (ENXIO); 1966 } else if ((ssp->prog_mode_only || ssp->programming) && 1967 cmd != LOMIOCPROG) { 1968 return (ENXIO); 1969 } 1970 1971 /* 1972 * Check that the caller has appropriate access permissions 1973 * (FWRITE set in mode) for those ioctls which change lom 1974 * state 1975 */ 1976 if (!(mode & FWRITE)) { 1977 switch (cmd) { 1978 case LOMIOCMPROG2: 1979 case LOMIOCMREAD2: 1980 case LOMIOCPROG: 1981 case LOMIOCTEST: 1982 return (EACCES); 1983 /* NOTREACHED */ 1984 default: 1985 /* Does not require write access */ 1986 break; 1987 } 1988 } 1989 1990 switch (cmd) { 1991 1992 case LOMIOCDOGSTATE: 1993 res = bscv_ioc_dogstate(ssp, arg, mode); 1994 break; 1995 1996 case LOMIOCPROG: 1997 res = bscv_prog(ssp, arg, mode); 1998 break; 1999 2000 case LOMIOCPSUSTATE: 2001 res = bscv_ioc_psustate(ssp, arg, mode); 2002 break; 2003 2004 case LOMIOCFANSTATE: 2005 res = bscv_ioc_fanstate(ssp, arg, mode); 2006 break; 2007 2008 case LOMIOCFLEDSTATE: 2009 res = bscv_ioc_fledstate(ssp, arg, mode); 2010 break; 2011 2012 case LOMIOCLEDSTATE: 2013 res = bscv_ioc_ledstate(ssp, arg, mode); 2014 break; 2015 2016 case LOMIOCINFO: 2017 res = bscv_ioc_info(ssp, arg, mode); 2018 break; 2019 2020 case LOMIOCMREAD: 2021 res = bscv_ioc_mread(ssp, arg, mode); 2022 break; 2023 2024 case LOMIOCVOLTS: 2025 res = bscv_ioc_volts(ssp, arg, mode); 2026 break; 2027 2028 case LOMIOCSTATS: 2029 res = bscv_ioc_stats(ssp, arg, mode); 2030 break; 2031 2032 case LOMIOCTEMP: 2033 res = bscv_ioc_temp(ssp, arg, mode); 2034 break; 2035 2036 case LOMIOCCONS: 2037 res = bscv_ioc_cons(ssp, arg, mode); 2038 break; 2039 2040 case LOMIOCEVENTLOG2: 2041 res = bscv_ioc_eventlog2(ssp, arg, mode); 2042 break; 2043 2044 case LOMIOCINFO2: 2045 res = bscv_ioc_info2(ssp, arg, mode); 2046 break; 2047 2048 case LOMIOCTEST: 2049 res = bscv_ioc_test(ssp, arg, mode); 2050 break; 2051 2052 case LOMIOCMPROG2: 2053 res = bscv_ioc_mprog2(ssp, arg, mode); 2054 break; 2055 2056 case LOMIOCMREAD2: 2057 res = bscv_ioc_mread2(ssp, arg, mode); 2058 break; 2059 2060 default: 2061 bscv_trace(ssp, 'I', "bscv_ioctl", "Invalid IOCTL 0x%x", cmd); 2062 res = EINVAL; 2063 } 2064 return (res); 2065 } 2066 2067 /* 2068 * LOMIOCDOGSTATE 2069 * TSIOCDOGSTATE - indicate whether the alarm watchdog and reset 2070 * circuitry is enabled or not. 2071 */ 2072 static int 2073 bscv_ioc_dogstate(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2074 { 2075 lom_dogstate_t dogstate; 2076 uint8_t dogval; 2077 int res = 0; 2078 2079 dogval = bscv_get8_locked(ssp, chan_general, EBUS_IDX_WDOG_CTRL, &res); 2080 dogstate.dog_enable = (dogval & EBUS_WDOG_ENABLE) ? 1 : 0; 2081 dogstate.reset_enable = (dogval & EBUS_WDOG_RST) ? 1 : 0; 2082 dogstate.dog_timeout = bscv_get8_locked(ssp, chan_general, 2083 EBUS_IDX_WDOG_TIME, &res); 2084 2085 if ((res == 0) && 2086 (ddi_copyout((caddr_t)&dogstate, 2087 (caddr_t)arg, sizeof (dogstate), mode) < 0)) { 2088 res = EFAULT; 2089 } 2090 return (res); 2091 } 2092 2093 /* 2094 * LOMIOCPSUSTATE - returns full information for 4 PSUs. All this 2095 * information is available from two bytes of LOMlite RAM, but if 2096 * on the first read it is noticed that two or more of the PSUs are 2097 * not present only 1 byte will be read subsequently. 2098 */ 2099 static int 2100 bscv_ioc_psustate(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2101 { 2102 lom_psudata_t psudata; 2103 uint8_t psustat; 2104 int i; 2105 int res = 0; 2106 2107 for (i = 0; i < MAX_PSUS; i++) { 2108 psustat = bscv_get8_locked(ssp, chan_general, 2109 EBUS_IDX_PSU1_STAT + i, &res); 2110 psudata.fitted[i] = psustat & EBUS_PSU_PRESENT; 2111 psudata.output[i] = psustat & EBUS_PSU_OUTPUT; 2112 psudata.supplyb[i] = psustat & EBUS_PSU_INPUTB; 2113 psudata.supplya[i] = psustat & EBUS_PSU_INPUTA; 2114 psudata.standby[i] = psustat & EBUS_PSU_STANDBY; 2115 } 2116 2117 if (ddi_copyout((caddr_t)&psudata, (caddr_t)arg, sizeof (psudata), 2118 mode) < 0) { 2119 res = EFAULT; 2120 } 2121 return (res); 2122 } 2123 2124 /* 2125 * LOMIOCFANSTATE - returns full information including speed for 4 2126 * fans and the minimum and maximum operating speeds for each fan as 2127 * stored in the READ ONLY EEPROM data. As this EEPROM data is set 2128 * at manufacture time, this data should only be read by the driver 2129 * once and stored locally. 2130 */ 2131 static int 2132 bscv_ioc_fanstate(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2133 { 2134 lom_fandata_t fandata; 2135 int numfans; 2136 int i; 2137 int res = 0; 2138 2139 bzero(&fandata, sizeof (lom_fandata_t)); 2140 numfans = EBUS_CONFIG_NFAN_DEC(bscv_get8_locked(ssp, 2141 chan_general, EBUS_IDX_CONFIG, &res)); 2142 for (i = 0; (i < numfans) && (res == 0); i++) { 2143 if (ssp->fanspeed[i] != LOM_FAN_NOT_PRESENT) { 2144 fandata.fitted[i] = 1; 2145 fandata.speed[i] = ssp->fanspeed[i]; 2146 fandata.minspeed[i] = bscv_get8_cached(ssp, 2147 EBUS_IDX_FAN1_LOW + i); 2148 } 2149 } 2150 2151 if ((res == 0) && 2152 (ddi_copyout((caddr_t)&fandata, (caddr_t)arg, sizeof (fandata), 2153 mode) < 0)) { 2154 res = EFAULT; 2155 } 2156 return (res); 2157 } 2158 2159 /* 2160 * LOMIOCFLEDSTATE - returns the state of the fault LED 2161 */ 2162 static int 2163 bscv_ioc_fledstate(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2164 { 2165 lom_fled_info_t fled_info; 2166 uint8_t fledstate; 2167 int res = 0; 2168 2169 fledstate = bscv_get8_locked(ssp, chan_general, EBUS_IDX_ALARM, &res); 2170 2171 /* Decode of 0x0F is off and 0x00-0x07 is on. */ 2172 if (EBUS_ALARM_LED_DEC(fledstate) == 0x0F) { 2173 fled_info.on = 0; 2174 } else { 2175 /* has +1 here - not 2 as in the info ioctl */ 2176 fled_info.on = EBUS_ALARM_LED_DEC(fledstate) + 1; 2177 } 2178 if ((res == 0) && 2179 (ddi_copyout((caddr_t)&fled_info, (caddr_t)arg, 2180 sizeof (fled_info), mode) < 0)) { 2181 res = EFAULT; 2182 } 2183 return (res); 2184 } 2185 2186 /* 2187 * LOMIOCLEDSTATE - returns the state of the requested LED 2188 */ 2189 static int 2190 bscv_ioc_ledstate(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2191 { 2192 lom_led_state_t led_state; 2193 int fw_led_state; 2194 int res = 0; 2195 2196 /* copy in arguments supplied */ 2197 if (ddi_copyin((caddr_t)arg, (caddr_t)&led_state, 2198 sizeof (lom_led_state_t), mode) < 0) { 2199 return (EFAULT); 2200 } 2201 2202 /* 2203 * check if led index is -1, if so set it to max value for 2204 * this implementation. 2205 */ 2206 if (led_state.index == -1) { 2207 led_state.index = MAX_LED_ID; 2208 } 2209 2210 /* is the index in a valid range */ 2211 if ((led_state.index > MAX_LED_ID) || (led_state.index < 0)) { 2212 led_state.state = LOM_LED_OUTOFRANGE; 2213 } else { 2214 /* read the relevant led info */ 2215 fw_led_state = bscv_get8_locked(ssp, chan_general, 2216 EBUS_IDX_LED1_STATUS + led_state.index, &res); 2217 2218 /* set the state values accordingly */ 2219 switch (fw_led_state) { 2220 case LOM_LED_STATE_OFF: 2221 led_state.state = LOM_LED_OFF; 2222 led_state.colour = LOM_LED_COLOUR_ANY; 2223 break; 2224 case LOM_LED_STATE_ON_STEADY: 2225 led_state.state = LOM_LED_ON; 2226 led_state.colour = LOM_LED_COLOUR_ANY; 2227 break; 2228 case LOM_LED_STATE_ON_FLASHING: 2229 case LOM_LED_STATE_ON_SLOWFLASH: 2230 led_state.state = LOM_LED_BLINKING; 2231 led_state.colour = LOM_LED_COLOUR_ANY; 2232 break; 2233 case LOM_LED_STATE_NOT_PRESENT: 2234 led_state.state = LOM_LED_NOT_IMPLEMENTED; 2235 led_state.colour = LOM_LED_COLOUR_NONE; 2236 break; 2237 case LOM_LED_STATE_INACCESSIBLE: 2238 case LOM_LED_STATE_STANDBY: 2239 default: 2240 led_state.state = LOM_LED_ACCESS_ERROR; 2241 led_state.colour = LOM_LED_COLOUR_NONE; 2242 break; 2243 } 2244 2245 /* set the label info */ 2246 (void) strcpy(led_state.label, 2247 ssp->led_names[led_state.index]); 2248 } 2249 2250 /* copy out lom_state */ 2251 if ((res == 0) && 2252 (ddi_copyout((caddr_t)&led_state, (caddr_t)arg, 2253 sizeof (lom_led_state_t), mode) < 0)) { 2254 res = EFAULT; 2255 } 2256 return (res); 2257 } 2258 2259 /* 2260 * LOMIOCINFO - returns with a structure containing any information 2261 * stored on the LOMlite which a user should not need to access but 2262 * may be useful for diagnostic problems. The structure contains: the 2263 * serial escape character, alarm3 mode, version and checksum read from 2264 * RAM and the Product revision and ID read from EEPROM. 2265 */ 2266 static int 2267 bscv_ioc_info(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2268 { 2269 lom_info_t info; 2270 int i; 2271 uint16_t csum; 2272 int res = 0; 2273 2274 info.ser_char = bscv_get8_locked(ssp, chan_general, EBUS_IDX_ESCAPE, 2275 &res); 2276 info.a3mode = WATCHDOG; 2277 info.fver = bscv_get8_locked(ssp, chan_general, EBUS_IDX_FW_REV, &res); 2278 csum = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_HI, &res) 2279 << 8; 2280 csum |= bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_LO, &res); 2281 info.fchksum = csum; 2282 info.prod_rev = bscv_get8_locked(ssp, chan_general, EBUS_IDX_MODEL_REV, 2283 &res); 2284 for (i = 0; i < sizeof (info.prod_id); i++) { 2285 info.prod_id[i] = bscv_get8_locked(ssp, 2286 chan_general, EBUS_IDX_MODEL_ID1 + i, &res); 2287 } 2288 if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_ALARM, &res) & 2289 EBUS_ALARM_NOEVENTS) { 2290 info.events = OFF; 2291 } else { 2292 info.events = ON; 2293 } 2294 2295 if ((res == 0) && 2296 (ddi_copyout((caddr_t)&info, (caddr_t)arg, sizeof (info), 2297 mode) < 0)) { 2298 res = EFAULT; 2299 } 2300 return (res); 2301 } 2302 2303 /* 2304 * LOMIOCMREAD - used to query the LOMlite configuration parameters 2305 */ 2306 static int 2307 bscv_ioc_mread(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2308 { 2309 lom_mprog_t mprog; 2310 int i; 2311 int fanz; 2312 int res = 0; 2313 2314 for (i = 0; i < sizeof (mprog.mod_id); i++) { 2315 mprog.mod_id[i] = bscv_get8_locked(ssp, chan_general, 2316 EBUS_IDX_MODEL_ID1 + i, &res); 2317 } 2318 mprog.mod_rev = bscv_get8_locked(ssp, chan_general, EBUS_IDX_MODEL_REV, 2319 &res); 2320 mprog.config = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CONFIG, 2321 &res); 2322 2323 /* Read the fan calibration values */ 2324 fanz = sizeof (mprog.fanhz) / sizeof (mprog.fanhz[0]); 2325 for (i = 0; i < fanz; i++) { 2326 mprog.fanhz[i] = bscv_get8_cached(ssp, 2327 EBUS_IDX_FAN1_CAL + i); 2328 mprog.fanmin[i] = bscv_get8_cached(ssp, 2329 EBUS_IDX_FAN1_LOW + i); 2330 } 2331 2332 if ((res == 0) && 2333 (ddi_copyout((caddr_t)&mprog, (caddr_t)arg, sizeof (mprog), 2334 mode) < 0)) { 2335 res = EFAULT; 2336 } 2337 return (res); 2338 } 2339 2340 /* 2341 * LOMIOCVOLTS 2342 */ 2343 static int 2344 bscv_ioc_volts(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2345 { 2346 int i; 2347 uint16_t supply; 2348 int res = 0; 2349 2350 supply = (bscv_get8_locked(ssp, chan_general, EBUS_IDX_SUPPLY_HI, &res) 2351 << 8) | bscv_get8_locked(ssp, chan_general, EBUS_IDX_SUPPLY_LO, 2352 &res); 2353 2354 for (i = 0; i < ssp->volts.num; i++) { 2355 ssp->volts.status[i] = (supply >> i) & 1; 2356 } 2357 2358 if ((res == 0) && 2359 (ddi_copyout((caddr_t)&ssp->volts, (caddr_t)arg, 2360 sizeof (ssp->volts), mode) < 0)) { 2361 res = EFAULT; 2362 } 2363 return (res); 2364 } 2365 2366 /* 2367 * LOMIOCSTATS 2368 */ 2369 static int 2370 bscv_ioc_stats(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2371 { 2372 int i; 2373 uint8_t status; 2374 int res = 0; 2375 2376 status = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CBREAK_STATUS, 2377 &res); 2378 for (i = 0; i < ssp->sflags.num; i++) { 2379 ssp->sflags.status[i] = (int)((status >> i) & 1); 2380 } 2381 2382 if ((res == 0) && 2383 (ddi_copyout((caddr_t)&ssp->sflags, (caddr_t)arg, 2384 sizeof (ssp->sflags), mode) < 0)) { 2385 res = EFAULT; 2386 } 2387 return (res); 2388 } 2389 2390 /* 2391 * LOMIOCTEMP 2392 */ 2393 static int 2394 bscv_ioc_temp(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2395 { 2396 int i; 2397 int idx; 2398 uint8_t status_ov; 2399 lom_temp_t temps; 2400 int res = 0; 2401 2402 bzero(&temps, sizeof (temps)); 2403 idx = 0; 2404 for (i = 0; i < ssp->temps.num; i++) { 2405 if (ssp->temps.temp[i] != LOM_TEMP_STATE_NOT_PRESENT) { 2406 temps.temp[idx] = ssp->temps.temp[i]; 2407 bcopy(ssp->temps.name[i], temps.name[idx], 2408 sizeof (temps.name[idx])); 2409 temps.warning[idx] = ssp->temps.warning[i]; 2410 temps.shutdown[idx] = ssp->temps.shutdown[i]; 2411 idx++; 2412 } 2413 } 2414 temps.num = idx; 2415 2416 bcopy(ssp->temps.name_ov, temps.name_ov, sizeof (temps.name_ov)); 2417 temps.num_ov = ssp->temps.num_ov; 2418 status_ov = bscv_get8_locked(ssp, chan_general, EBUS_IDX_OTEMP_STATUS, 2419 &res); 2420 for (i = 0; i < ssp->temps.num_ov; i++) { 2421 ssp->temps.status_ov[i] = (status_ov >> i) & 1; 2422 } 2423 2424 if ((res == 0) && 2425 (ddi_copyout((caddr_t)&temps, (caddr_t)arg, sizeof (temps), 2426 mode) < 0)) { 2427 res = EFAULT; 2428 } 2429 return (res); 2430 } 2431 2432 /* 2433 * LOMIOCCONS 2434 */ 2435 static int 2436 bscv_ioc_cons(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2437 { 2438 lom_cbuf_t cbuf; 2439 int datasize; 2440 int res = 0; 2441 2442 bzero(&cbuf, sizeof (cbuf)); 2443 datasize = EBUS_IDX1_CONS_BUF_END - EBUS_IDX1_CONS_BUF_START + 1; 2444 /* Ensure that we do not overfill cbuf and that it is NUL terminated */ 2445 if (datasize > (sizeof (cbuf) - 1)) { 2446 datasize = sizeof (cbuf) - 1; 2447 } 2448 bscv_rep_get8_locked(ssp, chan_general, (uint8_t *)cbuf.lrbuf, 2449 BSCVA(EBUS_CMD_SPACE1, (EBUS_IDX1_CONS_BUF_END - datasize + 1)), 2450 datasize, DDI_DEV_AUTOINCR, &res); 2451 /* This is always within the array due to the checks above */ 2452 cbuf.lrbuf[datasize] = '\0'; 2453 2454 if ((res == 0) && 2455 (ddi_copyout((caddr_t)&cbuf, (caddr_t)arg, sizeof (cbuf), 2456 mode) < 0)) { 2457 res = EFAULT; 2458 } 2459 return (res); 2460 } 2461 2462 /* 2463 * LOMIOCEVENTLOG2 2464 */ 2465 static int 2466 bscv_ioc_eventlog2(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2467 { 2468 lom_eventlog2_t *eventlog2; 2469 int events_recorded; 2470 int level; 2471 uint16_t next_offset; 2472 lom_event_t event; 2473 int res = 0; 2474 2475 eventlog2 = (lom_eventlog2_t *)kmem_zalloc(sizeof (*eventlog2), 2476 KM_SLEEP); 2477 2478 /* 2479 * First get number of events and level requested. 2480 */ 2481 2482 if (ddi_copyin((caddr_t)arg, (caddr_t)eventlog2, 2483 sizeof (lom_eventlog2_t), mode) < 0) { 2484 kmem_free((void *)eventlog2, sizeof (*eventlog2)); 2485 return (EFAULT); 2486 } 2487 2488 bscv_enter(ssp); 2489 2490 /* 2491 * OK we have full private access to the LOM now so loop 2492 * over the eventlog addr spaces until we get the required 2493 * number of events. 2494 */ 2495 2496 if (!bscv_window_setup(ssp)) { 2497 res = EIO; 2498 bscv_exit(ssp); 2499 kmem_free((void *)eventlog2, sizeof (*eventlog2)); 2500 return (res); 2501 } 2502 2503 /* 2504 * Read count, next event ptr MSB,LSB. Note a read of count 2505 * is necessary to latch values for the next event ptr 2506 */ 2507 (void) bscv_get8(ssp, chan_general, EBUS_IDX_UNREAD_EVENTS); 2508 next_offset = bscv_get16(ssp, chan_general, EBUS_IDX_LOG_PTR_HI); 2509 bscv_trace(ssp, 'I', "bscv_ioc_eventlog2", "log_ptr_hi 0x%x", 2510 next_offset); 2511 2512 events_recorded = 0; 2513 2514 while (events_recorded < eventlog2->num) { 2515 /* 2516 * Working backwards - read an event at a time. 2517 * next_offset is one event on from where we want to be! 2518 * Decrement next_offset and maybe wrap to the end of the 2519 * buffer. 2520 * Note the unsigned arithmetic, so check values first! 2521 */ 2522 if (next_offset <= ssp->eventlog_start) { 2523 /* Wrap to the end of the buffer */ 2524 next_offset = ssp->eventlog_start + ssp->eventlog_size; 2525 bscv_trace(ssp, 'I', "bscv_ioc_eventlog2", "wrapping" 2526 " around to end of buffer; next_offset 0x%x", 2527 next_offset); 2528 } 2529 next_offset -= sizeof (event); 2530 2531 if (bscv_eerw(ssp, next_offset, (uint8_t *)&event, 2532 sizeof (event), B_FALSE /* read */) != 0) { 2533 /* Fault reading data - stop */ 2534 bscv_trace(ssp, 'I', "bscv_ioc_eventlog2", "read" 2535 " failure for offset 0x%x", next_offset); 2536 res = EIO; 2537 break; 2538 } 2539 2540 if (bscv_is_null_event(ssp, &event)) { 2541 /* 2542 * No more events in this log so give up. 2543 */ 2544 bscv_trace(ssp, 'I', "bscv_ioc_eventlog2", "no more" 2545 " events left at offset 0x%x", next_offset); 2546 break; 2547 } 2548 2549 /* 2550 * Are we interested in this event 2551 */ 2552 2553 level = bscv_level_of_event(&event); 2554 if (level <= eventlog2->level) { 2555 /* Arggh why the funny byte ordering 3, 2, 0, 1 */ 2556 eventlog2->code[events_recorded] = 2557 ((unsigned)event.ev_event | 2558 ((unsigned)event.ev_subsys << 8) | 2559 ((unsigned)event.ev_resource << 16) | 2560 ((unsigned)event.ev_detail << 24)); 2561 2562 eventlog2->time[events_recorded] = 2563 ((unsigned)event.ev_data[0] | 2564 ((unsigned)event.ev_data[1] << 8) | 2565 ((unsigned)event.ev_data[3] << 16) | 2566 ((unsigned)event.ev_data[2] << 24)); 2567 2568 bscv_build_eventstring(ssp, 2569 &event, eventlog2->string[events_recorded], 2570 eventlog2->string[events_recorded] + 2571 sizeof (eventlog2->string[events_recorded])); 2572 events_recorded++; 2573 } 2574 } 2575 2576 eventlog2->num = events_recorded; 2577 2578 bscv_exit(ssp); 2579 2580 if ((res == 0) && 2581 (ddi_copyout((caddr_t)eventlog2, (caddr_t)arg, 2582 sizeof (lom_eventlog2_t), mode) < 0)) { 2583 res = EFAULT; 2584 } 2585 2586 kmem_free((void *)eventlog2, sizeof (lom_eventlog2_t)); 2587 return (res); 2588 } 2589 2590 /* 2591 * LOMIOCINFO2 2592 */ 2593 static int 2594 bscv_ioc_info2(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2595 { 2596 lom2_info_t info2; 2597 int i; 2598 uint16_t csum; 2599 int res = 0; 2600 2601 bzero(&info2, sizeof (info2)); 2602 2603 (void) strncpy(info2.escape_chars, ssp->escape_chars, 2604 sizeof (info2.escape_chars)); 2605 info2.serial_events = ssp->reporting_level | ssp->serial_reporting; 2606 info2.a3mode = WATCHDOG; 2607 2608 info2.fver = bscv_get8_locked(ssp, chan_general, EBUS_IDX_FW_REV, &res); 2609 csum = bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_HI, &res) 2610 << 8; 2611 csum |= bscv_get8_locked(ssp, chan_general, EBUS_IDX_CHECK_LO, &res); 2612 info2.fchksum = csum; 2613 info2.prod_rev = bscv_get8_locked(ssp, chan_general, 2614 EBUS_IDX_MODEL_REV, &res); 2615 for (i = 0; i < sizeof (info2.prod_id); i++) { 2616 info2.prod_id[i] = bscv_get8_locked(ssp, chan_general, 2617 EBUS_IDX_MODEL_ID1 + i, &res); 2618 } 2619 info2.serial_config = bscv_get8_locked(ssp, chan_general, 2620 EBUS_IDX_SER_TIMEOUT, &res); 2621 if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_CONFIG_MISC, &res) & 2622 EBUS_CONFIG_MISC_SECURITY_ENABLED) { 2623 info2.serial_config |= LOM_SER_SECURITY; 2624 } 2625 if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_CONFIG_MISC, &res) & 2626 EBUS_CONFIG_MISC_AUTO_CONSOLE) { 2627 info2.serial_config |= LOM_SER_RETURN; 2628 } 2629 if (bscv_get8_locked(ssp, chan_general, EBUS_IDX_WDOG_CTRL, &res) & 2630 EBUS_WDOG_BREAK_DISABLE) { 2631 info2.serial_config |= LOM_DISABLE_WDOG_BREAK; 2632 } 2633 info2.baud_rate = bscv_get8_locked(ssp, chan_general, 2634 EBUS_IDX_SER_BAUD, &res); 2635 info2.serial_hw_config = 2636 ((int)bscv_get8_locked(ssp, chan_general, 2637 EBUS_IDX_SER_CHARMODE, &res) | 2638 ((int)bscv_get8_locked(ssp, chan_general, 2639 EBUS_IDX_SER_FLOWCTL, &res) << 8) | 2640 ((int)bscv_get8_locked(ssp, chan_general, 2641 EBUS_IDX_SER_MODEMTYPE, &res) << 16)); 2642 2643 /* 2644 * There is no phone home support on the blade platform. We hardcode 2645 * FALSE and NUL for config and script respectively. 2646 */ 2647 info2.phone_home_config = B_FALSE; 2648 info2.phone_home_script[0] = '\0'; 2649 2650 for (i = 0; i < ssp->num_fans; i++) { 2651 (void) strcpy(info2.fan_names[i], ssp->fan_names[i]); 2652 } 2653 2654 if ((res == 0) && 2655 (ddi_copyout((caddr_t)&info2, (caddr_t)arg, sizeof (info2), 2656 mode) < 0)) { 2657 res = EFAULT; 2658 } 2659 return (res); 2660 } 2661 2662 /* 2663 * LOMIOCTEST 2664 */ 2665 static int 2666 bscv_ioc_test(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2667 { 2668 uint32_t test; 2669 uint8_t testnum; 2670 uint8_t testarg; 2671 int res = 0; 2672 2673 if (ddi_copyin((caddr_t)arg, (caddr_t)&test, sizeof (test), 2674 mode) < 0) { 2675 return (EFAULT); 2676 } 2677 2678 /* 2679 * Extract num iterations. 2680 */ 2681 2682 testarg = (test & 0xff00) >> 8; 2683 testnum = test & 0xff; 2684 2685 bscv_trace(ssp, 'F', "bscv_ioc_test", 2686 "LOMIOCTEST data 0x%x (test 0x%x, arg 0x%x)", 2687 test, (EBUS_IDX_SELFTEST0 + testnum), testarg); 2688 2689 switch (testnum + EBUS_IDX_SELFTEST0) { 2690 default: 2691 /* Invalid test */ 2692 res = EINVAL; 2693 break; 2694 2695 case EBUS_IDX_SELFTEST0: /* power on self-test result */ 2696 case EBUS_IDX_SELFTEST1: /* not used currently */ 2697 case EBUS_IDX_SELFTEST2: /* not used currently */ 2698 case EBUS_IDX_SELFTEST3: /* not used currently */ 2699 case EBUS_IDX_SELFTEST4: /* not used currently */ 2700 case EBUS_IDX_SELFTEST5: /* not used currently */ 2701 case EBUS_IDX_SELFTEST6: /* LED self-test */ 2702 case EBUS_IDX_SELFTEST7: /* platform-specific tests */ 2703 /* Run the test */ 2704 2705 /* Stop other things and then run the test */ 2706 bscv_enter(ssp); 2707 2708 /* 2709 * Then we simply write the argument to the relevant register 2710 * and wait for the return code. 2711 */ 2712 bscv_put8(ssp, chan_general, 2713 EBUS_IDX_SELFTEST0 + testnum, testarg); 2714 if (bscv_faulty(ssp)) { 2715 res = EIO; 2716 } else { 2717 /* Get hold of the SunVTS error code */ 2718 test = bscv_retcode(ssp); 2719 } 2720 2721 bscv_exit(ssp); 2722 break; 2723 } 2724 2725 bscv_trace(ssp, 'F', "bscv_ioc_test", 2726 "LOMIOCTEST status 0x%x, res 0x%x", test, res); 2727 if ((res == 0) && 2728 (ddi_copyout((caddr_t)&test, (caddr_t)arg, sizeof (test), 2729 mode) < 0)) { 2730 res = EFAULT; 2731 } 2732 return (res); 2733 } 2734 2735 /* 2736 * LOMIOCMPROG2 2737 */ 2738 static int 2739 bscv_ioc_mprog2(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2740 { 2741 lom2_mprog_t mprog2; 2742 uint32_t base_addr; 2743 uint32_t data_size; 2744 uint32_t eeprom_size; 2745 int res = 0; 2746 2747 if (ddi_copyin((caddr_t)arg, (caddr_t)&mprog2, sizeof (mprog2), 2748 mode) < 0) { 2749 return (EFAULT); 2750 } 2751 2752 /* 2753 * Note that originally this was accessed as 255 byte pages 2754 * in address spaces 240-255. We have to emulate this behaviour. 2755 */ 2756 if ((mprog2.addr_space < 240) || (mprog2.addr_space > 255)) { 2757 return (EINVAL); 2758 } 2759 2760 bscv_enter(ssp); 2761 2762 /* Calculate required data location */ 2763 data_size = 255; 2764 base_addr = (mprog2.addr_space - 240) * data_size; 2765 2766 eeprom_size = bscv_get8(ssp, chan_general, EBUS_IDX_EEPROM_SIZE_KB) * 2767 1024; 2768 2769 if (bscv_faulty(ssp)) { 2770 bscv_exit(ssp); 2771 return (EIO); 2772 } else if ((base_addr + data_size) > eeprom_size) { 2773 bscv_trace(ssp, 'M', "bscv_ioc_mprog2", 2774 "Request extends past end of eeprom"); 2775 bscv_exit(ssp); 2776 return (ENXIO); 2777 } 2778 2779 bscv_put8(ssp, chan_general, EBUS_IDX_CMD_RES, EBUS_CMD_UNLOCK1); 2780 if (bscv_faulty(ssp)) { 2781 bscv_trace(ssp, 'M', "bscv_ioc_mprog2", "ML1 Write failed"); 2782 bscv_exit(ssp); 2783 return (EIO); 2784 } 2785 2786 bscv_put8(ssp, chan_general, EBUS_IDX_CMD_RES, EBUS_CMD_UNLOCK2); 2787 if (bscv_faulty(ssp)) { 2788 bscv_trace(ssp, 'M', "bscv_ioc_mprog2", "ML2 Write failed"); 2789 bscv_exit(ssp); 2790 return (EIO); 2791 } 2792 2793 if (bscv_eerw(ssp, base_addr, &mprog2.data[0], 2794 data_size, B_TRUE /* write */) != 0) { 2795 res = EIO; 2796 } 2797 2798 /* Read a probe key to release the lock. */ 2799 (void) bscv_get8(ssp, chan_general, EBUS_IDX_PROBEAA); 2800 2801 if (bscv_faulty(ssp)) { 2802 res = EIO; 2803 } 2804 bscv_exit(ssp); 2805 2806 return (res); 2807 } 2808 2809 /* 2810 * LOMIOCMREAD2 2811 */ 2812 static int 2813 bscv_ioc_mread2(bscv_soft_state_t *ssp, intptr_t arg, int mode) 2814 { 2815 lom2_mprog_t mprog2; 2816 uint32_t base_addr; 2817 uint32_t data_size; 2818 uint32_t eeprom_size; 2819 int res = 0; 2820 2821 if (ddi_copyin((caddr_t)arg, (caddr_t)&mprog2, sizeof (mprog2), 2822 mode) < 0) { 2823 return (EFAULT); 2824 } 2825 2826 /* 2827 * Need to stop the queue and then just read 2828 * the bytes blind to the relevant addresses. 2829 * Note that originally this was accessed as 255 byte pages 2830 * in address spaces 240-255. We have to emulate this behaviour. 2831 */ 2832 if ((mprog2.addr_space < 240) || (mprog2.addr_space > 255)) { 2833 return (EINVAL); 2834 } 2835 2836 bscv_enter(ssp); 2837 2838 /* Calculate required data location */ 2839 data_size = 255; 2840 base_addr = (mprog2.addr_space - 240) * data_size; 2841 eeprom_size = bscv_get8(ssp, chan_general, EBUS_IDX_EEPROM_SIZE_KB) * 2842 1024; 2843 2844 if (bscv_faulty(ssp)) { 2845 bscv_exit(ssp); 2846 return (EIO); 2847 } else if ((base_addr + data_size) > eeprom_size) { 2848 bscv_trace(ssp, 'M', "bscv_ioc_mread2", 2849 "Request extends past end of eeprom"); 2850 bscv_exit(ssp); 2851 return (ENXIO); 2852 } 2853 2854 if (bscv_eerw(ssp, base_addr, &mprog2.data[0], 2855 data_size, B_FALSE /* read */) != 0) { 2856 res = EIO; 2857 } 2858 2859 if (bscv_faulty(ssp)) { 2860 res = EIO; 2861 } 2862 bscv_exit(ssp); 2863 2864 if ((res == 0) && 2865 (ddi_copyout((caddr_t)&mprog2, (caddr_t)arg, sizeof (mprog2), 2866 mode) < 0)) { 2867 res = EFAULT; 2868 } 2869 return (res); 2870 } 2871 2872 static void 2873 bscv_get_state_changes(bscv_soft_state_t *ssp) 2874 { 2875 int i = STATUS_READ_LIMIT; 2876 uint8_t change; 2877 uint8_t detail; 2878 2879 ASSERT(bscv_held(ssp)); 2880 2881 while (i-- && !ssp->cssp_prog) { 2882 /* Are there any changes to process? */ 2883 change = bscv_get8(ssp, chan_general, EBUS_IDX_STATE_CHNG); 2884 change &= EBUS_STATE_MASK; 2885 if (!change) 2886 break; 2887 2888 /* Clarify the pending change */ 2889 detail = bscv_get8(ssp, chan_general, EBUS_IDX_EVENT_DETAIL); 2890 2891 bscv_status(ssp, change, detail); 2892 } 2893 2894 bscv_trace(ssp, 'D', "bscv_get_state_changes", 2895 "loop index %d ssp->cssp_prog 0x%x", i, ssp->cssp_prog); 2896 } 2897 2898 /* 2899 * ********************************************************************* 2900 * Event Processing 2901 * ********************************************************************* 2902 */ 2903 2904 /* 2905 * function - bscv_event_daemon 2906 * description - Perform periodic lom tasks in a separate thread. 2907 * inputs - LOM soft state structure pointer 2908 * outputs - none. 2909 */ 2910 static void 2911 bscv_event_daemon(void *arg) 2912 { 2913 bscv_soft_state_t *ssp = (void *)arg; 2914 boolean_t do_events; 2915 boolean_t do_status; 2916 boolean_t do_nodename; 2917 boolean_t do_watchdog; 2918 uint32_t async_reg; 2919 uint32_t fault; 2920 clock_t poll_period = BSC_EVENT_POLL_NORMAL; 2921 int fault_cnt = 0; 2922 2923 bscv_trace(ssp, 'D', "bscv_event_daemon", 2924 "bscv_event_daemon: started"); 2925 2926 /* Acquire task daemon lock. */ 2927 mutex_enter(&ssp->task_mu); 2928 2929 ssp->task_flags |= TASK_ALIVE_FLG; 2930 2931 for (;;) { 2932 if ((ssp->task_flags & TASK_STOP_FLG) != 0) { 2933 /* Stop request seen - terminate */ 2934 break; 2935 } 2936 if ((ssp->task_flags & TASK_PAUSE_FLG) == 0) { 2937 /* Poll for events reported to the nexus */ 2938 mutex_exit(&ssp->task_mu); 2939 /* Probe and Check faults */ 2940 bscv_enter(ssp); 2941 async_reg = bscv_probe(ssp, chan_general, &fault); 2942 bscv_trace(ssp, 'D', "bscv_event_daemon", 2943 "process event: async_reg 0x%x, fault 0x%x", 2944 async_reg, fault); 2945 2946 if (!fault) { 2947 /* Treat non-fault conditions */ 2948 2949 if (ssp->cssp_prog || ssp->prog_mode_only) { 2950 /* 2951 * The BSC has become available again. 2952 */ 2953 fault_cnt = 0; 2954 ssp->cssp_prog = B_FALSE; 2955 ssp->prog_mode_only = B_FALSE; 2956 (void) bscv_attach_common(ssp); 2957 } else if (fault_cnt > 0) { 2958 /* Previous fault has cleared */ 2959 bscv_clear_fault(ssp); 2960 fault_cnt = 0; 2961 cmn_err(CE_WARN, 2962 "!bscv_event_daemon previous fault " 2963 "cleared."); 2964 } else if (bscv_faulty(ssp)) { 2965 /* Previous fault has cleared */ 2966 bscv_clear_fault(ssp); 2967 /* Sleep to avoid busy waiting */ 2968 ssp->event_sleep = B_TRUE; 2969 } 2970 poll_period = BSC_EVENT_POLL_NORMAL; 2971 2972 if (async_reg) { 2973 ssp->status_change = B_TRUE; 2974 ssp->event_waiting = B_TRUE; 2975 } 2976 } else if (ssp->cssp_prog) { 2977 /* 2978 * Expect radio silence or error values 2979 * when the CSSP is upgrading the BSC firmware 2980 * so throw away any fault indication. 2981 */ 2982 fault = B_FALSE; 2983 } else if (fault_cnt == BSC_PROBE_FAULT_LIMIT) { 2984 /* Count previous faults and maybe fail */ 2985 /* Declare the lom broken */ 2986 bscv_set_fault(ssp); 2987 poll_period = BSC_EVENT_POLL_FAULTY; 2988 cmn_err(CE_WARN, 2989 "!bscv_event_daemon had faults probing " 2990 "lom - marking it as faulty."); 2991 /* 2992 * Increment fault_cnt to ensure that 2993 * next time we do not report a message 2994 * i.e. we drop out of the bottom 2995 */ 2996 fault_cnt = BSC_PROBE_FAULT_LIMIT + 1; 2997 ssp->event_sleep = B_TRUE; 2998 } else if (fault_cnt < BSC_PROBE_FAULT_LIMIT) { 2999 if (bscv_faulty(ssp)) { 3000 poll_period = BSC_EVENT_POLL_FAULTY; 3001 /* 3002 * No recovery messages in this case 3003 * because there was never a fault 3004 * message here. 3005 */ 3006 fault_cnt = 0; 3007 } else { 3008 /* Getting ready to explode */ 3009 fault_cnt++; 3010 cmn_err(CE_WARN, 3011 "!bscv_event_daemon had fault 0x%x", 3012 fault); 3013 } 3014 ssp->event_sleep = B_TRUE; 3015 } 3016 bscv_exit(ssp); 3017 mutex_enter(&ssp->task_mu); 3018 } 3019 3020 #if defined(__i386) || defined(__amd64) 3021 /* 3022 * we have no platmod hook on Solaris x86 to report 3023 * a change to the nodename so we keep a copy so 3024 * we can detect a change and request that the bsc 3025 * be updated when appropriate. 3026 */ 3027 if (strcmp(ssp->last_nodename, utsname.nodename) != 0) { 3028 3029 bscv_trace(ssp, 'X', "bscv_event_daemon", 3030 "utsname.nodename='%s' possible change detected", 3031 utsname.nodename); 3032 ssp->nodename_change = B_TRUE; 3033 (void) strncpy(ssp->last_nodename, utsname.nodename, 3034 sizeof (ssp->last_nodename)); 3035 /* enforce null termination */ 3036 ssp->last_nodename[sizeof (ssp->last_nodename) - 1] = 3037 '\0'; 3038 } 3039 #endif /* __i386 || __amd64 */ 3040 3041 if (((ssp->task_flags & TASK_PAUSE_FLG) == 0) && 3042 fault_cnt == 0 && ssp->cssp_prog == B_FALSE && 3043 (ssp->event_waiting || ssp->status_change || 3044 ssp->nodename_change || ssp->watchdog_change)) { 3045 3046 do_events = ssp->event_waiting; 3047 ssp->event_waiting = B_FALSE; 3048 ssp->task_flags |= do_events ? 3049 TASK_EVENT_PENDING_FLG : 0; 3050 do_status = ssp->status_change; 3051 ssp->status_change = B_FALSE; 3052 do_nodename = ssp->nodename_change; 3053 ssp->nodename_change = B_FALSE; 3054 do_watchdog = ssp->watchdog_change; 3055 if (ssp->watchdog_change) { 3056 ssp->watchdog_change = B_FALSE; 3057 } 3058 3059 mutex_exit(&ssp->task_mu); 3060 /* 3061 * We must not hold task_mu whilst processing 3062 * events because this can lead to priority 3063 * inversion and hence our interrupts getting 3064 * locked out. 3065 */ 3066 bscv_enter(ssp); 3067 if (do_events) { 3068 bscv_event_process(ssp, do_events); 3069 } 3070 if (do_nodename) { 3071 bscv_trace(ssp, 'D', "bscv_event_daemon", 3072 "do_nodename task"); 3073 bscv_setup_hostname(ssp); 3074 } 3075 if (do_watchdog) { 3076 bscv_trace(ssp, 'D', "bscv_event_daemon", 3077 "do_watchdog task"); 3078 bscv_setup_watchdog(ssp); 3079 } 3080 /* 3081 * Pending status changes are dealt with last because 3082 * if we see that the BSC is about to be programmed, 3083 * then it will expect us to to quiescent in the 3084 * first second so it can cleanly tear down its comms 3085 * protocols; this takes ~100 ms. 3086 */ 3087 if (do_status) { 3088 bscv_get_state_changes(ssp); 3089 } 3090 if (bscv_session_error(ssp)) { 3091 /* 3092 * Had fault during event session. We always 3093 * sleep after one of these because there 3094 * may be a problem with the lom which stops 3095 * us doing useful work in the event daemon. 3096 * If we don't sleep then we may livelock. 3097 */ 3098 bscv_trace(ssp, 'D', "bscv_event_daemon", 3099 "had session error - sleeping"); 3100 ssp->event_sleep = B_TRUE; 3101 } 3102 bscv_exit(ssp); 3103 3104 mutex_enter(&ssp->task_mu); 3105 3106 if (ssp->task_flags & TASK_EVENT_PENDING_FLG) { 3107 /* 3108 * We have read any events which were 3109 * pending. Let the consumer continue. 3110 * Ignore the race condition with new events 3111 * arriving - just let the consumer have 3112 * whatever was pending when they asked. 3113 */ 3114 ssp->event_active_count++; 3115 ssp->task_flags &= ~(TASK_EVENT_PENDING_FLG | 3116 TASK_EVENT_CONSUMER_FLG); 3117 cv_broadcast(&ssp->task_evnt_cv); 3118 } 3119 } else { 3120 /* There was nothing to do - sleep */ 3121 ssp->event_sleep = B_TRUE; 3122 } 3123 3124 if (ssp->event_sleep) { 3125 ssp->task_flags |= TASK_SLEEPING_FLG; 3126 /* Sleep until there is something to do */ 3127 (void) cv_timedwait(&ssp->task_cv, 3128 &ssp->task_mu, 3129 poll_period + ddi_get_lbolt()); 3130 ssp->task_flags &= ~TASK_SLEEPING_FLG; 3131 ssp->event_sleep = B_FALSE; 3132 } 3133 } 3134 3135 if (ssp->task_flags & TASK_EVENT_CONSUMER_FLG) { 3136 /* 3137 * We are going away so wake up any event consumer. 3138 * Pretend that any pending events have been processed. 3139 */ 3140 ssp->event_active_count += 2; 3141 cv_broadcast(&ssp->task_evnt_cv); 3142 } 3143 3144 ASSERT(!(ssp->task_flags & TASK_EVENT_PENDING_FLG)); 3145 ssp->task_flags &= 3146 ~(TASK_STOP_FLG | TASK_ALIVE_FLG | TASK_EVENT_CONSUMER_FLG); 3147 mutex_exit(&ssp->task_mu); 3148 3149 bscv_trace(ssp, 'D', "bscv_event_daemon", 3150 "exiting."); 3151 } 3152 3153 /* 3154 * function - bscv_start_event_daemon 3155 * description - Create the event daemon thread. 3156 * inputs - LOM soft state structure pointer 3157 * outputs - none 3158 */ 3159 static void 3160 bscv_start_event_daemon(bscv_soft_state_t *ssp) 3161 { 3162 if (ssp->progress & BSCV_THREAD) 3163 return; 3164 3165 /* Start the event thread after the queue has started */ 3166 (void) thread_create(NULL, 0, (void (*)())bscv_event_daemon, ssp, 3167 0, &p0, TS_RUN, minclsyspri); 3168 3169 ssp->progress |= BSCV_THREAD; 3170 } 3171 3172 /* 3173 * function - bscv_stop_event_daemon 3174 * description - Attempt to stop the event daemon thread. 3175 * inputs - LOM soft state structure pointer 3176 * outputs - DDI_SUCCESS OR DDI_FAILURE 3177 */ 3178 static int 3179 bscv_stop_event_daemon(bscv_soft_state_t *ssp) 3180 { 3181 int try; 3182 int res = DDI_SUCCESS; 3183 3184 mutex_enter(&ssp->task_mu); 3185 3186 /* Wait for task daemon to stop running. */ 3187 for (try = 0; 3188 ((ssp->task_flags & TASK_ALIVE_FLG) && try < 10); 3189 try++) { 3190 /* Signal that the task daemon should stop */ 3191 ssp->task_flags |= TASK_STOP_FLG; 3192 cv_signal(&ssp->task_cv); 3193 /* Release task daemon lock. */ 3194 mutex_exit(&ssp->task_mu); 3195 /* 3196 * TODO - when the driver is modified to support 3197 * system suspend or if this routine gets called 3198 * during panic we should use drv_usecwait() rather 3199 * than delay in those circumstances. 3200 */ 3201 delay(drv_usectohz(1000000)); 3202 mutex_enter(&ssp->task_mu); 3203 } 3204 3205 if (ssp->task_flags & TASK_ALIVE_FLG) { 3206 res = DDI_FAILURE; 3207 } 3208 mutex_exit(&ssp->task_mu); 3209 3210 return (res); 3211 } 3212 3213 /* 3214 * function - bscv_pause_event_daemon 3215 * description - Attempt to pause the event daemon thread. 3216 * inputs - LOM soft state structure pointer 3217 * outputs - DDI_SUCCESS OR DDI_FAILURE 3218 */ 3219 static int 3220 bscv_pause_event_daemon(bscv_soft_state_t *ssp) 3221 { 3222 int try; 3223 3224 if (!(ssp->progress & BSCV_THREAD)) { 3225 /* Nothing to do */ 3226 return (BSCV_SUCCESS); 3227 } 3228 3229 bscv_trace(ssp, 'D', "bscv_pause_event_daemon", 3230 "Attempting to pause event daemon"); 3231 3232 mutex_enter(&ssp->task_mu); 3233 /* Signal that the task daemon should pause */ 3234 ssp->task_flags |= TASK_PAUSE_FLG; 3235 3236 /* Wait for task daemon to pause. */ 3237 for (try = 0; 3238 (!(ssp->task_flags & TASK_SLEEPING_FLG) && 3239 (ssp->task_flags & TASK_ALIVE_FLG) && 3240 try < 10); 3241 try++) { 3242 /* Paranoia */ 3243 ssp->task_flags |= TASK_PAUSE_FLG; 3244 cv_signal(&ssp->task_cv); 3245 /* Release task daemon lock. */ 3246 mutex_exit(&ssp->task_mu); 3247 delay(drv_usectohz(1000000)); 3248 mutex_enter(&ssp->task_mu); 3249 } 3250 if ((ssp->task_flags & TASK_SLEEPING_FLG) || 3251 !(ssp->task_flags & TASK_ALIVE_FLG)) { 3252 mutex_exit(&ssp->task_mu); 3253 bscv_trace(ssp, 'D', "bscv_pause_event_daemon", 3254 "Pause event daemon - success"); 3255 return (BSCV_SUCCESS); 3256 } 3257 mutex_exit(&ssp->task_mu); 3258 bscv_trace(ssp, 'D', "bscv_pause_event_daemon", 3259 "Pause event daemon - failed"); 3260 return (BSCV_FAILURE); 3261 } 3262 3263 /* 3264 * function - bscv_resume_event_daemon 3265 * description - Resumethe event daemon thread. 3266 * inputs - LOM soft state structure pointer 3267 * outputs - None. 3268 */ 3269 static void 3270 bscv_resume_event_daemon(bscv_soft_state_t *ssp) 3271 { 3272 if (!(ssp->progress & BSCV_THREAD)) { 3273 /* Nothing to do */ 3274 return; 3275 } 3276 3277 mutex_enter(&ssp->task_mu); 3278 /* Allow the task daemon to resume event processing */ 3279 ssp->task_flags &= ~TASK_PAUSE_FLG; 3280 cv_signal(&ssp->task_cv); 3281 mutex_exit(&ssp->task_mu); 3282 3283 bscv_trace(ssp, 'D', "bscv_pause_event_daemon", 3284 "Event daemon resumed"); 3285 } 3286 3287 /* 3288 * function - bscv_event_process 3289 * description - process (report) events 3290 * inputs - Soft state ptr, process event request 3291 * outputs - none 3292 */ 3293 static void 3294 bscv_event_process(bscv_soft_state_t *ssp, boolean_t do_events) 3295 { 3296 uint32_t currptr; 3297 unsigned int count; 3298 3299 /* Raw values read from the lom */ 3300 uint8_t evcount; 3301 uint16_t logptr; 3302 3303 lom_event_t event; 3304 3305 if (do_events) { 3306 /* 3307 * Read count, next event ptr MSB,LSB. Note a read of count 3308 * latches values for the next event ptr 3309 */ 3310 evcount = bscv_get8(ssp, chan_general, EBUS_IDX_UNREAD_EVENTS); 3311 logptr = bscv_get16(ssp, chan_general, EBUS_IDX_LOG_PTR_HI); 3312 3313 /* Sanity check the values from the lom */ 3314 count = bscv_event_validate(ssp, logptr, evcount); 3315 3316 if (count == -1) { 3317 /* 3318 * Nothing to do - or badly configured event log. 3319 * We really do not want to touch the lom in this 3320 * case because any data that we access may be bad! 3321 * This differs from zero because if we have zero 3322 * to read the lom probably things that unread is 3323 * non-zero and we want that to be set to zero! 3324 * Signal event fault to make the thread wait 3325 * before attempting to re-read the log. 3326 */ 3327 ssp->event_sleep = B_TRUE; 3328 3329 goto logdone; 3330 } 3331 if (ssp->event_fault_reported) { 3332 /* Clear down any old status - things are fixed */ 3333 cmn_err(CE_NOTE, "Event pointer fault recovered."); 3334 ssp->event_fault_reported = B_FALSE; 3335 } 3336 3337 /* Compute the first entry that we need to read. */ 3338 currptr = logptr - ssp->eventlog_start; 3339 currptr += ssp->eventlog_size; 3340 currptr -= (count * sizeof (event)); 3341 currptr %= ssp->eventlog_size; 3342 currptr += ssp->eventlog_start; 3343 3344 bscv_trace(ssp, 'E', "bscv_event_process", 3345 "processing %d events from 0x%x in 0x%x:0x%x", 3346 count, currptr, 3347 ssp->eventlog_start, 3348 ssp->eventlog_start + ssp->eventlog_size); 3349 3350 for (; count > 0; count--) { 3351 /* Ensure window is positioned correctly */ 3352 if (bscv_eerw(ssp, currptr, (uint8_t *)&event, 3353 sizeof (event), B_FALSE /* read */) != 0) { 3354 /* Fault reading data - stop */ 3355 break; 3356 } 3357 3358 bscv_event_process_one(ssp, &event); 3359 bscv_sysevent(ssp, &event); 3360 3361 currptr += sizeof (event); 3362 if (currptr >= ssp->eventlog_start + 3363 ssp->eventlog_size) { 3364 currptr = ssp->eventlog_start; 3365 } 3366 } 3367 /* 3368 * Clear event count - write the evcount value to remove that 3369 * many from the unread total. 3370 * Adjust the value to reflect how many we have left to 3371 * read just in case we had a failure reading events. 3372 */ 3373 if (count == 0) { 3374 /*EMPTY*/ 3375 ASSERT(logptr == currptr); 3376 } else if (count > evcount) { 3377 evcount = 0; 3378 } else { 3379 evcount -= count; 3380 } 3381 bscv_put8(ssp, chan_general, EBUS_IDX_UNREAD_EVENTS, evcount); 3382 /* Remember where we were for next time */ 3383 ssp->oldeeptr = currptr; 3384 ssp->oldeeptr_valid = B_TRUE; 3385 logdone: 3386 ; 3387 } 3388 } 3389 3390 /* 3391 * function - bscv_event_validate 3392 * description - validate the event data supplied by the lom and determine 3393 * how many (if any) events to read. 3394 * This function performs complex checks to ensure that 3395 * events are not lost due to lom resets or host resets. 3396 * A combination of lom reset and host reset (i.e. power fail) 3397 * may cause some events to not be reported. 3398 * inputs - Soft state ptr, next event pointer, number of unread events. 3399 * outputs - the number of events to read. -1 on error. 3400 * zero is a valid value because it forces the loms unread 3401 * count to be cleared. 3402 */ 3403 static int 3404 bscv_event_validate(bscv_soft_state_t *ssp, uint32_t newptr, uint8_t unread) 3405 { 3406 uint32_t oldptr; 3407 unsigned int count; 3408 3409 if (!bscv_window_setup(ssp)) { 3410 /* Problem with lom eeprom setup we cannot do anything */ 3411 return (-1); 3412 } 3413 3414 /* Sanity check the event pointers */ 3415 if ((newptr < ssp->eventlog_start) || 3416 (newptr >= (ssp->eventlog_start + ssp->eventlog_size))) { 3417 if (!ssp->event_fault_reported) { 3418 cmn_err(CE_WARN, "Event pointer out of range. " 3419 "Cannot read events."); 3420 ssp->event_fault_reported = B_TRUE; 3421 } 3422 return (-1); 3423 } 3424 oldptr = ssp->oldeeptr; 3425 /* Now sanity check log pointer against count */ 3426 if (newptr < oldptr) { 3427 /* 3428 * Must have wrapped add eventlog_size to get the 3429 * correct relative values - this makes the checks 3430 * below work! 3431 */ 3432 newptr += ssp->eventlog_size; 3433 } 3434 if (!ssp->oldeeptr_valid) { 3435 /* We have just started up - we have to trust lom */ 3436 count = unread; 3437 } else if ((unread == 0) && (newptr == oldptr)) { 3438 /* Nothing to do - we were just polling */ 3439 return (-1); 3440 } else if (oldptr + (unread * sizeof (lom_event_t)) == newptr) { 3441 /* Ok - got as many events as we expected */ 3442 count = unread; 3443 } else if (oldptr + (unread * sizeof (lom_event_t)) > newptr) { 3444 /* 3445 * Errrm more messages than there should have been. 3446 * Possible causes: 3447 * 1. the event log has filled - we have been 3448 * away for a long time 3449 * 2. software bug in lom or driver. 3450 * 3. something that I haven't thought of! 3451 * Always warn about this we should really never 3452 * see it! 3453 */ 3454 count = (newptr - oldptr) / sizeof (lom_event_t); 3455 bscv_trace(ssp, 'E', "bscv_event_process", 3456 "bscv_event_process: lom reported " 3457 "more events (%d) than expected (%d).", 3458 unread, count); 3459 cmn_err(CE_CONT, "only processing %d events", count); 3460 } else { 3461 /* Less messages - perhaps the lom has been reset */ 3462 count = (newptr - oldptr) / sizeof (lom_event_t); 3463 bscv_trace(ssp, 'E', "bscv_event_process", 3464 "lom reported less events (%d) than expected (%d)" 3465 " - the lom may have been reset", 3466 unread, count); 3467 } 3468 /* Whatever happens only read a maximum of 255 entries */ 3469 if ((count >= 0xff)) { 3470 cmn_err(CE_WARN, 3471 "bscv_event_process: too many events (%d) to " 3472 "process - some may have been lost", count); 3473 count = 0xff; 3474 } 3475 return (count); 3476 } 3477 3478 /* 3479 * function - bscv_event_process_one 3480 * description - reports on state changes to the host. 3481 * 3482 * inputs - LOM soft state structure pointer. 3483 * 3484 * outputs - none. 3485 */ 3486 3487 static void 3488 bscv_event_process_one(bscv_soft_state_t *ssp, lom_event_t *event) 3489 { 3490 int level; 3491 char eventstr[100]; 3492 int msg_type = 0; 3493 3494 if (bscv_is_null_event(ssp, event)) { 3495 /* Cleared entry - do not report it */ 3496 return; 3497 } 3498 3499 level = bscv_level_of_event(event); 3500 3501 switch (level) { 3502 default: 3503 msg_type = CE_NOTE; 3504 break; 3505 3506 case EVENT_LEVEL_FATAL: 3507 case EVENT_LEVEL_FAULT: 3508 msg_type = CE_WARN; 3509 break; 3510 } 3511 3512 bscv_build_eventstring(ssp, event, eventstr, eventstr + 3513 sizeof (eventstr)); 3514 3515 if (level <= ssp->reporting_level) { 3516 /* 3517 * The message is important enough to be shown on the console 3518 * as well as the log. 3519 */ 3520 cmn_err(msg_type, "%s", eventstr); 3521 } else { 3522 /* 3523 * The message goes only to the log. 3524 */ 3525 cmn_err(msg_type, "!%s", eventstr); 3526 } 3527 } 3528 3529 /* 3530 * time formats 3531 * 3532 * The BSC represents times as seconds since epoch 1970. Currently it gives 3533 * us 32 bits, unsigned. In the future this might change to a 64-bit count, 3534 * to allow a greater range. 3535 * 3536 * Timestamp values below BSC_TIME_SANITY do not represent an absolute time, 3537 * but instead represent an offset from the last reset. This must be 3538 * borne in mind by output routines. 3539 */ 3540 3541 typedef uint32_t bsctime_t; 3542 3543 #define BSC_TIME_SANITY 1000000000 3544 3545 /* 3546 * render a formatted time for display 3547 */ 3548 3549 static size_t 3550 bscv_event_snprintgmttime(char *buf, size_t bufsz, todinfo_t t) 3551 { 3552 int year; 3553 3554 /* tod_year is base 1900 so this code needs to adjust */ 3555 year = 1900 + t.tod_year; 3556 3557 return (snprintf(buf, bufsz, "%04d-%02d-%02d %02d:%02d:%02dZ", 3558 year, t.tod_month, t.tod_day, t.tod_hour, 3559 t.tod_min, t.tod_sec)); 3560 } 3561 3562 /* 3563 * function - bscv_build_eventstring 3564 * description - reports on state changes to the host. 3565 * 3566 * inputs - LOM soft state structure pointer. 3567 * 3568 * outputs - none. 3569 */ 3570 3571 static void 3572 bscv_build_eventstring(bscv_soft_state_t *ssp, lom_event_t *event, 3573 char *buf, char *bufend) 3574 { 3575 uint8_t subsystem; 3576 uint8_t eventtype; 3577 bsctime_t bsctm; 3578 3579 bscv_trace(ssp, 'S', "bscv_build_eventstring", "event %2x%2x%2x%2x", 3580 event->ev_subsys, event->ev_event, 3581 event->ev_resource, event->ev_detail); 3582 bscv_trace(ssp, 'S', "bscv_build_eventstring", "time %2x%2x%2x%2x", 3583 event->ev_data[0], event->ev_data[1], 3584 event->ev_data[2], event->ev_data[3]); 3585 3586 /* 3587 * We accept bad subsystems and event type codes here. 3588 * The code decodes as much as possible and then produces 3589 * suitable output. 3590 */ 3591 subsystem = EVENT_DECODE_SUBSYS(event->ev_subsys); 3592 eventtype = event->ev_event; 3593 3594 /* time */ 3595 bsctm = (((uint32_t)event->ev_data[0]) << 24) | 3596 (((uint32_t)event->ev_data[1]) << 16) | 3597 (((uint32_t)event->ev_data[2]) << 8) | 3598 ((uint32_t)event->ev_data[3]); 3599 if (bsctm < BSC_TIME_SANITY) { 3600 /* offset */ 3601 buf += snprintf(buf, bufend-buf, "+P%dd%02dh%02dm%02ds", 3602 (int)(bsctm/86400), (int)(bsctm/3600%24), 3603 (int)(bsctm/60%60), (int)(bsctm%60)); 3604 } else { 3605 /* absolute time */ 3606 mutex_enter(&tod_lock); 3607 buf += bscv_event_snprintgmttime(buf, bufend-buf, 3608 utc_to_tod(bsctm)); 3609 mutex_exit(&tod_lock); 3610 } 3611 buf += snprintf(buf, bufend-buf, " "); 3612 3613 /* subsysp */ 3614 if (subsystem < 3615 (sizeof (eventSubsysStrings)/sizeof (*eventSubsysStrings))) { 3616 buf += snprintf(buf, bufend - buf, "%s", 3617 eventSubsysStrings[subsystem]); 3618 } else { 3619 buf += snprintf(buf, bufend - buf, 3620 "unknown subsystem %d ", subsystem); 3621 } 3622 3623 /* resource */ 3624 switch (subsystem) { 3625 case EVENT_SUBSYS_ALARM: 3626 case EVENT_SUBSYS_TEMP: 3627 case EVENT_SUBSYS_OVERTEMP: 3628 case EVENT_SUBSYS_FAN: 3629 case EVENT_SUBSYS_SUPPLY: 3630 case EVENT_SUBSYS_BREAKER: 3631 case EVENT_SUBSYS_PSU: 3632 buf += snprintf(buf, bufend - buf, "%d ", event->ev_resource); 3633 break; 3634 case EVENT_SUBSYS_LED: 3635 buf += snprintf(buf, bufend - buf, "%s ", bscv_get_label( 3636 ssp->led_names, MAX_LED_ID, event->ev_resource - 1)); 3637 break; 3638 default: 3639 break; 3640 } 3641 3642 /* fatal */ 3643 if (event->ev_subsys & EVENT_MASK_FAULT) { 3644 if (event->ev_subsys & EVENT_MASK_FATAL) { 3645 buf += snprintf(buf, bufend - buf, "FATAL FAULT: "); 3646 } else { 3647 buf += snprintf(buf, bufend - buf, "FAULT: "); 3648 } 3649 } 3650 3651 /* eventp */ 3652 if (eventtype < 3653 (sizeof (eventTypeStrings)/sizeof (*eventTypeStrings))) { 3654 buf += snprintf(buf, bufend - buf, "%s", 3655 eventTypeStrings[eventtype]); 3656 } else { 3657 buf += snprintf(buf, bufend - buf, 3658 "unknown event 0x%02x%02x%02x%02x", 3659 event->ev_subsys, event->ev_event, 3660 event->ev_resource, event->ev_detail); 3661 } 3662 3663 /* detail */ 3664 switch (subsystem) { 3665 case EVENT_SUBSYS_TEMP: 3666 if ((eventtype != EVENT_RECOVERED) && 3667 eventtype != EVENT_DEVICE_INACCESSIBLE) { 3668 buf += snprintf(buf, bufend - buf, " - %d degC", 3669 (int8_t)event->ev_detail); 3670 } 3671 break; 3672 case EVENT_SUBSYS_FAN: 3673 if (eventtype == EVENT_FAILED) { 3674 buf += snprintf(buf, bufend - buf, 3675 " %d%%", event->ev_detail); 3676 } 3677 break; 3678 case EVENT_SUBSYS_LOM: 3679 switch (eventtype) { 3680 case EVENT_FLASH_DOWNLOAD: 3681 buf += snprintf(buf, bufend - buf, 3682 ": v%d.%d to v%d.%d", 3683 (event->ev_resource >> 4), 3684 (event->ev_resource & 0x0f), 3685 (event->ev_detail >> 4), 3686 (event->ev_detail & 0x0f)); 3687 break; 3688 case EVENT_WATCHDOG_TRIGGER: 3689 buf += snprintf(buf, bufend - buf, 3690 event->ev_detail ? "- soft" : " - hard"); 3691 break; 3692 case EVENT_UNEXPECTED_RESET: 3693 if (event->ev_detail & 3694 LOM_UNEXPECTEDRESET_MASK_BADTRAP) { 3695 buf += snprintf(buf, bufend - buf, 3696 " - unclaimed exception 0x%x", 3697 event->ev_detail & 3698 ~LOM_UNEXPECTEDRESET_MASK_BADTRAP); 3699 } 3700 break; 3701 case EVENT_RESET: 3702 switch (event->ev_detail) { 3703 case LOM_RESET_DETAIL_BYUSER: 3704 buf += snprintf(buf, bufend - buf, " by user"); 3705 break; 3706 case LOM_RESET_DETAIL_REPROGRAMMING: 3707 buf += snprintf(buf, bufend - buf, 3708 " after flash download"); 3709 break; 3710 default: 3711 buf += snprintf(buf, bufend - buf, 3712 " - unknown reason"); 3713 break; 3714 } 3715 break; 3716 default: 3717 break; 3718 } 3719 break; 3720 case EVENT_SUBSYS_LED: 3721 switch (event->ev_detail) { 3722 case LOM_LED_STATE_OFF: 3723 buf += snprintf(buf, bufend - buf, ": OFF"); 3724 break; 3725 case LOM_LED_STATE_ON_STEADY: 3726 buf += snprintf(buf, bufend - buf, ": ON"); 3727 break; 3728 case LOM_LED_STATE_ON_FLASHING: 3729 case LOM_LED_STATE_ON_SLOWFLASH: 3730 buf += snprintf(buf, bufend - buf, ": BLINKING"); 3731 break; 3732 case LOM_LED_STATE_INACCESSIBLE: 3733 buf += snprintf(buf, bufend - buf, ": inaccessible"); 3734 break; 3735 case LOM_LED_STATE_STANDBY: 3736 buf += snprintf(buf, bufend - buf, ": standby"); 3737 break; 3738 case LOM_LED_STATE_NOT_PRESENT: 3739 buf += snprintf(buf, bufend - buf, ": not present"); 3740 break; 3741 default: 3742 buf += snprintf(buf, bufend - buf, ": 0x%x", 3743 event->ev_resource); 3744 break; 3745 } 3746 break; 3747 case EVENT_SUBSYS_USER: 3748 switch (eventtype) { 3749 case EVENT_USER_ADDED: 3750 case EVENT_USER_REMOVED: 3751 case EVENT_USER_PERMSCHANGED: 3752 case EVENT_USER_LOGIN: 3753 case EVENT_USER_PASSWORD_CHANGE: 3754 case EVENT_USER_LOGINFAIL: 3755 case EVENT_USER_LOGOUT: 3756 buf += snprintf(buf, bufend - buf, " %d", 3757 event->ev_resource); 3758 default: 3759 break; 3760 } 3761 break; 3762 case EVENT_SUBSYS_PSU: 3763 if (event->ev_detail & LOM_PSU_NOACCESS) { 3764 buf += snprintf(buf, bufend - buf, " - inaccessible"); 3765 } else if ((event->ev_detail & LOM_PSU_STATUS_MASK) 3766 == LOM_PSU_STATUS_MASK) { 3767 buf += snprintf(buf, bufend - buf, " - OK"); 3768 } else { 3769 buf += snprintf(buf, bufend - buf, " -"); 3770 /* 3771 * If both inputs are seen to have failed then simply 3772 * indicate that the PSU input has failed 3773 */ 3774 if (!(event->ev_detail & 3775 (LOM_PSU_INPUT_A_OK | LOM_PSU_INPUT_B_OK))) { 3776 buf += snprintf(buf, bufend - buf, " Input"); 3777 } else { 3778 /* At least one input is ok */ 3779 if (!(event->ev_detail & LOM_PSU_INPUT_A_OK)) { 3780 buf += snprintf(buf, bufend - buf, 3781 " InA"); 3782 } 3783 if (!(event->ev_detail & LOM_PSU_INPUT_B_OK)) { 3784 buf += snprintf(buf, bufend - buf, 3785 " InB"); 3786 } 3787 /* 3788 * Only flag an output error if an input is 3789 * still present 3790 */ 3791 if (!(event->ev_detail & LOM_PSU_OUTPUT_OK)) { 3792 buf += snprintf(buf, bufend - buf, 3793 " Output"); 3794 } 3795 } 3796 buf += snprintf(buf, bufend - buf, " failed"); 3797 } 3798 break; 3799 case EVENT_SUBSYS_NONE: 3800 if (eventtype == EVENT_FAULT_LED) { 3801 switch (event->ev_detail) { 3802 case 0: 3803 buf += snprintf(buf, bufend - buf, " - ON"); 3804 break; 3805 case 255: 3806 buf += snprintf(buf, bufend - buf, " - OFF"); 3807 break; 3808 default: 3809 buf += snprintf(buf, bufend - buf, 3810 " - %dHz", event->ev_detail); 3811 break; 3812 } 3813 } 3814 break; 3815 case EVENT_SUBSYS_HOST: 3816 if (eventtype == EVENT_BOOTMODE_CHANGE) { 3817 switch (event->ev_detail & 3818 ~EBUS_BOOTMODE_FORCE_CONSOLE) { 3819 case EBUS_BOOTMODE_FORCE_NOBOOT: 3820 buf += snprintf(buf, bufend - buf, 3821 " - no boot"); 3822 break; 3823 case EBUS_BOOTMODE_RESET_DEFAULT: 3824 buf += snprintf(buf, bufend - buf, 3825 " - reset defaults"); 3826 break; 3827 case EBUS_BOOTMODE_FULLDIAG: 3828 buf += snprintf(buf, bufend - buf, 3829 " - full diag"); 3830 break; 3831 case EBUS_BOOTMODE_SKIPDIAG: 3832 buf += snprintf(buf, bufend - buf, 3833 " - skip diag"); 3834 break; 3835 default: 3836 break; 3837 } 3838 } 3839 if (eventtype == EVENT_SCC_STATUS) { 3840 switch (event->ev_detail) { 3841 case 0: 3842 buf += snprintf(buf, bufend - buf, 3843 " - inserted"); 3844 break; 3845 case 1: 3846 buf += snprintf(buf, bufend - buf, 3847 " - removed"); 3848 break; 3849 default: 3850 break; 3851 } 3852 } 3853 break; 3854 3855 default: 3856 break; 3857 } 3858 3859 /* shutd */ 3860 if (event->ev_subsys & EVENT_MASK_SHUTDOWN_REQD) { 3861 buf += snprintf(buf, bufend - buf, " - shutdown req'd"); 3862 } 3863 3864 buf += snprintf(buf, bufend - buf, "\n"); 3865 3866 if (buf >= bufend) { 3867 /* Ensure newline at end of string */ 3868 bufend[-2] = '\n'; 3869 bufend[-1] = '\0'; 3870 #ifdef DEBUG 3871 cmn_err(CE_WARN, "!bscv_build_eventstring: buffer too small!"); 3872 #endif /* DEBUG */ 3873 } 3874 } 3875 3876 /* 3877 * function - bscv_level_of_event 3878 * description - This routine determines which level an event should be 3879 * reported at. 3880 * inputs - lom event structure pointer 3881 * outputs - event level. 3882 */ 3883 static int 3884 bscv_level_of_event(lom_event_t *event) 3885 { 3886 int level; 3887 /* 3888 * This is the same criteria that the firmware uses except we 3889 * log the fault led on as being EVENT_LEVEL_FAULT 3890 */ 3891 if (EVENT_DECODE_SUBSYS(event->ev_subsys) == EVENT_SUBSYS_USER) { 3892 level = EVENT_LEVEL_USER; 3893 } else if ((EVENT_DECODE_SUBSYS(event->ev_subsys) == 3894 EVENT_SUBSYS_ALARM) && (event->ev_event == EVENT_STATE_ON)) { 3895 level = EVENT_LEVEL_FAULT; 3896 } else if ((EVENT_DECODE_SUBSYS(event->ev_subsys) == 3897 EVENT_SUBSYS_NONE) && 3898 (event->ev_event == EVENT_FAULT_LED) && 3899 (event->ev_detail != 0xff)) { 3900 level = EVENT_LEVEL_FAULT; 3901 } else if ((EVENT_DECODE_SUBSYS(event->ev_subsys) == 3902 EVENT_SUBSYS_LOM) && event->ev_event == EVENT_TIME_REFERENCE) { 3903 level = EVENT_LEVEL_NOTICE; 3904 } else if (event->ev_event == EVENT_RECOVERED) { 3905 /* 3906 * All recovery messages need to be reported to the console 3907 * because during boot, the faults which occurred whilst 3908 * Solaris was not running are relayed to the console. There 3909 * is a case whereby a fatal fault (eg. over temp) could 3910 * have occurred and then recovered. The recovery condition 3911 * needs to be reported so the user doesn't think that the 3912 * failure (over temp) is still present. 3913 */ 3914 level = EVENT_LEVEL_FAULT; 3915 } else if (EVENT_DECODE_FAULT(event->ev_subsys) == 0) { 3916 /* None of FAULT, FATAL or SHUTDOWN REQD are set */ 3917 level = EVENT_LEVEL_NOTICE; 3918 } else if (EVENT_DECODE_FAULT(event->ev_subsys) == EVENT_MASK_FAULT) { 3919 /* Only FAULT set i.e not FATAL or SHUTDOWN REQD */ 3920 level = EVENT_LEVEL_FAULT; 3921 } else { 3922 level = EVENT_LEVEL_FATAL; 3923 } 3924 3925 return (level); 3926 } 3927 3928 /* 3929 * function - bscv_status 3930 * description - This routine is called when any change in the LOMlite2 status 3931 * is indicated by the status registers. 3932 * 3933 * inputs - LOM soft state structure pointer 3934 * 3935 * outputs - none. 3936 */ 3937 static void 3938 bscv_status(bscv_soft_state_t *ssp, uint8_t state_chng, uint8_t dev_no) 3939 { 3940 int8_t temp; 3941 uint8_t fanspeed; 3942 3943 ASSERT(bscv_held(ssp)); 3944 3945 bscv_trace(ssp, 'D', "bscv_status", "state_chng 0x%x dev_no 0x%x", 3946 state_chng, dev_no); 3947 3948 /* 3949 * The device that has changed is given by the state change 3950 * register and the event detail register so react 3951 * accordingly. 3952 */ 3953 3954 if (state_chng == EBUS_STATE_NOTIFY) { 3955 /* 3956 * The BSC is indicating a self state change 3957 */ 3958 if (dev_no == EBUS_DETAIL_FLASH) { 3959 ssp->cssp_prog = B_TRUE; 3960 bscv_trace(ssp, 'D', "bscv_status", 3961 "ssp->cssp_prog changed to 0x%x", 3962 ssp->cssp_prog); 3963 /* 3964 * It takes the BSC at least 100 ms to 3965 * clear down the comms protocol. 3966 * We back-off from talking to the 3967 * BSC during this period. 3968 */ 3969 delay(BSC_EVENT_POLL_NORMAL); 3970 bscv_trace(ssp, 'D', "bscv_status", 3971 "completed delay"); 3972 } else if (dev_no == EBUS_DETAIL_RESET) { 3973 /* 3974 * The bsc has reset 3975 */ 3976 bscv_trace(ssp, 'D', "bscv_status", 3977 "BSC reset occured, re-synching"); 3978 (void) bscv_attach_common(ssp); 3979 bscv_trace(ssp, 'D', "bscv_status", 3980 "completed attach_common"); 3981 } 3982 3983 } 3984 3985 if ((state_chng & EBUS_STATE_FAN) && ((dev_no - 1) < MAX_FANS)) { 3986 fanspeed = bscv_get8(ssp, chan_general, 3987 EBUS_IDX_FAN1_SPEED + dev_no - 1); 3988 /* 3989 * Only remember fanspeeds which are real values or 3990 * NOT PRESENT values. 3991 */ 3992 if ((fanspeed <= LOM_FAN_MAX_SPEED) || 3993 (fanspeed == LOM_FAN_NOT_PRESENT)) { 3994 ssp->fanspeed[dev_no - 1] = fanspeed; 3995 } 3996 } 3997 3998 if ((state_chng & EBUS_STATE_PSU) && ((dev_no - 1) < MAX_PSUS)) { 3999 (void) bscv_get8(ssp, chan_general, 4000 EBUS_IDX_PSU1_STAT + dev_no - 1); 4001 } 4002 4003 if (state_chng & EBUS_STATE_GP) { 4004 (void) bscv_get8(ssp, chan_general, EBUS_IDX_GPIP); 4005 } 4006 4007 if (state_chng & EBUS_STATE_CB) { 4008 (void) bscv_get8(ssp, chan_general, EBUS_IDX_CBREAK_STATUS); 4009 } 4010 4011 if ((state_chng & EBUS_STATE_TEMPERATURE) && 4012 ((dev_no - 1) < MAX_TEMPS)) { 4013 temp = bscv_get8(ssp, chan_general, 4014 EBUS_IDX_TEMP1 + dev_no - 1); 4015 /* 4016 * Only remember temperatures which are real values or 4017 * a NOT PRESENT value. 4018 */ 4019 if ((temp <= LOM_TEMP_MAX_VALUE) || 4020 (temp == LOM_TEMP_STATE_NOT_PRESENT)) { 4021 ssp->temps.temp[dev_no - 1] = temp; 4022 } 4023 } 4024 4025 if (state_chng & EBUS_STATE_RAIL) { 4026 (void) bscv_get8(ssp, chan_general, EBUS_IDX_SUPPLY_LO); 4027 (void) bscv_get8(ssp, chan_general, EBUS_IDX_SUPPLY_HI); 4028 } 4029 } 4030 4031 char * 4032 bscv_get_label(char labels[][MAX_LOM2_NAME_STR], int limit, int index) 4033 { 4034 4035 if (labels == NULL) 4036 return (""); 4037 4038 if (limit < 0 || index < 0 || index > limit) 4039 return ("-"); 4040 4041 return (labels[index]); 4042 } 4043 4044 static void 4045 bscv_generic_sysevent(bscv_soft_state_t *ssp, char *class, char *subclass, 4046 char *fru_id, char *res_id, int32_t fru_state, char *msg) 4047 { 4048 int rv; 4049 nvlist_t *attr_list; 4050 4051 bscv_trace(ssp, 'E', "bscv_generic_sysevent", "%s/%s:(%s,%s,%d) %s", 4052 class, subclass, fru_id, res_id, fru_state, msg); 4053 4054 4055 if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, KM_SLEEP)) { 4056 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4057 "nvlist alloc failure"); 4058 return; 4059 } 4060 if (nvlist_add_uint32(attr_list, ENV_VERSION, 1)) { 4061 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4062 "nvlist ENV_VERSION failure"); 4063 nvlist_free(attr_list); 4064 return; 4065 } 4066 if (nvlist_add_string(attr_list, ENV_FRU_ID, fru_id)) { 4067 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4068 "nvlist ENV_FRU_ID failure"); 4069 nvlist_free(attr_list); 4070 return; 4071 } 4072 if (nvlist_add_string(attr_list, ENV_FRU_RESOURCE_ID, res_id)) { 4073 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4074 "nvlist ENV_FRU_RESOURCE_ID failure"); 4075 nvlist_free(attr_list); 4076 return; 4077 } 4078 if (nvlist_add_string(attr_list, ENV_FRU_DEVICE, ENV_RESERVED_ATTR)) { 4079 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4080 "nvlist ENV_FRU_DEVICE failure"); 4081 nvlist_free(attr_list); 4082 return; 4083 } 4084 if (nvlist_add_int32(attr_list, ENV_FRU_STATE, fru_state)) { 4085 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4086 "nvlist ENV_FRU_STATE failure"); 4087 nvlist_free(attr_list); 4088 return; 4089 } 4090 if (nvlist_add_string(attr_list, ENV_MSG, msg)) { 4091 bscv_trace(ssp, 'E', "bscv_generic_sysevent", 4092 "nvlist ENV_MSG failure"); 4093 nvlist_free(attr_list); 4094 return; 4095 } 4096 4097 rv = ddi_log_sysevent(ssp->dip, DDI_VENDOR_SUNW, class, 4098 subclass, attr_list, NULL, DDI_SLEEP); 4099 4100 if (rv == DDI_SUCCESS) { 4101 bscv_trace(ssp, 'E', "bscv_generic_sysevent", "sent sysevent"); 4102 } else { 4103 cmn_err(CE_WARN, "!cannot deliver sysevent"); 4104 } 4105 4106 nvlist_free(attr_list); 4107 } 4108 4109 /* 4110 * function - bscv_sysevent 4111 * description - send out a sysevent on the given change if needed 4112 * inputs - soft state pointer, event to report 4113 * outputs - none 4114 */ 4115 4116 static void 4117 bscv_sysevent(bscv_soft_state_t *ssp, lom_event_t *event) 4118 { 4119 char *class = NULL; 4120 char *subclass = NULL; 4121 char *fru_id = "Blade"; /* The blade is only one FRU */ 4122 char *res_id; 4123 int32_t fru_state = 0; 4124 4125 bscv_trace(ssp, 'E', "bscv_sysevent", "processing event"); 4126 4127 ASSERT(event != NULL); 4128 4129 /* Map ev_subsys to sysevent class/sub-class */ 4130 4131 switch (EVENT_DECODE_SUBSYS(event->ev_subsys)) { 4132 case EVENT_SUBSYS_NONE: 4133 break; 4134 case EVENT_SUBSYS_ALARM: 4135 break; 4136 case EVENT_SUBSYS_TEMP: 4137 class = EC_ENV, subclass = ESC_ENV_TEMP; 4138 res_id = bscv_get_label(ssp->temps.name, ssp->temps.num, 4139 event->ev_resource - 1); 4140 switch (event->ev_event) { 4141 case EVENT_SEVERE_OVERHEAT: 4142 fru_state = ENV_FAILED; 4143 break; 4144 case EVENT_OVERHEAT: 4145 fru_state = ENV_WARNING; 4146 break; 4147 case EVENT_NO_OVERHEAT: 4148 fru_state = ENV_OK; 4149 break; 4150 default: 4151 return; 4152 } 4153 break; 4154 case EVENT_SUBSYS_OVERTEMP: 4155 break; 4156 case EVENT_SUBSYS_FAN: 4157 class = EC_ENV, subclass = ESC_ENV_FAN; 4158 res_id = bscv_get_label(ssp->fan_names, ssp->num_fans, 4159 event->ev_resource - 1); 4160 switch (event->ev_event) { 4161 case EVENT_FAILED: 4162 fru_state = ENV_FAILED; 4163 break; 4164 case EVENT_RECOVERED: 4165 fru_state = ENV_OK; 4166 break; 4167 default: 4168 return; 4169 } 4170 break; 4171 case EVENT_SUBSYS_SUPPLY: 4172 class = EC_ENV, subclass = ESC_ENV_POWER; 4173 res_id = bscv_get_label(ssp->sflags.name, ssp->sflags.num, 4174 event->ev_resource - 1); 4175 switch (event->ev_event) { 4176 case EVENT_FAILED: 4177 fru_state = ENV_FAILED; 4178 break; 4179 case EVENT_RECOVERED: 4180 fru_state = ENV_OK; 4181 break; 4182 default: 4183 return; 4184 } 4185 break; 4186 case EVENT_SUBSYS_BREAKER: 4187 break; 4188 case EVENT_SUBSYS_PSU: 4189 break; 4190 case EVENT_SUBSYS_USER: 4191 break; 4192 case EVENT_SUBSYS_PHONEHOME: 4193 break; 4194 case EVENT_SUBSYS_LOM: 4195 break; 4196 case EVENT_SUBSYS_HOST: 4197 break; 4198 case EVENT_SUBSYS_EVENTLOG: 4199 break; 4200 case EVENT_SUBSYS_EXTRA: 4201 break; 4202 case EVENT_SUBSYS_LED: 4203 if (event->ev_event != EVENT_FAULT_LED && 4204 event->ev_event != EVENT_STATE_CHANGE) 4205 return; 4206 /* 4207 * There are 3 LEDs : Power, Service, Ready-to-Remove on a 4208 * JBOS blade. We'll never report the Power since Solaris 4209 * won't be running when it is _switched_ ON. Ready-to-Remove 4210 * will only be lit when we're powered down which also means 4211 * Solaris won't be running. We don't want to report it 4212 * during system testing / Sun VTS exercising the LEDs. 4213 * 4214 * Therefore, we only report the Service Required LED. 4215 */ 4216 class = EC_ENV, subclass = ESC_ENV_LED; 4217 res_id = bscv_get_label(ssp->led_names, MAX_LED_ID, 4218 event->ev_resource - 1); 4219 4220 switch (event->ev_detail) { 4221 case LOM_LED_STATE_ON_STEADY: 4222 fru_state = ENV_LED_ON; 4223 break; 4224 case LOM_LED_STATE_ON_FLASHING: 4225 case LOM_LED_STATE_ON_SLOWFLASH: 4226 fru_state = ENV_LED_BLINKING; 4227 break; 4228 case LOM_LED_STATE_OFF: 4229 fru_state = ENV_LED_OFF; 4230 break; 4231 case LOM_LED_STATE_INACCESSIBLE: 4232 fru_state = ENV_LED_INACCESSIBLE; 4233 break; 4234 case LOM_LED_STATE_STANDBY: 4235 fru_state = ENV_LED_STANDBY; 4236 break; 4237 case LOM_LED_STATE_NOT_PRESENT: 4238 fru_state = ENV_LED_NOT_PRESENT; 4239 break; 4240 default: 4241 fru_state = ENV_LED_INACCESSIBLE; 4242 break; 4243 } 4244 break; 4245 default : 4246 break; 4247 } 4248 4249 if (class == NULL || subclass == NULL) { 4250 bscv_trace(ssp, 'E', "bscv_sysevent", "class/subclass NULL"); 4251 return; 4252 } 4253 4254 bscv_generic_sysevent(ssp, class, subclass, fru_id, res_id, fru_state, 4255 ENV_RESERVED_ATTR); 4256 } 4257 4258 /* 4259 * ********************************************************************* 4260 * Firmware download (programming) 4261 * ********************************************************************* 4262 */ 4263 4264 /* 4265 * function - bscv_prog 4266 * description - LOMlite2 flash programming code. 4267 * 4268 * bscv_prog_image - download a complete image to the lom. 4269 * bscv_prog_receive_image - receive data to build up a 4270 * complete image. 4271 * bscv_prog_stop_lom - pause the event daemon and prepare 4272 * lom for firmware upgrade. 4273 * bscv_prog_start_lom - reinit the driver/lom after upgrade 4274 * and restart the event daemon 4275 * 4276 * inputs - soft state pointer, arg ptr, ioctl mode 4277 * outputs - status 4278 */ 4279 4280 static int 4281 bscv_prog(bscv_soft_state_t *ssp, intptr_t arg, int mode) 4282 { 4283 lom_prog_t *prog; 4284 int res = 0; 4285 4286 /* 4287 * We will get repeatedly called with bits of data first for 4288 * loader, then for main image. 4289 */ 4290 prog = (lom_prog_t *)kmem_alloc(sizeof (lom_prog_t), KM_SLEEP); 4291 4292 if (ddi_copyin((caddr_t)arg, (caddr_t)prog, sizeof (*prog), 4293 mode) < 0) { 4294 kmem_free((void *)prog, sizeof (*prog)); 4295 return (EFAULT); 4296 } 4297 4298 bscv_trace(ssp, 'U', "bscv_prog", 4299 "index 0x%x size 0x%x", prog->index, prog->size); 4300 4301 mutex_enter(&ssp->prog_mu); 4302 if (prog->size == 0) { 4303 if (prog->index == 2) { 4304 /* 4305 * This is the initial request for the chip type so we 4306 * know what we are programming. 4307 * The type will have been read in at init so just 4308 * return it in data[0]. 4309 */ 4310 prog->data[0] = bscv_get8_cached(ssp, 4311 EBUS_IDX_CPU_IDENT); 4312 4313 if (ddi_copyout((caddr_t)prog, (caddr_t)arg, 4314 sizeof (lom_prog_t), mode) < 0) { 4315 res = EFAULT; 4316 } 4317 } else if (prog->index == 0) { 4318 res = bscv_prog_stop_lom(ssp); 4319 } else if (prog->index == 1) { 4320 res = bscv_prog_start_lom(ssp); 4321 } else { 4322 res = EINVAL; 4323 } 4324 } else { 4325 if (ssp->image == NULL) { 4326 ssp->image = (uint8_t *)kmem_zalloc( 4327 BSC_IMAGE_MAX_SIZE, KM_SLEEP); 4328 } 4329 res = bscv_prog_receive_image(ssp, prog, 4330 ssp->image, BSC_IMAGE_MAX_SIZE); 4331 } 4332 mutex_exit(&ssp->prog_mu); 4333 kmem_free((void *)prog, sizeof (lom_prog_t)); 4334 4335 return (res); 4336 } 4337 4338 static int 4339 bscv_check_loader_config(bscv_soft_state_t *ssp, boolean_t is_image2) 4340 { 4341 bscv_trace(ssp, 'U', "bscv_check_loader_config", 4342 "loader_running %d, is_image2 %d", 4343 ssp->loader_running, is_image2); 4344 4345 /* 4346 * loader_running TRUE means that we have told the microcontroller to 4347 * JUMP into the loader code which has been downloaded into its RAM. 4348 * At this point its an error to try and download another loader. We 4349 * should be downloading the actual image at this point. 4350 * Conversely, it is an error to download an image when the loader is 4351 * not already downloaded and the microcontroller hasn't JUMPed into it. 4352 * is_image2 TRUE means the image is being downloaded. 4353 * is_image2 FALSE means the loader is being downloaded. 4354 */ 4355 if (ssp->loader_running && !is_image2) { 4356 cmn_err(CE_WARN, "Attempt to download loader image " 4357 "with loader image already active"); 4358 cmn_err(CE_CONT, "This maybe an attempt to restart a " 4359 "failed firmware download - ignoring download attempt"); 4360 return (B_FALSE); 4361 } else if (!ssp->loader_running && is_image2) { 4362 cmn_err(CE_WARN, "Attempt to download firmware image " 4363 "without loader image active"); 4364 return (B_FALSE); 4365 4366 } 4367 4368 return (B_TRUE); 4369 } 4370 4371 static uint32_t 4372 bscv_get_pagesize(bscv_soft_state_t *ssp) 4373 { 4374 uint32_t pagesize; 4375 4376 ASSERT(bscv_held(ssp)); 4377 4378 pagesize = bscv_get32(ssp, chan_prog, 4379 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PAGE0)); 4380 4381 bscv_trace(ssp, 'U', "bscv_get_pagesize", "pagesize 0x%x", pagesize); 4382 4383 return (pagesize); 4384 } 4385 4386 /* 4387 * Sets the pagesize, returning the old value. 4388 */ 4389 static uint32_t 4390 bscv_set_pagesize(bscv_soft_state_t *ssp, uint32_t pagesize) 4391 { 4392 uint32_t old_pagesize; 4393 4394 ASSERT(bscv_held(ssp)); 4395 4396 old_pagesize = bscv_get_pagesize(ssp); 4397 4398 /* 4399 * The microcontroller remembers this value until until someone 4400 * changes it. 4401 */ 4402 bscv_put32(ssp, chan_prog, 4403 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PSIZ0), pagesize); 4404 4405 return (old_pagesize); 4406 } 4407 4408 static uint8_t 4409 bscv_enter_programming_mode(bscv_soft_state_t *ssp) 4410 { 4411 uint8_t retval; 4412 4413 ASSERT(bscv_held(ssp)); 4414 4415 bscv_put8(ssp, chan_prog, 4416 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), 4417 EBUS_PROGRAM_PCR_PRGMODE_ON); 4418 4419 retval = bscv_get8(ssp, chan_prog, BSCVA(EBUS_CMD_SPACE_PROGRAM, 4420 EBUS_PROGRAM_PCSR)); 4421 4422 return (retval); 4423 } 4424 4425 static void 4426 bscv_leave_programming_mode(bscv_soft_state_t *ssp, boolean_t with_jmp) 4427 { 4428 uint8_t reg; 4429 ASSERT(bscv_held(ssp)); 4430 4431 if (with_jmp) { 4432 reg = EBUS_PROGRAM_PCR_PROGOFF_JUMPTOADDR; 4433 bscv_trace(ssp, 'U', "bscv_leave_programming_mode", 4434 "jumptoaddr"); 4435 } else { 4436 reg = EBUS_PROGRAM_PCR_PRGMODE_OFF; 4437 bscv_trace(ssp, 'U', "bscv_leave_programming_mode", 4438 "prgmode_off"); 4439 } 4440 4441 bscv_put8(ssp, chan_prog, 4442 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), reg); 4443 } 4444 4445 4446 static void 4447 bscv_set_jump_to_addr(bscv_soft_state_t *ssp, uint32_t loadaddr) 4448 { 4449 ASSERT(bscv_held(ssp)); 4450 4451 bscv_put32(ssp, chan_prog, 4452 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0), loadaddr); 4453 4454 bscv_trace(ssp, 'U', "bscv_set_jump_to_addr", 4455 "set jump to loadaddr 0x%x", loadaddr); 4456 } 4457 4458 static uint8_t 4459 bscv_erase_once(bscv_soft_state_t *ssp, uint32_t loadaddr, uint32_t image_size) 4460 { 4461 uint8_t retval; 4462 4463 ASSERT(bscv_held(ssp)); 4464 4465 /* 4466 * write PADR, PSIZ to define area to be erased 4467 * We do not send erase for zero size because the current 4468 * downloader gets this wrong 4469 */ 4470 4471 /* 4472 * start at 0 4473 */ 4474 bscv_trace(ssp, 'U', "bscv_erase_once", "sending erase command"); 4475 4476 bscv_put32(ssp, chan_prog, 4477 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0), 4478 loadaddr); 4479 4480 /* set PSIZ to full size of image to be programmed */ 4481 bscv_put32(ssp, chan_prog, 4482 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PSIZ0), 4483 image_size); 4484 4485 /* write ERASE to PCSR */ 4486 bscv_put8(ssp, chan_prog, 4487 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), 4488 EBUS_PROGRAM_PCR_ERASE); 4489 4490 /* read PCSR to check status */ 4491 retval = bscv_get8(ssp, chan_prog, 4492 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR)); 4493 return (retval); 4494 } 4495 4496 static uint8_t 4497 bscv_do_erase(bscv_soft_state_t *ssp, uint32_t loadaddr, uint32_t image_size, 4498 boolean_t is_image2) 4499 { 4500 int retryable = BSC_ERASE_RETRY_LIMIT; 4501 uint8_t retval; 4502 4503 while (retryable--) { 4504 retval = bscv_erase_once(ssp, loadaddr, image_size); 4505 if (PSR_SUCCESS(retval)) 4506 break; 4507 else 4508 cmn_err(CE_WARN, "erase error 0x%x, attempt %d" 4509 ", base 0x%x, size 0x%x, %s image", 4510 retval, BSC_ERASE_RETRY_LIMIT - retryable, 4511 loadaddr, image_size, 4512 is_image2 ? "main" : "loader"); 4513 } 4514 4515 return (retval); 4516 } 4517 4518 static uint8_t 4519 bscv_set_page(bscv_soft_state_t *ssp, uint32_t addr) 4520 { 4521 uint32_t retval; 4522 int retryable = BSC_PAGE_RETRY_LIMIT; 4523 4524 ASSERT(bscv_held(ssp)); 4525 4526 while (retryable--) { 4527 4528 /* 4529 * Write the page address and read it back for confirmation. 4530 */ 4531 bscv_put32(ssp, chan_prog, 4532 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0), 4533 addr); 4534 retval = bscv_get32(ssp, chan_prog, 4535 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PADR0)); 4536 4537 if (retval == addr) 4538 break; 4539 else { 4540 cmn_err(CE_WARN, "programmming error, attempt %d, " 4541 "set page 0x%x, read back 0x%x", 4542 BSC_PAGE_RETRY_LIMIT - retryable, 4543 addr, retval); 4544 } 4545 } 4546 return ((addr == retval) ? EBUS_PROGRAM_PSR_SUCCESS : 4547 EBUS_PROGRAM_PSR_INVALID_OPERATION); 4548 } 4549 4550 static uint8_t 4551 bscv_do_page_data_once(bscv_soft_state_t *ssp, uint32_t index, 4552 uint32_t image_size, uint32_t pagesize, uint8_t *imagep, 4553 uint16_t *calcd_chksum) 4554 { 4555 uint32_t size; 4556 uint16_t chksum; 4557 int i; 4558 uint8_t retval; 4559 4560 ASSERT(bscv_held(ssp)); 4561 4562 bscv_trace(ssp, 'P', "bscv_do_page_data_once", "index 0x%x", index); 4563 4564 /* write PSIZ bytes to PDAT */ 4565 if (index + pagesize < image_size) { 4566 bscv_rep_rw8(ssp, chan_prog, imagep + index, 4567 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_DATA), 4568 pagesize, DDI_DEV_NO_AUTOINCR, B_TRUE /* write */); 4569 size = pagesize; 4570 } else { 4571 bscv_trace(ssp, 'P', "bscv_do_page_once", 4572 "Sending last block, last 0x%x bytes", 4573 (image_size % pagesize)); 4574 size = (image_size - index); 4575 bscv_rep_rw8(ssp, chan_prog, imagep + index, 4576 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_DATA), 4577 size, DDI_DEV_NO_AUTOINCR, B_TRUE /* write */); 4578 /* Now pad the rest of the page with zeros */ 4579 for (i = size; i < pagesize; i++) { 4580 bscv_put8(ssp, chan_prog, 4581 BSCVA(EBUS_CMD_SPACE_PROGRAM, 4582 EBUS_PROGRAM_DATA), 4583 0); 4584 } 4585 } 4586 4587 /* write the checksum to PCSM */ 4588 chksum = 0; 4589 for (i = 0; i < size; i++) { 4590 chksum = ((chksum << 3) | (chksum >> 13)) ^ 4591 *(imagep + index + i); 4592 } 4593 /* Cope with non-pagesize sized bufers */ 4594 for (; i < pagesize; i++) { 4595 chksum = ((chksum << 3) | (chksum >> 13)) ^ 0; 4596 } 4597 bscv_put16(ssp, chan_prog, 4598 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSM0), chksum); 4599 4600 bscv_put8(ssp, chan_prog, 4601 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), 4602 EBUS_PROGRAM_PCR_PROGRAM); 4603 4604 retval = bscv_get8(ssp, chan_prog, 4605 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR)); 4606 4607 *calcd_chksum = chksum; 4608 return (retval); 4609 } 4610 4611 static uint8_t bscv_do_page(bscv_soft_state_t *ssp, uint32_t loadaddr, 4612 uint32_t index, uint32_t image_size, uint32_t pagesize, uint8_t *imagep, 4613 boolean_t is_image2) 4614 { 4615 int retryable = BSC_PAGE_RETRY_LIMIT; 4616 uint8_t retval; 4617 uint16_t checksum; 4618 4619 bscv_trace(ssp, 'P', "bscv_do_page", "index 0x%x", index); 4620 4621 while (retryable--) { 4622 /* 4623 * Set the page address (with retries). If this is not 4624 * successful, then there is no point carrying on and sending 4625 * the page's data since that could cause random memory 4626 * corruption in the microcontroller. 4627 */ 4628 retval = bscv_set_page(ssp, loadaddr + index); 4629 if (!PSR_SUCCESS(retval)) { 4630 cmn_err(CE_WARN, "programming error 0x%x, " 4631 "could not setup page address 0x%x, %s image", 4632 retval, loadaddr + index, 4633 is_image2 ? "main" : "loader"); 4634 break; 4635 } 4636 4637 /* 4638 * Send down the data for the page 4639 */ 4640 4641 bscv_trace(ssp, 'P', "bscv_do_page", "sending data for page"); 4642 4643 retval = bscv_do_page_data_once(ssp, index, image_size, 4644 pagesize, imagep, &checksum); 4645 if (PSR_SUCCESS(retval)) 4646 break; 4647 else 4648 cmn_err(CE_WARN, "programming error 0x%x," 4649 " attempt %d, index 0x%x, checksum 0x%x, %s image", 4650 retval, BSC_PAGE_RETRY_LIMIT - retryable, 4651 index, checksum, is_image2 ? "main" : "loader"); 4652 } 4653 4654 bscv_trace(ssp, 'U', "bscv_do_page", "Returning 0x%x for index 0x%x," 4655 " checksum 0x%x, %s image", retval, index, checksum, 4656 is_image2 ? "main" : "loader"); 4657 4658 return (retval); 4659 } 4660 4661 static uint8_t 4662 bscv_do_pages(bscv_soft_state_t *ssp, uint32_t loadaddr, uint32_t image_size, 4663 uint32_t pagesize, uint8_t *imagep, boolean_t is_image2) 4664 { 4665 uint8_t retval; 4666 uint32_t index; 4667 4668 bscv_trace(ssp, 'P', "bscv_do_pages", "entered"); 4669 4670 for (index = 0; index < image_size; index += pagesize) { 4671 retval = bscv_do_page(ssp, loadaddr, index, image_size, 4672 pagesize, imagep, is_image2); 4673 if (bscv_faulty(ssp) || !PSR_SUCCESS(retval)) { 4674 bscv_trace(ssp, 'U', "bscv_do_pages", 4675 "Failed to program lom (status 0x%x)", retval); 4676 break; 4677 } 4678 } 4679 4680 return (retval); 4681 } 4682 4683 static int 4684 bscv_prog_image(bscv_soft_state_t *ssp, boolean_t is_image2, 4685 uint8_t *imagep, int image_size, uint32_t loadaddr) 4686 { 4687 uint32_t pagesize; 4688 int res = 0; 4689 uint8_t retval; 4690 4691 bscv_trace(ssp, 'U', "bscv_prog_image", 4692 "image 0x%x, imagep %p, size 0x%x", 4693 is_image2 ? 2 : 1, imagep, image_size); 4694 4695 if (!bscv_check_loader_config(ssp, is_image2)) 4696 /* 4697 * Return no error to allow userland to continue on with 4698 * downloading the image. 4699 */ 4700 return (0); 4701 4702 bscv_enter(ssp); 4703 4704 pagesize = bscv_get_pagesize(ssp); 4705 4706 retval = bscv_enter_programming_mode(ssp); 4707 if (bscv_faulty(ssp) || !PSR_PROG(retval)) { 4708 cmn_err(CE_WARN, "lom: Failed to enter program mode, error 0x%x" 4709 ", %s image", retval, is_image2 ? "main" : "loader"); 4710 res = EIO; 4711 goto BSCV_PROG_IMAGE_END; 4712 } 4713 bscv_trace(ssp, 'U', "bscv_prog_image", "entered programming mode"); 4714 4715 /* 4716 * Only issue an erase if we are downloading the image. The loader 4717 * does not need this step. 4718 */ 4719 if (is_image2 && (image_size != 0)) { 4720 retval = bscv_do_erase(ssp, loadaddr, image_size, is_image2); 4721 if (bscv_faulty(ssp) || !PSR_SUCCESS(retval)) { 4722 cmn_err(CE_WARN, 4723 "lom: Erase failed during programming, status 0x%x", 4724 retval); 4725 res = EIO; 4726 goto BSCV_PROG_IMAGE_END; 4727 } else { 4728 bscv_trace(ssp, 'U', "bscv_prog_image", 4729 "erase complete - programming..."); 4730 4731 } 4732 } 4733 4734 (void) bscv_set_pagesize(ssp, pagesize); 4735 4736 retval = bscv_do_pages(ssp, loadaddr, image_size, pagesize, imagep, 4737 is_image2); 4738 if (bscv_faulty(ssp) || !PSR_SUCCESS(retval)) { 4739 bscv_trace(ssp, 'U', "bscv_prog_image", 4740 "Failed to program lom (status 0x%x)", retval); 4741 res = EIO; 4742 goto BSCV_PROG_IMAGE_END; 4743 } 4744 4745 BSCV_PROG_IMAGE_END: 4746 if (res == 0 && !is_image2) { 4747 /* 4748 * We've downloaded the loader successfully. Now make the 4749 * microcontroller jump to it. 4750 */ 4751 bscv_set_jump_to_addr(ssp, loadaddr); 4752 ssp->loader_running = B_TRUE; 4753 bscv_leave_programming_mode(ssp, B_TRUE); 4754 } else { 4755 /* 4756 * We've just downloaded either the loader which failed, or 4757 * the image (which may or may not have been successful). 4758 */ 4759 bscv_set_jump_to_addr(ssp, 0); 4760 4761 if (res != 0) { 4762 bscv_trace(ssp, 'U', "bscv_prog_image", 4763 "got error 0x%x - leaving programming mode", 4764 res); 4765 cmn_err(CE_WARN, "programming error 0x%x, %s image", 4766 res, is_image2 ? "main" : "loader"); 4767 } else { 4768 bscv_trace(ssp, 'U', "bscv_prog_image", 4769 "programming complete - leaving programming mode"); 4770 } 4771 4772 bscv_leave_programming_mode(ssp, B_FALSE); 4773 ssp->loader_running = B_FALSE; 4774 } 4775 4776 bscv_exit(ssp); 4777 4778 return (res); 4779 } 4780 4781 4782 static int 4783 bscv_prog_receive_image(bscv_soft_state_t *ssp, lom_prog_t *prog, 4784 uint8_t *imagep, int max_size) 4785 { 4786 int res = 0; 4787 uint_t size; 4788 int32_t loadaddr; 4789 lom_prog_data_t *prog_data; 4790 4791 if ((prog->index & 0x7FFF) != ssp->prog_index) { 4792 bscv_trace(ssp, 'U', "bscv_prog_receive_image", 4793 "Got wrong buffer 0x%x, expected 0x%x", 4794 prog->index & 0x7fff, ssp->prog_index); 4795 return (EINVAL); 4796 } 4797 4798 /* 4799 * We want to get the whole image and then do the download. 4800 * It is assumed the device is now in programming mode. 4801 */ 4802 4803 if ((prog->index & 0x7fff) == 0) { 4804 /* Starting a new image */ 4805 ssp->image_ptr = 0; 4806 } 4807 4808 if ((ssp->image_ptr + prog->size) > max_size) { 4809 cmn_err(CE_WARN, 4810 "lom image exceeded maximum size: got 0x%x, maximum 0x%x", 4811 (ssp->image_ptr + prog->size), max_size); 4812 return (EFAULT); 4813 } 4814 bcopy(prog->data, &imagep[ssp->image_ptr], prog->size); 4815 ssp->image_ptr += prog->size; 4816 4817 ssp->prog_index++; 4818 4819 if (prog->index & 0x8000) { 4820 /* 4821 * OK we have the whole image so synch up and start download. 4822 */ 4823 prog_data = (lom_prog_data_t *)imagep; 4824 if (prog_data->header.magic != PROG_MAGIC) { 4825 /* Old style programming data */ 4826 /* Take care image may not fill all of structure */ 4827 4828 /* sign extend loadaddr from 16 to 32 bits */ 4829 loadaddr = (int16_t)((uint16_t)((imagep[2] << 8) + 4830 imagep[3])); 4831 4832 size = (imagep[0] << 8) + imagep[1]; 4833 if (size != (ssp->image_ptr - 4)) { 4834 cmn_err(CE_WARN, "Image size mismatch:" 4835 " expected 0x%x, got 0x%x", 4836 size, (ssp->image_ptr - 1)); 4837 } 4838 4839 res = bscv_prog_image(ssp, 4840 ssp->image2_processing, 4841 imagep + 4, ssp->image_ptr - 4, loadaddr); 4842 4843 /* 4844 * Done the loading so set the flag to say we are doing 4845 * the other image. 4846 */ 4847 ssp->image2_processing = !ssp->image2_processing; 4848 } else if ((ssp->image_ptr < sizeof (*prog_data)) || 4849 (prog_data->platform.bscv.size != 4850 (ssp->image_ptr - sizeof (*prog_data)))) { 4851 /* Image too small for new style image */ 4852 cmn_err(CE_WARN, "image too small"); 4853 res = EINVAL; 4854 } else { 4855 /* New style programming image */ 4856 switch (prog_data->platmagic) { 4857 case PROG_PLAT_BSCV_IMAGE: 4858 res = bscv_prog_image(ssp, B_TRUE, 4859 imagep + sizeof (*prog_data), 4860 prog_data->platform.bscv.size, 4861 prog_data->platform.bscv.loadaddr); 4862 ssp->image2_processing = B_FALSE; 4863 break; 4864 case PROG_PLAT_BSCV_LOADER: 4865 res = bscv_prog_image(ssp, B_FALSE, 4866 imagep + sizeof (*prog_data), 4867 prog_data->platform.bscv.size, 4868 prog_data->platform.bscv.loadaddr); 4869 ssp->image2_processing = B_TRUE; 4870 break; 4871 default: 4872 cmn_err(CE_WARN, "unknown platmagic 0x%x", 4873 prog_data->platmagic); 4874 res = EINVAL; 4875 break; 4876 } 4877 } 4878 ssp->prog_index = 0; 4879 ssp->image_ptr = 0; 4880 } 4881 return (res); 4882 } 4883 4884 static int 4885 bscv_prog_stop_lom(bscv_soft_state_t *ssp) 4886 { 4887 if (ssp->programming) { 4888 /* 4889 * Already programming - this may be a retry of a failed 4890 * programming attempt or just a software error! 4891 */ 4892 goto queue_stopped; 4893 } 4894 4895 if (bscv_pause_event_daemon(ssp) == BSCV_FAILURE) { 4896 bscv_trace(ssp, 'Q', "bscv_prog_stop_lom", 4897 "failed to pause event daemon thread"); 4898 return (EAGAIN); 4899 } 4900 4901 bscv_enter(ssp); 4902 4903 ssp->programming = B_TRUE; 4904 4905 bscv_exit(ssp); 4906 4907 queue_stopped: 4908 4909 ssp->prog_index = 0; 4910 ssp->image2_processing = B_FALSE; 4911 4912 return (0); 4913 } 4914 4915 static int 4916 bscv_prog_start_lom(bscv_soft_state_t *ssp) 4917 { 4918 int res = 0; 4919 4920 if (!ssp->programming) { 4921 /* Not programming so this is not a valid command */ 4922 return (EINVAL); 4923 } 4924 4925 if (ssp->image != NULL) { 4926 kmem_free((void *)ssp->image, BSC_IMAGE_MAX_SIZE); 4927 ssp->image = NULL; 4928 } 4929 4930 /* 4931 * OK we are out of reset now so: 4932 * Probe the firmware and set everything up. 4933 */ 4934 4935 bscv_enter(ssp); 4936 4937 /* Explicit clear fault because things may have been mended now */ 4938 bscv_clear_fault(ssp); 4939 4940 if (ssp->loader_running) { 4941 cmn_err(CE_WARN, "Firmware upgrade failed to exit loader - " 4942 "performing forced exit"); 4943 /* Must try to restart the lom here. */ 4944 /* Ensure prog mode entry to enable PRGMODE_OFF */ 4945 bscv_put8(ssp, chan_prog, 4946 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), 4947 EBUS_PROGRAM_PCR_PRGMODE_ON); 4948 bscv_put8(ssp, chan_prog, 4949 BSCVA(EBUS_CMD_SPACE_PROGRAM, EBUS_PROGRAM_PCSR), 4950 EBUS_PROGRAM_PCR_PRGMODE_OFF); 4951 ssp->loader_running = B_FALSE; 4952 /* give the lom chance to recover */ 4953 delay(drv_usectohz(5000000)); /* 5 seconds */ 4954 } 4955 4956 ssp->prog_mode_only = B_FALSE; 4957 ssp->programming = B_FALSE; 4958 4959 if (bscv_attach_common(ssp) == DDI_FAILURE) { 4960 ssp->prog_mode_only = B_TRUE; 4961 res = EIO; 4962 } 4963 4964 bscv_exit(ssp); 4965 4966 if (!ssp->prog_mode_only) { 4967 /* 4968 * Start the event thread after the queue has started 4969 * 4970 * Not sure if this is entirely correct because 4971 * the other code at the end of bscv_attach() 4972 * does not get run here. 4973 */ 4974 bscv_start_event_daemon(ssp); 4975 bscv_resume_event_daemon(ssp); 4976 } 4977 4978 return (res); 4979 } 4980 4981 4982 /* 4983 * ********************************************************************* 4984 * Attach processing 4985 * ********************************************************************* 4986 */ 4987 4988 /* 4989 * function - bscv_attach_common 4990 * description - this routine co-ordinates the initialisation of the 4991 * driver both at attach time and after firmware programming. 4992 * sequence - bscv_setup_capability - read LOMlite2 capabilities 4993 * bscv_probe_check - test comms and setup register cache 4994 * bscv_setup_hostname - sync stored name in lom with nodename. 4995 * bscv_setup_static_info - read device names etc. 4996 * bscv_setup_events - start event daemon etc. 4997 * 4998 * inputs - device information structure, DDI_ATTACH command 4999 * outputs - DDI_SUCCESS or DDI_FAILURE 5000 */ 5001 5002 static int 5003 bscv_attach_common(bscv_soft_state_t *ssp) 5004 { 5005 ASSERT(bscv_held(ssp)); 5006 5007 bscv_trace(ssp, 'A', "bscv_attach_common:", ""); 5008 5009 /* 5010 * Set the threshold for reporting messages to the console to 5011 * Warnings or higher. 5012 */ 5013 ssp->reporting_level = 2; 5014 5015 /* 5016 * When the system is not running the Operating System, make 5017 * the microcontroller print event messages straight onto the 5018 * console. 5019 */ 5020 ssp->serial_reporting = LOM_SER_EVENTS_DEF; 5021 5022 /* Setup capabilities */ 5023 bscv_setup_capability(ssp); 5024 5025 if (bscv_probe_check(ssp) == DDI_FAILURE) { 5026 cmn_err(CE_WARN, "BSC chip not responding"); 5027 /* 5028 * We want lom -G to talk to this driver upon broken firmware 5029 * so we prematurely return success here. 5030 */ 5031 return (DDI_SUCCESS); 5032 } 5033 5034 bscv_setup_hostname(ssp); 5035 bscv_setup_static_info(ssp); 5036 bscv_setup_events(ssp); 5037 5038 #if defined(__i386) || defined(__amd64) 5039 bscv_inform_bsc(ssp, BSC_INFORM_ONLINE); 5040 #endif /* __i386 || __amd64 */ 5041 /* 5042 * Watchdog configuration and CPU signatures are sent asynchronously 5043 * with respect to attach so only inform the BSC if we've already 5044 * sent the data in the past. 5045 */ 5046 5047 if (ssp->progress & BSCV_WDOG_CFG) 5048 bscv_setup_watchdog(ssp); 5049 5050 #ifdef __sparc 5051 if (ssp->progress & BSCV_SIG_SENT) 5052 bscv_write_sig(ssp, ssp->last_sig); 5053 #endif /* __sparc */ 5054 5055 return (DDI_SUCCESS); 5056 } 5057 5058 /* 5059 * function - bscv_cleanup 5060 * description - routine that does the necessary tidying up if the attach 5061 * request fails or the driver is to be detached. 5062 * If the event thread has been started we may fail to 5063 * stop it (because it is busy) so we fail the cleanup 5064 * and hence the detach. All other calls to bscv_cleanup 5065 * are done before the event daemon is started. 5066 * inputs - soft state structure address. 5067 * outputs - DDI_SUCCESS or DDI_FAILURE. 5068 */ 5069 5070 static int 5071 bscv_cleanup(bscv_soft_state_t *ssp) 5072 { 5073 int instance; 5074 uint8_t bits2set; 5075 uint8_t bits2clear; 5076 5077 instance = ssp->instance; 5078 5079 if (ssp->progress & BSCV_LOCKS) { 5080 bscv_enter(ssp); 5081 } 5082 5083 if (ssp->progress & BSCV_THREAD) { 5084 if (bscv_stop_event_daemon(ssp) == DDI_FAILURE) { 5085 /* Fail the cleanup - may be able to cleanup later */ 5086 if (ssp->progress & BSCV_LOCKS) { 5087 bscv_exit(ssp); 5088 } 5089 return (DDI_FAILURE); 5090 } 5091 } 5092 5093 if (ssp->progress & BSCV_NODES) { 5094 ddi_remove_minor_node(ssp->dip, NULL); 5095 } 5096 5097 if (ssp->progress & BSCV_MAPPED_REGS) { 5098 /* 5099 * switch back on serial event reporting - cover all configs. 5100 */ 5101 bits2set = 0; 5102 bits2clear = 0; 5103 if (ssp->serial_reporting == LOM_SER_EVENTS_ON) { 5104 bits2clear |= EBUS_ALARM_NOEVENTS; 5105 } else if (ssp->serial_reporting == LOM_SER_EVENTS_OFF) { 5106 bits2set |= EBUS_ALARM_NOEVENTS; 5107 } else if (ssp->serial_reporting == LOM_SER_EVENTS_DEF) { 5108 bits2clear |= EBUS_ALARM_NOEVENTS; 5109 } 5110 bscv_setclear8_volatile(ssp, chan_general, EBUS_IDX_ALARM, 5111 bits2set, bits2clear); 5112 5113 /* 5114 * disable the reset function if we have enabled 5115 * it. We don't want any nasty surprises like system 5116 * rebooting unexpectedly. If we timeout on the busy 5117 * flag we just have to carry on. 5118 */ 5119 5120 bscv_trace(ssp, 'W', "bscv_cleanup", 5121 "bscv_cleanup - disable wdog"); 5122 if (bscv_get8_cached(ssp, EBUS_IDX_WDOG_CTRL) & 5123 EBUS_WDOG_ENABLE) { 5124 bscv_setclear8(ssp, chan_general, EBUS_IDX_WDOG_CTRL, 5125 0, EBUS_WDOG_RST | EBUS_WDOG_ENABLE); 5126 } 5127 } 5128 5129 /* 5130 * unmap registers 5131 */ 5132 5133 if (ssp->progress & BSCV_MAPPED_REGS) { 5134 bscv_unmap_regs(ssp); 5135 } 5136 5137 /* 5138 * release any memory allocated for mutexes and condition 5139 * variables before deallocating the structures containing them 5140 */ 5141 5142 if (ssp->progress & BSCV_LOCKS) { 5143 bscv_exit(ssp); 5144 cv_destroy(&ssp->task_cv); 5145 cv_destroy(&ssp->task_evnt_cv); 5146 mutex_destroy(&ssp->task_mu); 5147 mutex_destroy(&ssp->prog_mu); 5148 mutex_destroy(&ssp->cmd_mutex); 5149 } 5150 5151 if (ssp->image != NULL) { 5152 kmem_free((void *)ssp->image, BSC_IMAGE_MAX_SIZE); 5153 } 5154 5155 #if defined(__i386) || defined(__amd64) 5156 bscv_watchdog_cyclic_remove(ssp); 5157 #endif /* __i386 || __amd64 */ 5158 ddi_soft_state_free(bscv_statep, instance); 5159 5160 return (DDI_SUCCESS); 5161 } 5162 5163 /* 5164 * function - bscv_setup_capability 5165 * description - probe the lom find what capabilities are present for 5166 * us to use. 5167 * inputs - soft state ptr 5168 * outputs - returns DDI_SUCCESS or DDI_FAILURE 5169 */ 5170 static void bscv_setup_capability(bscv_soft_state_t *ssp) 5171 { 5172 ASSERT(bscv_held(ssp)); 5173 5174 if (ssp->prog_mode_only) { 5175 /* Turn off all capabilities */ 5176 ssp->cap0 = 0; 5177 ssp->cap1 = 0; 5178 ssp->cap2 = 0; 5179 return; 5180 } 5181 5182 ssp->cap0 = bscv_get8(ssp, chan_general, EBUS_IDX_CAP0); 5183 ssp->cap1 = bscv_get8(ssp, chan_general, EBUS_IDX_CAP1); 5184 ssp->cap2 = bscv_get8(ssp, chan_general, EBUS_IDX_CAP2); 5185 if (!bscv_faulty(ssp)) { 5186 bscv_trace(ssp, 'A', "bscv_setup_capability", 5187 "Capability flags cap0=0x%x cap1=0x%x, cap2=0x%x", 5188 ssp->cap0, ssp->cap1, ssp->cap2); 5189 } else { 5190 cmn_err(CE_WARN, "!Could not read capability flags"); 5191 ssp->cap0 = 0; ssp->cap1 = 0; ssp->cap2 = 0; 5192 } 5193 } 5194 5195 /* 5196 * function - bscv_probe_check 5197 * description - probe the lom to check for correct operation 5198 * has a side effect of setting up the cached registers and 5199 * updates ssp->prog_mode_only. 5200 * inputs - soft state ptr 5201 * outputs - returns DDI_SUCCESS or DDI_FAILURE 5202 */ 5203 5204 static int bscv_probe_check(bscv_soft_state_t *ssp) 5205 { 5206 int i; 5207 uint8_t probeval; 5208 5209 ASSERT(bscv_held(ssp)); 5210 5211 bscv_trace(ssp, 'A', "bscv_probe_check", ""); 5212 5213 if (!ssp->prog_mode_only) { 5214 /* 5215 * Make sure probe location is OK so that we are 5216 * in sync. 5217 * We want to make sure that this is not faulty so we 5218 * do a bscv_clear_fault to clear any existing 5219 * fault records down. 5220 */ 5221 bscv_clear_fault(ssp); 5222 probeval = bscv_get8(ssp, chan_general, EBUS_IDX_PROBEAA); 5223 if (bscv_faulty(ssp)) { 5224 ssp->prog_mode_only = B_TRUE; 5225 } else if (probeval != 0xAA) { 5226 bscv_trace(ssp, 'A', "bscv_probe_check", 5227 "LOMlite out of sync"); 5228 5229 /* 5230 * It may be that the LOMlite was out of 5231 * sync so lets try the read again. 5232 */ 5233 probeval = bscv_get8(ssp, chan_general, 5234 EBUS_IDX_PROBEAA); 5235 if (bscv_faulty(ssp)) { 5236 bscv_trace(ssp, 'A', "bscv_probe_check", 5237 "Init readAA1 failed"); 5238 ssp->prog_mode_only = B_TRUE; 5239 } else if (probeval != 0xAA) { 5240 /* 5241 * OK that is twice we are out so I 5242 * guess the LOMlite is in trouble 5243 */ 5244 bscv_trace(ssp, 'A', "bscv_probe_check", 5245 "Init readAA probe failed - got 0x%x", 5246 probeval); 5247 ssp->prog_mode_only = B_TRUE; 5248 } 5249 } 5250 } 5251 5252 /* 5253 * Read in all page zero lom registers. 5254 * Read state change 1st so we dont miss anything and clear it. 5255 * Note: we discard the values because we rely on bscv_get8 to 5256 * setup the cache of register values. 5257 */ 5258 5259 if (!ssp->prog_mode_only) { 5260 (void) bscv_get8(ssp, chan_general, EBUS_IDX_STATE_CHNG); 5261 if (bscv_faulty(ssp)) { 5262 bscv_trace(ssp, 'A', "bscv_probe_check", 5263 "Read of state change register failed"); 5264 ssp->prog_mode_only = B_TRUE; 5265 } 5266 } 5267 5268 if (!ssp->prog_mode_only) { 5269 for (i = 1; i < 0x80; i++) { 5270 switch (i) { 5271 case EBUS_IDX_STATE_CHNG: 5272 case EBUS_IDX_CMD_RES: 5273 case EBUS_IDX_HNAME_CHAR: 5274 /* 5275 * Should not read these - they have side 5276 * effects. 5277 */ 5278 break; 5279 default: 5280 (void) bscv_get8(ssp, chan_general, i); 5281 break; 5282 } 5283 if (bscv_faulty(ssp)) { 5284 bscv_trace(ssp, 'A', "bscv_probe_check", 5285 "Initial read or register %2x failed", i); 5286 ssp->prog_mode_only = B_TRUE; 5287 /* Might as well give up now! */ 5288 break; 5289 } 5290 } 5291 } 5292 5293 /* 5294 * Check the probe keys so we know the lom is OK 5295 */ 5296 5297 if (!ssp->prog_mode_only) { 5298 if ((bscv_get8_cached(ssp, EBUS_IDX_PROBE55) != 0x55) || 5299 (bscv_get8_cached(ssp, EBUS_IDX_PROBEAA) != 0xAA)) { 5300 5301 bscv_trace(ssp, 'A', "bscv_probe_check", 5302 "LOMlite Probe failed"); 5303 for (i = 0; i < 0x8; i++) { 5304 bscv_trace(ssp, 'A', "bscv_probe_check", 5305 "%2x %2x %2x %2x %2x %2x %2x %2x %2x " 5306 "%2x %2x %2x %2x %2x %2x %2x %2x %2x", 5307 bscv_get8_cached(ssp, i), 5308 bscv_get8_cached(ssp, i + 1), 5309 bscv_get8_cached(ssp, i + 2), 5310 bscv_get8_cached(ssp, i + 3), 5311 bscv_get8_cached(ssp, i + 4), 5312 bscv_get8_cached(ssp, i + 5), 5313 bscv_get8_cached(ssp, i + 6), 5314 bscv_get8_cached(ssp, i + 7), 5315 bscv_get8_cached(ssp, i + 8), 5316 bscv_get8_cached(ssp, i + 9), 5317 bscv_get8_cached(ssp, i + 10), 5318 bscv_get8_cached(ssp, i + 11), 5319 bscv_get8_cached(ssp, i + 12), 5320 bscv_get8_cached(ssp, i + 13), 5321 bscv_get8_cached(ssp, i + 14), 5322 bscv_get8_cached(ssp, i + 15)); 5323 } 5324 ssp->prog_mode_only = B_TRUE; 5325 } 5326 } 5327 5328 return ((ssp->prog_mode_only == B_FALSE) ? DDI_SUCCESS : DDI_FAILURE); 5329 } 5330 5331 #ifdef __sparc 5332 /* 5333 * function - bscv_idi_set 5334 * description - bscv inter driver interface set function 5335 * inputs - structure which defines type of service required and data 5336 * ouputs - none 5337 * 5338 * This is the Entry Point function for the platmod driver. It works out which 5339 * X Bus channel ought to deliver the service requested. 5340 */ 5341 void 5342 bscv_idi_set(struct bscv_idi_info info) 5343 { 5344 struct bscv_idi_callout *tbl; 5345 boolean_t retval; 5346 5347 ASSERT(bscv_idi_mgr.magic == BSCV_IDI_CALLOUT_MAGIC); 5348 5349 if (bscv_idi_mgr.tbl == NULL) { 5350 if (bscv_idi_err()) 5351 cmn_err(CE_WARN, "!bscv_idi_set : cannot find " 5352 "bscv_callout_table"); 5353 return; 5354 } else if (bscv_idi_mgr.valid_inst == (uint32_t)~0) { 5355 if (bscv_idi_err()) 5356 /* 5357 * This error message can appear in the context of 5358 * another driver, say platmod or todblade. We want 5359 * to clearly indicate the culprit driver so put in 5360 * the driver name. 5361 */ 5362 cmn_err(CE_WARN, "!bscv_idi_set : no valid " 5363 "driver instance of " 5364 MYNAME); 5365 return; 5366 } 5367 5368 tbl = bscv_idi_mgr.tbl; 5369 5370 while (tbl->type != BSCV_IDI_NULL) { 5371 if (tbl->type == info.type) { 5372 /* 5373 * We service the request with a valid instance number 5374 * for the driver. 5375 */ 5376 retval = ((tbl->fn) (info)); 5377 5378 /* 5379 * If the request was serviced, clear any accumulated 5380 * error counters so future warnings will be reported if 5381 * seen. 5382 */ 5383 if (retval == B_TRUE) 5384 bscv_idi_clear_err(); 5385 return; 5386 } else { 5387 tbl++; 5388 } 5389 } 5390 5391 if (bscv_idi_err()) 5392 cmn_err(CE_WARN, "!bscv_idi_set : cannot match info.type %d", 5393 info.type); 5394 } 5395 5396 /* 5397 * function - bscv_nodename_set 5398 * description - notify the event thread that a nodename change has occurred. 5399 * inputs - data from client driver 5400 * outputs - none. 5401 * side-effects - the event thread will schedule an update to the lom firmware. 5402 */ 5403 /*ARGSUSED*/ 5404 static boolean_t 5405 bscv_nodename_set(struct bscv_idi_info info) 5406 { 5407 bscv_soft_state_t *ssp; 5408 5409 ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst); 5410 5411 if (ssp == NULL) { 5412 if (bscv_idi_err()) 5413 cmn_err(CE_WARN, "!blade_nodename_set: cannot get ssp"); 5414 return (B_FALSE); 5415 } 5416 5417 /* Get a lock on the SSP, notify our change, then exit */ 5418 mutex_enter(&ssp->task_mu); 5419 ssp->nodename_change = B_TRUE; 5420 cv_signal(&ssp->task_cv); 5421 mutex_exit(&ssp->task_mu); 5422 5423 return (B_TRUE); 5424 } 5425 5426 /* 5427 * function - bscv_sig_set 5428 * description - write a signature 5429 * inputs - data from client driver 5430 * outputs - none. 5431 */ 5432 static boolean_t 5433 bscv_sig_set(struct bscv_idi_info info) 5434 { 5435 bscv_soft_state_t *ssp; 5436 bscv_sig_t sig; 5437 5438 ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst); 5439 5440 if (ssp == NULL) { 5441 if (bscv_idi_err()) 5442 cmn_err(CE_WARN, "!blade_nodename_set: cannot get ssp"); 5443 return (B_FALSE); 5444 } 5445 5446 /* Service the request */ 5447 bcopy(info.data, &sig, sizeof (sig)); 5448 bscv_enter(ssp); 5449 bscv_write_sig(ssp, sig); 5450 bscv_exit(ssp); 5451 5452 return (B_TRUE); 5453 } 5454 #endif /* __sparc */ 5455 5456 static void 5457 bscv_wdog_do_pat(bscv_soft_state_t *ssp) 5458 { 5459 uint8_t pat; 5460 5461 /* 5462 * The value of the dog pat is a sequence number which wraps around, 5463 * bounded by BSCV_WDOG_PAT_SEQ_MASK. 5464 */ 5465 pat = ssp->pat_seq++; 5466 pat &= EBUS_WDOG_NB_PAT_SEQ_MASK; 5467 5468 /* Set top nibble to indicate a pat */ 5469 pat |= EBUS_WDOG_NB_PAT; 5470 5471 /* 5472 * Now pat the dog. This exercises a special protocol in the 5473 * bus nexus that offers : non-blocking IO, and timely delivery, 5474 * callable from high-level interrupt context. The requirement 5475 * on us is that the channel is not shared for any other use. 5476 * This means for chan_wdogpat, nothing may use channel[chan].regs 5477 * or channel.[chan].handle. 5478 */ 5479 5480 ddi_put8(ssp->channel[chan_wdogpat].handle, 5481 ssp->channel[chan_wdogpat].regs, pat); 5482 5483 bscv_trace(ssp, 'W', "bscv_wdog_pat", "patted the dog with seq %d", 5484 pat); 5485 } 5486 5487 #ifdef __sparc 5488 /* 5489 * function - bscv_wdog_pat 5490 * description - pat the watchdog 5491 * inputs - data from client driver 5492 * outputs - none. 5493 */ 5494 /*ARGSUSED*/ 5495 static boolean_t 5496 bscv_wdog_pat(struct bscv_idi_info info) 5497 { 5498 /* 5499 * This function remembers if it has ever been called with the 5500 * configure option set. 5501 */ 5502 bscv_soft_state_t *ssp; 5503 5504 ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst); 5505 5506 if (ssp == NULL) { 5507 if (bscv_idi_err()) 5508 cmn_err(CE_WARN, "!bscv_wdog_pat: cannot get ssp"); 5509 return (B_FALSE); 5510 } else if (ssp->nchannels == 0) { 5511 /* Didn't manage to map handles so ddi_{get,put}* broken */ 5512 if (bscv_idi_err()) 5513 cmn_err(CE_WARN, "!bscv_wdog_pat: handle not mapped"); 5514 return (B_FALSE); 5515 } 5516 5517 bscv_wdog_do_pat(ssp); 5518 return (B_TRUE); 5519 } 5520 5521 /* 5522 * function - bscv_wdog_cfg 5523 * description - configure the watchdog 5524 * inputs - data from client driver 5525 * outputs - none. 5526 */ 5527 static boolean_t 5528 bscv_wdog_cfg(struct bscv_idi_info info) 5529 { 5530 bscv_soft_state_t *ssp; 5531 5532 ssp = ddi_get_soft_state(bscv_statep, bscv_idi_mgr.valid_inst); 5533 5534 if (ssp == NULL) { 5535 if (bscv_idi_err()) 5536 cmn_err(CE_WARN, "!bscv_wdog_cfg: cannot get ssp"); 5537 return (B_FALSE); 5538 } else if (ssp->nchannels == 0) { 5539 /* Didn't manage to map handles so ddi_{get,put}* broken */ 5540 if (bscv_idi_err()) 5541 cmn_err(CE_WARN, "!bscv_wdog_cfg: handle not mapped"); 5542 return (B_FALSE); 5543 } 5544 5545 if (sizeof (bscv_wdog_t) != info.size) { 5546 bscv_trace(ssp, 'W', "bscv_wdog_set", "data passed in is size" 5547 " %d instead of %d", info.size, 5548 sizeof (bscv_wdog_t)); 5549 return (B_FALSE); 5550 } 5551 5552 bscv_trace(ssp, 'W', "bscv_wdog_cfg", "enable_wdog %s, " 5553 "wdog_timeout_s %d, reset_system_on_timeout %s", 5554 ((bscv_wdog_t *)info.data)->enable_wdog ? "enabled" : "disabled", 5555 ((bscv_wdog_t *)info.data)->wdog_timeout_s, 5556 ((bscv_wdog_t *)info.data)->reset_system_on_timeout ? "yes" : "no"); 5557 bscv_write_wdog_cfg(ssp, 5558 ((bscv_wdog_t *)info.data)->wdog_timeout_s, 5559 ((bscv_wdog_t *)info.data)->enable_wdog, 5560 ((bscv_wdog_t *)info.data)->reset_system_on_timeout); 5561 return (B_TRUE); 5562 } 5563 #endif /* __sparc */ 5564 5565 static void 5566 bscv_write_wdog_cfg(bscv_soft_state_t *ssp, 5567 uint_t wdog_timeout_s, 5568 boolean_t enable_wdog, 5569 uint8_t reset_system_on_timeout) 5570 { 5571 uint8_t cfg = EBUS_WDOG_NB_CFG; 5572 5573 /* 5574 * Configure the timeout value (1 to 127 seconds). 5575 * Note that a policy is implemented at the bsc/ssp which bounds 5576 * the value further. The bounding here is to fit the timeout value 5577 * into the 7 bits the bsc uses. 5578 */ 5579 if (wdog_timeout_s < 1) 5580 ssp->watchdog_timeout = 1; 5581 else if (wdog_timeout_s > 127) 5582 ssp->watchdog_timeout = 127; 5583 else 5584 ssp->watchdog_timeout = wdog_timeout_s; 5585 5586 /* 5587 * Configure the watchdog on or off. 5588 */ 5589 if (enable_wdog) 5590 cfg |= EBUS_WDOG_NB_CFG_ENB; 5591 else 5592 cfg &= ~EBUS_WDOG_NB_CFG_ENB; 5593 5594 /* 5595 * Configure whether the microcontroller should reset the system when 5596 * the watchdog expires. 5597 */ 5598 ssp->watchdog_reset_on_timeout = reset_system_on_timeout; 5599 5600 ddi_put8(ssp->channel[chan_wdogpat].handle, 5601 ssp->channel[chan_wdogpat].regs, cfg); 5602 5603 /* have the event daemon set the timeout value and whether to reset */ 5604 ssp->watchdog_change = B_TRUE; 5605 5606 bscv_trace(ssp, 'W', "bscv_wdog_cfg", 5607 "configured the dog with cfg 0x%x", cfg); 5608 } 5609 5610 /* 5611 * function - bscv_setup_watchdog 5612 * description - setup the bsc watchdog 5613 * inputs - soft state ptr 5614 * outputs - 5615 */ 5616 static void bscv_setup_watchdog(bscv_soft_state_t *ssp) 5617 { 5618 uint8_t set = 0; 5619 uint8_t clear = 0; 5620 #ifdef __sparc 5621 extern int watchdog_activated; 5622 #endif /* __sparc */ 5623 5624 ASSERT(bscv_held(ssp)); 5625 5626 /* Set the timeout */ 5627 bscv_put8(ssp, chan_general, 5628 EBUS_IDX_WDOG_TIME, ssp->watchdog_timeout); 5629 5630 /* Set whether to reset the system on timeout */ 5631 if (ssp->watchdog_reset_on_timeout) { 5632 set |= EBUS_WDOG_RST; 5633 } else { 5634 clear |= EBUS_WDOG_RST; 5635 } 5636 5637 if (watchdog_activated) { 5638 set |= EBUS_WDOG_ENABLE; 5639 } else { 5640 clear |= EBUS_WDOG_ENABLE; 5641 } 5642 5643 /* Set other host defaults */ 5644 clear |= (EBUS_WDOG_BREAK_DISABLE | EBUS_WDOG_AL3_FANPSU 5645 | EBUS_WDOG_AL3_WDOG); 5646 5647 bscv_setclear8_volatile(ssp, chan_general, EBUS_IDX_WDOG_CTRL, 5648 set, clear); 5649 5650 #if defined(__i386) || defined(__amd64) 5651 /* start the cyclic based watchdog patter */ 5652 bscv_watchdog_cyclic_add(ssp); 5653 #endif /* __i386 || __amd64 */ 5654 ssp->progress |= BSCV_WDOG_CFG; 5655 } 5656 5657 5658 /* 5659 * function - bscv_setup_hostname 5660 * description - setup the lom hostname if different from the nodename 5661 * inputs - soft state ptr 5662 * outputs - none 5663 */ 5664 5665 static void bscv_setup_hostname(bscv_soft_state_t *ssp) 5666 { 5667 char host_nodename[128]; 5668 char lom_nodename[128]; 5669 size_t hostlen; 5670 size_t nodelen; 5671 5672 ASSERT(bscv_held(ssp)); 5673 5674 /* 5675 * Check machine label is the same as the 5676 * system nodename. 5677 */ 5678 (void) strncpy(host_nodename, utsname.nodename, 5679 sizeof (host_nodename)); 5680 5681 /* read in lom hostname */ 5682 bscv_read_hostname(ssp, lom_nodename); 5683 5684 /* Enforce null termination */ 5685 host_nodename[sizeof (host_nodename) - 1] = '\0'; 5686 lom_nodename[sizeof (lom_nodename) - 1] = '\0'; 5687 5688 hostlen = (size_t)bscv_get8(ssp, chan_general, EBUS_IDX_HNAME_LENGTH); 5689 nodelen = (size_t)strlen(host_nodename); 5690 if ((nodelen > 0) && 5691 ((hostlen != nodelen) || (strcmp((const char *)&lom_nodename, 5692 (const char *)&host_nodename)) || 5693 (hostlen == 0))) { 5694 bscv_trace(ssp, 'A', "bscv_setup_hostname", 5695 "nodename(%s,%d) != bsc label(%s,%d)", 5696 host_nodename, nodelen, lom_nodename, hostlen); 5697 5698 /* Write new label into LOM EEPROM */ 5699 bscv_write_hostname(ssp, 5700 host_nodename, 5701 (uint8_t)strlen(host_nodename)); 5702 } 5703 5704 ssp->progress |= BSCV_HOSTNAME_DONE; 5705 } 5706 5707 /* 5708 * function - bscv_read_hostname 5709 * description - read the current hostname from the lom 5710 * inputs - soft state pointer and buffer to store the hostname in. 5711 * outputs - none 5712 */ 5713 5714 static void 5715 bscv_read_hostname(bscv_soft_state_t *ssp, char *lom_nodename) 5716 { 5717 int num_failures; 5718 boolean_t needretry; 5719 int length; 5720 int i; 5721 5722 ASSERT(bscv_held(ssp)); 5723 5724 /* 5725 * We have a special failure case here because a retry of a read 5726 * causes data to be lost. Thus we handle the retries ourselves 5727 * and are also responsible for detemining if the lom is faulty 5728 */ 5729 for (num_failures = 0; 5730 num_failures < BSC_FAILURE_RETRY_LIMIT; 5731 num_failures++) { 5732 bscv_clear_fault(ssp); 5733 length = bscv_get8(ssp, chan_general, EBUS_IDX_HNAME_LENGTH); 5734 if (bscv_faulty(ssp)) { 5735 needretry = 1; 5736 } else { 5737 needretry = 0; 5738 for (i = 0; i < length; i++) { 5739 lom_nodename[i] = bscv_get8_once(ssp, 5740 chan_general, EBUS_IDX_HNAME_CHAR); 5741 /* Retry on any error */ 5742 if (bscv_retcode(ssp) != 0) { 5743 needretry = 1; 5744 break; 5745 } 5746 } 5747 /* null terminate for strcmp later */ 5748 lom_nodename[length] = '\0'; 5749 } 5750 if (!needretry) { 5751 break; 5752 } 5753 /* Force the nodename to be empty */ 5754 lom_nodename[0] = '\0'; 5755 } 5756 5757 if (needretry) { 5758 /* Failure - we ran out of retries */ 5759 cmn_err(CE_WARN, 5760 "bscv_read_hostname: retried %d times, giving up", 5761 num_failures); 5762 ssp->had_fault = B_TRUE; 5763 } else if (num_failures > 0) { 5764 bscv_trace(ssp, 'R', "bscv_read_hostname", 5765 "retried %d times, succeeded", num_failures); 5766 } 5767 } 5768 5769 /* 5770 * function - bscv_write_hostname 5771 * description - write a new hostname to the lom 5772 * inputs - soft state pointer, pointer to new name, name length 5773 * outputs - none 5774 */ 5775 static void 5776 bscv_write_hostname(bscv_soft_state_t *ssp, 5777 char *host_nodename, uint8_t length) 5778 { 5779 int num_failures; 5780 boolean_t needretry; 5781 int i; 5782 5783 ASSERT(bscv_held(ssp)); 5784 5785 /* 5786 * We have a special failure case here because a retry of a read 5787 * causes data to be lost. Thus we handle the retries ourselves 5788 * and are also responsible for detemining if the lom is faulty 5789 */ 5790 for (num_failures = 0; 5791 num_failures < BSC_FAILURE_RETRY_LIMIT; 5792 num_failures++) { 5793 bscv_clear_fault(ssp); 5794 bscv_put8(ssp, chan_general, EBUS_IDX_HNAME_LENGTH, length); 5795 if (bscv_faulty(ssp)) { 5796 needretry = 1; 5797 } else { 5798 needretry = 0; 5799 for (i = 0; i < length; i++) { 5800 bscv_put8_once(ssp, chan_general, 5801 EBUS_IDX_HNAME_CHAR, host_nodename[i]); 5802 /* Retry on any error */ 5803 if (bscv_retcode(ssp) != 0) { 5804 needretry = 1; 5805 break; 5806 } 5807 } 5808 } 5809 if (!needretry) { 5810 break; 5811 } 5812 } 5813 5814 if (needretry) { 5815 /* Failure - we ran out of retries */ 5816 cmn_err(CE_WARN, 5817 "bscv_write_hostname: retried %d times, giving up", 5818 num_failures); 5819 ssp->had_fault = B_TRUE; 5820 } else if (num_failures > 0) { 5821 bscv_trace(ssp, 'R', "bscv_write_hostname", 5822 "retried %d times, succeeded", num_failures); 5823 } 5824 } 5825 5826 /* 5827 * function - bscv_setup_static_info 5828 * description - read in static information from the lom at attach time. 5829 * inputs - soft state ptr 5830 * outputs - none 5831 */ 5832 5833 static void 5834 bscv_setup_static_info(bscv_soft_state_t *ssp) 5835 { 5836 uint8_t addr_space_ptr; 5837 uint16_t mask; 5838 uint8_t fanspeed; 5839 int oldtemps[MAX_TEMPS]; 5840 int8_t temp; 5841 int i; 5842 5843 ASSERT(bscv_held(ssp)); 5844 5845 /* 5846 * Finally read in some static info like device names, 5847 * shutdown enabled, etc before the queue starts. 5848 */ 5849 5850 /* 5851 * To get the volts static info we need address space 2 5852 */ 5853 bzero(&ssp->volts, sizeof (lom_volts_t)); 5854 ssp->volts.num = EBUS_CONFIG2_NSUPPLY_DEC( 5855 bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG2)); 5856 if (ssp->volts.num > MAX_VOLTS) { 5857 cmn_err(CE_WARN, 5858 "lom: firmware reported too many voltage lines. "); 5859 cmn_err(CE_CONT, "Reported %d, maximum is %d", 5860 ssp->volts.num, MAX_VOLTS); 5861 ssp->volts.num = MAX_VOLTS; 5862 } 5863 5864 bscv_trace(ssp, 'A', "bscv_setup_static_info", 5865 "num volts %d", ssp->volts.num); 5866 (void) bscv_read_env_name(ssp, 5867 EBUS_CMD_SPACE2, 5868 EBUS_IDX2_SUPPLY_NAME_START, 5869 EBUS_IDX2_SUPPLY_NAME_END, 5870 ssp->volts.name, 5871 ssp->volts.num); 5872 5873 mask = bscv_get8(ssp, chan_general, BSCVA(EBUS_CMD_SPACE2, 5874 EBUS_IDX2_SUPPLY_FATAL_MASK1)) << 8; 5875 mask |= bscv_get8(ssp, chan_general, BSCVA(EBUS_CMD_SPACE2, 5876 EBUS_IDX2_SUPPLY_FATAL_MASK2)); 5877 5878 for (i = 0; i < ssp->volts.num; i++) { 5879 ssp->volts.shutdown_enabled[i] = 5880 (((mask >> i) & 1) == 0) ? 0 : 1; 5881 } 5882 5883 /* 5884 * Get the temperature static info and populate initial temperatures. 5885 * Do not destroy old temperature values if the new value is not 5886 * known i.e. if the device is inaccessible. 5887 */ 5888 bcopy(ssp->temps.temp, oldtemps, sizeof (oldtemps)); 5889 5890 bzero(&ssp->temps, sizeof (lom_temp_t)); 5891 ssp->temps.num = EBUS_CONFIG2_NTEMP_DEC( 5892 bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG2)); 5893 if (ssp->temps.num > MAX_TEMPS) { 5894 cmn_err(CE_WARN, 5895 "lom: firmware reported too many temperatures being " 5896 "monitored."); 5897 cmn_err(CE_CONT, "Reported %d, maximum is %d", 5898 ssp->temps.num, MAX_TEMPS); 5899 ssp->temps.num = MAX_TEMPS; 5900 } 5901 ssp->temps.num_ov = EBUS_CONFIG3_NOTEMP_DEC( 5902 bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG3)); 5903 if (ssp->temps.num_ov > MAX_TEMPS) { 5904 cmn_err(CE_WARN, 5905 "lom: firmware reported too many over temperatures being " 5906 "monitored."); 5907 cmn_err(CE_CONT, "Reported %d, maximum is %d", 5908 ssp->temps.num_ov, MAX_TEMPS); 5909 ssp->temps.num_ov = MAX_TEMPS; 5910 } 5911 bscv_trace(ssp, 'A', "bscv_setup_static_info", 5912 "num temps %d, over temps %d", 5913 ssp->temps.num, ssp->temps.num_ov); 5914 5915 addr_space_ptr = bscv_read_env_name(ssp, 5916 EBUS_CMD_SPACE4, 5917 EBUS_IDX4_TEMP_NAME_START, 5918 EBUS_IDX4_TEMP_NAME_END, 5919 ssp->temps.name, 5920 ssp->temps.num); 5921 5922 for (i = 0; i < ssp->temps.num; i++) { 5923 ssp->temps.warning[i] = (int8_t)bscv_get8(ssp, chan_general, 5924 BSCVA(EBUS_CMD_SPACE4, EBUS_IDX4_TEMP_WARN1 + i)); 5925 5926 /* 5927 * If shutdown is not enabled then set it as zero so 5928 * it is not displayed by the utility. 5929 */ 5930 if ((bscv_get8(ssp, chan_general, BSCVA(EBUS_CMD_SPACE4, 5931 EBUS_IDX4_TEMP_FATAL_MASK)) >> i) & 0x01) { 5932 ssp->temps.shutdown[i] = (int8_t)bscv_get8(ssp, 5933 chan_general, 5934 BSCVA(EBUS_CMD_SPACE4, EBUS_IDX4_TEMP_SDOWN1 + i)); 5935 } else { 5936 ssp->temps.shutdown[i] = 0; 5937 } 5938 } 5939 5940 for (i = 0; i < ssp->temps.num; i++) { 5941 temp = bscv_get8(ssp, chan_general, EBUS_IDX_TEMP1 + i); 5942 if ((temp <= LOM_TEMP_MAX_VALUE) || 5943 (temp == LOM_TEMP_STATE_NOT_PRESENT)) { 5944 ssp->temps.temp[i] = temp; 5945 } else { 5946 /* New value is not known - use old value */ 5947 ssp->temps.temp[i] = oldtemps[i]; 5948 } 5949 } 5950 5951 /* 5952 * Check for and skip a single 0xff character between the 5953 * temperature and over temperature names 5954 */ 5955 if (bscv_get8(ssp, chan_general, 5956 BSCVA(EBUS_CMD_SPACE4, addr_space_ptr)) == 0xff) { 5957 addr_space_ptr++; 5958 } 5959 5960 (void) bscv_read_env_name(ssp, 5961 EBUS_CMD_SPACE4, 5962 addr_space_ptr, 5963 EBUS_IDX4_TEMP_NAME_END, 5964 ssp->temps.name_ov, 5965 ssp->temps.num_ov); 5966 5967 /* 5968 * To get the CB static info we need address space 3 5969 */ 5970 bzero(&ssp->sflags, sizeof (lom_sflags_t)); 5971 ssp->sflags.num = EBUS_CONFIG3_NBREAKERS_DEC(bscv_get8(ssp, 5972 chan_general, EBUS_IDX_CONFIG3)); 5973 if (ssp->sflags.num > MAX_STATS) { 5974 cmn_err(CE_WARN, 5975 "lom: firmware reported too many status flags."); 5976 cmn_err(CE_CONT, 5977 "Reported %d, maximum is %d", 5978 ssp->sflags.num, MAX_STATS); 5979 ssp->sflags.num = MAX_STATS; 5980 } 5981 bscv_trace(ssp, 'A', "bscv_setup_static_info", 5982 "num sflags %d", ssp->sflags.num); 5983 5984 (void) bscv_read_env_name(ssp, 5985 EBUS_CMD_SPACE3, 5986 EBUS_IDX3_BREAKER_NAME_START, 5987 EBUS_IDX3_BREAKER_NAME_END, 5988 ssp->sflags.name, 5989 ssp->sflags.num); 5990 5991 5992 /* 5993 * To get the fan static info we need address space 5 5994 */ 5995 ssp->num_fans = EBUS_CONFIG_NFAN_DEC( 5996 bscv_get8(ssp, chan_general, EBUS_IDX_CONFIG)); 5997 if (ssp->num_fans > MAX_FANS) { 5998 cmn_err(CE_WARN, 5999 "lom: firmware reported too many fans. "); 6000 cmn_err(CE_CONT, 6001 "Reported %d, maximum is %d", 6002 ssp->num_fans, MAX_FANS); 6003 ssp->num_fans = MAX_FANS; 6004 } 6005 6006 for (i = 0; i < ssp->num_fans; i++) { 6007 fanspeed = bscv_get8(ssp, chan_general, 6008 EBUS_IDX_FAN1_SPEED + i); 6009 if ((fanspeed <= LOM_FAN_MAX_SPEED) || 6010 (fanspeed == LOM_FAN_NOT_PRESENT)) { 6011 /* 6012 * Do not destroy previous values unless the 6013 * value is definitive. 6014 */ 6015 ssp->fanspeed[i] = fanspeed; 6016 } 6017 } 6018 6019 bscv_trace(ssp, 'A', "bscv_setup_static_info", 6020 "num fans %d", ssp->num_fans); 6021 6022 (void) bscv_read_env_name(ssp, 6023 EBUS_CMD_SPACE5, 6024 EBUS_IDX5_FAN_NAME_START, 6025 EBUS_IDX5_FAN_NAME_END, 6026 ssp->fan_names, 6027 ssp->num_fans); 6028 6029 /* Get led static information from address space 10 */ 6030 6031 (void) bscv_read_env_name(ssp, 6032 EBUS_CMD_SPACE_LEDS, 6033 EBUS_IDX10_LED_NAME_START, 6034 EBUS_IDX10_LED_NAME_END, 6035 ssp->led_names, 6036 MAX_LED_ID); 6037 } 6038 6039 /* 6040 * function - bscv_read_env_name 6041 * description - read in static environment names 6042 * warning changes address space and the caller relies 6043 * on this behaviour. 6044 * inputs - soft state ptr, chosen address space, 6045 * start of name data, end of name data, 6046 * name storage, number of names. 6047 * outputs - next address for reading name data. 6048 */ 6049 6050 static uint8_t 6051 bscv_read_env_name(bscv_soft_state_t *ssp, 6052 uint8_t addr_space, 6053 uint8_t addr_start, 6054 uint8_t addr_end, 6055 char namebuf[][MAX_LOM2_NAME_STR], 6056 int numnames) 6057 { 6058 int i; 6059 int nameidx; 6060 int namemax; 6061 unsigned int addr_space_ptr; 6062 uint8_t this_char; 6063 6064 ASSERT(bscv_held(ssp)); 6065 6066 bscv_trace(ssp, 'A', "bscv_read_env_name", 6067 "bscv_read_env_name, space %d, start 0x%x, end 0x%x, numnames %d", 6068 addr_space, addr_start, addr_end, numnames); 6069 6070 addr_space_ptr = addr_start; 6071 6072 for (i = 0; i < numnames; i++) { 6073 nameidx = 0; 6074 namemax = sizeof (namebuf[i]); 6075 bzero(namebuf[i], namemax); 6076 6077 while (addr_space_ptr <= addr_end) { 6078 /* 6079 * Read the current character. 6080 */ 6081 this_char = bscv_get8(ssp, chan_general, 6082 BSCVA(addr_space, addr_space_ptr)); 6083 6084 if (this_char == 0xff) { 6085 /* 6086 * Ran out of names - this must 6087 * be the end of the name. 6088 * This is really an error because 6089 * we have just seen either a non-NUL 6090 * terminated string or the number of 6091 * strings did not match what was 6092 * reported. 6093 */ 6094 break; 6095 } 6096 /* 6097 * We increment the buffer pointer now so that 6098 * it is ready for the next read 6099 */ 6100 addr_space_ptr++; 6101 6102 if (this_char == '\0') { 6103 /* Found end of string - done */ 6104 break; 6105 } 6106 if (nameidx < (namemax - 1)) { 6107 /* 6108 * Buffer not full - record character 6109 * NOTE we always leave room for the NUL 6110 * terminator. 6111 */ 6112 namebuf[i][nameidx++] = this_char; 6113 } 6114 } 6115 /* Ensure null termination */ 6116 namebuf[i][nameidx] = '\0'; 6117 } 6118 /* Clamp addr_space_ptr to 0xff because we return uint8_t */ 6119 if (addr_space_ptr > 0xff) { 6120 addr_space_ptr = 0xff; 6121 } 6122 return (addr_space_ptr); 6123 } 6124 6125 /* 6126 * function - bscv_setup_events 6127 * description - initialise the event reporting code 6128 * inputs - soft state ptr 6129 * outputs - DDI_SUCCESS or DDI_FAILURE 6130 */ 6131 6132 static void 6133 bscv_setup_events(bscv_soft_state_t *ssp) 6134 { 6135 uint8_t bits2set; 6136 uint8_t bits2clear; 6137 6138 ASSERT(bscv_held(ssp)); 6139 6140 /* 6141 * deal with event reporting - cover all cases 6142 */ 6143 6144 bits2set = 0; 6145 bits2clear = 0; 6146 if (ssp->serial_reporting == LOM_SER_EVENTS_ON) { 6147 bits2clear |= EBUS_ALARM_NOEVENTS; 6148 } else if (ssp->serial_reporting == LOM_SER_EVENTS_OFF) { 6149 bits2set |= EBUS_ALARM_NOEVENTS; 6150 } else if (ssp->serial_reporting == LOM_SER_EVENTS_DEF) { 6151 bits2set |= EBUS_ALARM_NOEVENTS; 6152 } 6153 bscv_setclear8_volatile(ssp, chan_general, EBUS_IDX_ALARM, 6154 bits2set, bits2clear); 6155 } 6156 6157 #ifdef __sparc 6158 /* 6159 * function - bscv_write_sig 6160 * description - write out a signature, taking care to deal with any strange 6161 * values for CPU ID 6162 * inputs - soft state ptr, signature 6163 * outputs - none 6164 */ 6165 static void 6166 bscv_write_sig(bscv_soft_state_t *ssp, bscv_sig_t s) 6167 { 6168 ASSERT(bscv_held(ssp)); 6169 6170 /* Upload the signature */ 6171 bscv_put32(ssp, chan_cpusig, 6172 BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_SIG_MSB), 6173 s.sig_info.signature); 6174 6175 /* 6176 * We always write the CPU ID last because this tells the firmware 6177 * that the signature is fully uploaded and therefore to consume the 6178 * data. This is required since the signature is > 1 byte in size 6179 * and we transmit data in single bytes. 6180 */ 6181 if (s.cpu == ~0) { 6182 /* ~0 means the signature applies to any CPU. */ 6183 bscv_put8(ssp, chan_cpusig, 6184 BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_ID), 6185 EBUS_ANY_CPU_ID); 6186 } else { 6187 if (s.cpu > 255) { 6188 /* 6189 * The CPU ID supplied is unexpectedly large. Lets 6190 * just use the bottom bits, in case other high order 6191 * bits are being used for special meaning. 6192 */ 6193 cmn_err(CE_WARN, "CPU Signature ID 0x%x > 255", s.cpu); 6194 s.cpu %= 256; 6195 cmn_err(CE_CONT, "using ID 0x%x instead ", s.cpu); 6196 } 6197 bscv_put8(ssp, chan_cpusig, 6198 BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_ID), 6199 (uint8_t)s.cpu); 6200 } 6201 6202 ssp->last_sig = s; 6203 ssp->progress |= BSCV_SIG_SENT; 6204 } 6205 #endif /* __sparc */ 6206 6207 #if defined(__i386) || defined(__amd64) 6208 6209 /* 6210 * function - bscv_inform_bsc 6211 * description - inform bsc of driver state for logging purposes 6212 * inputs - driver soft state, state 6213 * outputs - none 6214 * 6215 */ 6216 static void 6217 bscv_inform_bsc(bscv_soft_state_t *ssp, uint32_t state) 6218 { 6219 ASSERT(bscv_held(ssp)); 6220 6221 bscv_trace(ssp, 'X', "bscv_inform_bsc", 6222 "bscv_inform_bsc: state=%d", state); 6223 6224 bscv_put32(ssp, chan_general, 6225 BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_SIG_MSB), state); 6226 bscv_put8(ssp, chan_cpusig, 6227 BSCVA(EBUS_CMD_SPACE_CPUSIG, EBUS_IDX11_CPU_ID), EBUS_ANY_CPU_ID); 6228 } 6229 6230 /* 6231 * function - bscv_watchdog_pat_request 6232 * description - request a heartbeat pat 6233 * inputs - timeout value in seconds 6234 * outputs - none 6235 */ 6236 static void 6237 bscv_watchdog_pat_request(void *arg) 6238 { 6239 bscv_soft_state_t *ssp = (bscv_soft_state_t *)arg; 6240 6241 bscv_wdog_do_pat(ssp); 6242 } 6243 6244 /* 6245 * function - bscv_watchdog_cfg_request 6246 * description - request configuration of the bsc hardware watchdog 6247 * inputs - new state (0=disabled, 1=enabled) 6248 * outputs - one if successful, zero if unsuccesful 6249 */ 6250 static void 6251 bscv_watchdog_cfg_request(bscv_soft_state_t *ssp, uint8_t new_state) 6252 { 6253 ASSERT(new_state == WDOG_ON || new_state == WDOG_OFF); 6254 6255 watchdog_activated = new_state; 6256 bscv_trace(ssp, 'X', "bscv_watchdog_cfg_request", 6257 "watchdog_activated=%d", watchdog_activated); 6258 bscv_write_wdog_cfg(ssp, 6259 bscv_watchdog_timeout_seconds, 6260 new_state, 6261 wdog_reset_on_timeout); 6262 } 6263 6264 /* 6265 * function - bscv_set_watchdog_timer 6266 * description - setup the heartbeat timeout value 6267 * inputs - timeout value in seconds 6268 * outputs - zero if the value was not changed 6269 * otherwise the current value 6270 */ 6271 static uint_t 6272 bscv_set_watchdog_timer(bscv_soft_state_t *ssp, uint_t timeoutval) 6273 { 6274 bscv_trace(ssp, 'X', "bscv_set_watchdog_timer:", 6275 "timeout=%d", timeoutval); 6276 6277 /* 6278 * We get started during bscv_attach only 6279 * if bscv_watchdog_enable is set. 6280 */ 6281 if (bscv_watchdog_available && (!watchdog_activated || 6282 (watchdog_activated && 6283 (timeoutval != bscv_watchdog_timeout_seconds)))) { 6284 bscv_watchdog_timeout_seconds = timeoutval; 6285 bscv_watchdog_cfg_request(ssp, WDOG_ON); 6286 return (bscv_watchdog_timeout_seconds); 6287 } 6288 return (0); 6289 } 6290 6291 /* 6292 * function - bscv_clear_watchdog_timer 6293 * description - add the watchdog patter cyclic 6294 * inputs - driver soft state 6295 * outputs - value of watchdog timeout in seconds 6296 * 6297 * This function is a copy of the SPARC implementation 6298 * in the todblade clock driver. 6299 */ 6300 static void 6301 bscv_clear_watchdog_timer(bscv_soft_state_t *ssp) 6302 { 6303 bscv_trace(ssp, 'X', "bscv_clear_watchdog_timer", ""); 6304 6305 if (bscv_watchdog_available && watchdog_activated) { 6306 bscv_watchdog_enable = 0; 6307 bscv_watchdog_cfg_request(ssp, WDOG_OFF); 6308 } 6309 } 6310 6311 /* 6312 * function - bscv_panic_callback 6313 * description - called when we panic so we can disabled the watchdog 6314 * inputs - driver soft state pointer 6315 * outputs - DDI_SUCCESS 6316 */ 6317 /*ARGSUSED1*/ 6318 static boolean_t 6319 bscv_panic_callback(void *arg, int code) 6320 { 6321 bscv_soft_state_t *ssp = (bscv_soft_state_t *)arg; 6322 6323 bscv_trace(ssp, 'X', "bscv_panic_callback", 6324 "disabling watchdog"); 6325 6326 bscv_clear_watchdog_timer(ssp); 6327 /* 6328 * We dont get interrupts during the panic callback. But bscbus 6329 * takes care of all this 6330 */ 6331 bscv_full_stop(ssp); 6332 return (DDI_SUCCESS); 6333 } 6334 6335 /* 6336 * function - bscv_watchdog_cyclic_add 6337 * description - add the watchdog patter cyclic 6338 * inputs - driver soft state 6339 * outputs - none 6340 */ 6341 static void 6342 bscv_watchdog_cyclic_add(bscv_soft_state_t *ssp) 6343 { 6344 if (ssp->periodic_id != NULL) { 6345 return; 6346 } 6347 6348 ssp->periodic_id = ddi_periodic_add(bscv_watchdog_pat_request, ssp, 6349 WATCHDOG_PAT_INTERVAL, DDI_IPL_10); 6350 6351 bscv_trace(ssp, 'X', "bscv_watchdog_cyclic_add:", 6352 "cyclic added"); 6353 } 6354 6355 /* 6356 * function - bscv_watchdog_cyclic_remove 6357 * description - remove the watchdog patter cyclic 6358 * inputs - soft state ptr 6359 * outputs - none 6360 */ 6361 static void 6362 bscv_watchdog_cyclic_remove(bscv_soft_state_t *ssp) 6363 { 6364 if (ssp->periodic_id == NULL) { 6365 return; 6366 } 6367 ddi_periodic_delete(ssp->periodic_id); 6368 ssp->periodic_id = NULL; 6369 bscv_trace(ssp, 'X', "bscv_watchdog_cyclic_remove:", 6370 "cyclic removed"); 6371 } 6372 #endif /* __i386 || __amd64 */ 6373 6374 6375 /* 6376 * General utility routines ... 6377 */ 6378 6379 #ifdef DEBUG 6380 6381 static void 6382 bscv_trace(bscv_soft_state_t *ssp, char code, const char *caller, 6383 const char *fmt, ...) 6384 { 6385 char buf[256]; 6386 char *p; 6387 va_list va; 6388 6389 if (ssp->debug & (1 << (code-'@'))) { 6390 p = buf; 6391 (void) snprintf(p, sizeof (buf) - (p - buf), 6392 "%s/%s: ", MYNAME, caller); 6393 p += strlen(p); 6394 6395 va_start(va, fmt); 6396 (void) vsnprintf(p, sizeof (buf) - (p - buf), fmt, va); 6397 va_end(va); 6398 6399 buf[sizeof (buf) - 1] = '\0'; 6400 (void) strlog((short)ssp->majornum, (short)ssp->minornum, code, 6401 SL_TRACE, buf); 6402 } 6403 } 6404 6405 #else /* DEBUG */ 6406 6407 _NOTE(ARGSUSED(0)) 6408 static void 6409 bscv_trace(bscv_soft_state_t *ssp, char code, const char *caller, 6410 const char *fmt, ...) 6411 { 6412 } 6413 6414 #endif /* DEBUG */ 6415