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