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