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