Lines Matching refs:scsb

72 #include <sys/scsb.h>
89 * scsb build version format is "CCYYMMDD"
100 static int scsb_in_postintr = 0; /* 1 if scsb is processing intr */
110 * cb_ops section of scsb driver.
255 static void scsb_freeze(scsb_state_t *scsb);
256 static void scsb_freeze_check(scsb_state_t *scsb);
257 static void scsb_restore(scsb_state_t *scsb);
259 static int scsb_check_config_status(scsb_state_t *scsb);
263 int scsb_read_bhealthy(scsb_state_t *scsb);
265 static void tonga_slotnum_check(scsb_state_t *scsb, scsb_uinfo_t *suip);
266 static int tonga_psl_to_ssl(scsb_state_t *scsb, int slotnum);
267 static uchar_t tonga_slotnum_led_shift(scsb_state_t *scsb, uchar_t data);
268 static int scsb_clear_intptrs(scsb_state_t *scsb);
269 static int scsb_clear_intmasks(scsb_state_t *scsb);
270 static int scsb_setall_intmasks(scsb_state_t *scsb);
306 static void scsb_failing_event(scsb_state_t *scsb);
315 cmn_err(CE_NOTE, "scsb: _init()");
321 cmn_err(CE_NOTE, "scsb: _init(): mod_install failed");
347 cmn_err(CE_NOTE, "scsb: _fini()");
354 cmn_err(CE_NOTE, "scsb: _fini, error %x\n", status);
363 cmn_err(CE_NOTE, "scsb: _info()");
372 scsb_state_t *scsb;
392 cmn_err(CE_WARN, "scsb%d: cannot allocate soft state",
397 scsb = (scsb_state_t *)ddi_get_soft_state(scsb_state, instance);
398 if (scsb == NULL) {
399 cmn_err(CE_WARN, "scsb%d: cannot get soft state", instance);
403 scsb->scsb_instance = instance;
404 scsb->scsb_state = 0; /* just checking strange mutex behavior */
412 "scsb%d: Failed to get \"reg\" property", instance);
416 scsb->scsb_i2c_addr = regs[1] & SCSB_I2C_ADDR_MASK;
417 if (scsb->scsb_i2c_addr != SCSB_I2C_ADDR) {
418 cmn_err(CE_WARN, "scsb%d: I2C Addr reg %x %x must be %x",
430 mutex_init(&scsb->scsb_mutex, NULL, MUTEX_DRIVER, NULL);
431 scsb->scsb_state |= SCSB_UMUTEX;
432 cv_init(&scsb->scsb_cv, NULL, CV_DRIVER, NULL);
433 scsb->scsb_state |= SCSB_CONDVAR;
437 * 2. Get scsb private handle for communication via I2C Services.
449 scsb->scsb_state |= SCSB_PROP_CREATE;
453 scsb->scsb_state |= SCSB_P06_INTR_ON;
455 scsb->scsb_state |= SCSB_P06_NOINT_KLUGE;
459 * on how many errors will scsb send a warning event about it's
470 scsb->scsb_i2c_errcnt = 0;
471 scsb->scsb_err_flag = B_FALSE;
472 scsb->scsb_kstat_flag = B_FALSE;
480 free_resources(dip, scsb, instance);
483 scsb->scsb_state |= SCSB_MINOR_NODE;
484 scsb->scsb_dev = dip;
489 free_resources(dip, scsb, instance);
493 bzero(scsb->clone_devs, sizeof (clone_dev_t) * SCSB_CLONES_MAX);
495 if (i2c_client_register(dip, &scsb->scsb_phandle) != I2C_SUCCESS) {
498 free_resources(dip, scsb, instance);
501 scsb->scsb_state |= SCSB_I2C_PHANDLE;
503 if ((scsb->scsb_i2ctp = scsb_alloc_i2ctx(scsb->scsb_phandle,
506 "scsb%d: i2c_transfer allocation failed", instance);
507 free_resources(dip, scsb, instance);
510 scsb->scsb_state |= SCSB_I2C_TRANSFER;
544 if (initialize_scb(scsb) != DDI_SUCCESS) {
546 free_resources(dip, scsb, instance);
555 * necessary workarounds to several scsb routines.
560 if (scsb->scsb_state & SCSB_P06_INTR_ON) {
562 &scsb->scsb_iblock) == DDI_SUCCESS) {
563 mutex_init(&scsb->scsb_imutex, NULL, MUTEX_DRIVER,
564 (void *)scsb->scsb_iblock);
565 scsb->scsb_state |= SCSB_IMUTEX;
566 if (ddi_add_intr(dip, instance, &scsb->scsb_iblock,
568 (caddr_t)scsb) != DDI_SUCCESS) {
572 free_resources(dip, scsb, instance);
575 scb_intr_mutex = &scsb->scsb_imutex;
581 scsb->scsb_state |= SCSB_P06_NOINT_KLUGE;
582 scsb->scsb_state &= ~SCSB_P06_INTR_ON;
584 free_resources(dip, scsb, instance);
590 if (i = scsb_clear_intmasks(scsb)) {
592 "scsb%d: I2C TRANSFER Failed", instance);
594 free_resources(dip, scsb, instance);
603 if (!(scsb->scsb_state & SCSB_P06_NOINT_KLUGE)) {
609 if (i = scsb_write_mask(scsb, reg, rmask, wdata, (uchar_t)0)) {
611 "scsb%d: I2C TRANSFER Failed", instance);
613 free_resources(dip, scsb, instance);
617 scsb->scsb_state |= SCSB_PSM_INT_ENABLED;
627 scsb->scsb_state |= SCSB_DEBUG_MODE;
628 mutex_enter(&scsb->scsb_mutex);
629 if (scsb_readall_regs(scsb))
632 mutex_exit(&scsb->scsb_mutex);
636 if (scsb_fru_op(scsb, ALARM, 1, SCTRL_SYSCFG_BASE,
638 scsb->scsb_hsc_state |= SCSB_ALARM_CARD_PRES;
644 if (scsb_hsc_attach(dip, scsb, instance) != DDI_SUCCESS) {
647 "scsb: Hotswap controller initialisation"
651 scsb->scsb_hsc_state |= SCSB_HSC_INIT;
656 if (scsb_alloc_kstats(scsb) != DDI_SUCCESS) {
661 scsb->scsb_state |= SCSB_UP;
663 ddi_report_dev(scsb->scsb_dev);
666 ddi_driver_name(scsb->scsb_dev),
667 scsb->scsb_instance,
668 (scsb->scsb_state & SCSB_P06_PROM) ? "0.6" :
669 (scsb->scsb_state & SCSB_P10_PROM) ? "1.0" :
670 (scsb->scsb_state & SCSB_P15_PROM) ? "1.5" :
671 (scsb->scsb_state & SCSB_P20_PROM) ? "2.0" : "Unknown",
682 scb_check_version(scsb_state_t *scsb)
686 if (scsb->scsb_state & SCSB_UP) {
694 if (scsb_rdwr_register(scsb, I2C_WR_RD, (uchar_t)SCTRL_PROM_VERSION, 1,
696 if (!(hotswap && scsb->scsb_state & SCSB_FROZEN))
697 cmn_err(CE_WARN, "scsb%d: I2C TRANSFER Failed",
698 scsb->scsb_instance);
702 scsb->scsb_instance);
724 scsb->scsb_state |= SCSB_P06_PROM;
726 scsb->scsb_state |= SCSB_P10_PROM;
728 scsb->scsb_state |= SCSB_P15_PROM;
730 scsb->scsb_state |= SCSB_P20_PROM;
732 if (!(scsb->scsb_state & SCSB_SCB_PRESENT))
733 scsb->scsb_state |= SCSB_SCB_PRESENT;
746 cmn_err(CE_WARN, "scsb%d: SCB Version %d not recognized",
747 scsb->scsb_instance, data);
749 scsb->scsb_state |= SCSB_FROZEN;
756 scsb->scsb_state |= SCSB_P15_PROM;
766 initialize_scb(scsb_state_t *scsb)
773 if (!(scsb->scsb_state & SCSB_IN_INTR))
774 if (scb_check_version(scsb) != DDI_SUCCESS)
783 if (i = scsb_write_mask(scsb, reg, rmask, wdata, 0)) {
785 "scsb%d: I2C TRANSFER Failed", scsb->scsb_instance);
796 scsb->scsb_instance);
798 if (i = scsb_leds_switch(scsb, OFF)) {
799 cmn_err(CE_WARN, "scsb%d: I2C TRANSFER Failed",
800 scsb->scsb_instance);
807 scsb->scsb_instance);
808 if ((i = scsb_check_config_status(scsb)) == 0) {
809 if (!(scsb->scsb_state & SCSB_TOPOLOGY)) {
810 scsb_set_topology(scsb);
813 scsb->scsb_instance,
823 update_fru_info(scsb, fru_ptr);
828 i = scsb_set_scfg_pres_leds(scsb, NULL);
831 cmn_err(CE_WARN, "scsb%d: I2C TRANSFER Failed",
832 scsb->scsb_instance);
838 scsb->scsb_instance);
839 i = scsb_read_bhealthy(scsb);
841 cmn_err(CE_WARN, "scsb%d: I2C TRANSFER Failed",
842 scsb->scsb_instance);
858 if (i = scsb_write_mask(scsb, reg, rmask, (uchar_t)0, wdata)) {
859 cmn_err(CE_WARN, "scsb%d: Cannot turn off PSM_INT",
860 scsb->scsb_instance);
864 if (i = scsb_setall_intmasks(scsb)) {
865 cmn_err(CE_WARN, "scsb%d: I2C TRANSFER Failed",
866 scsb->scsb_instance);
870 if (i = scsb_clear_intptrs(scsb)) {
871 cmn_err(CE_WARN, "scsb%d: I2C TRANSFER Failed",
872 scsb->scsb_instance);
888 scsb_state_t *scsb;
905 scsb = (scsb_state_t *)ddi_get_soft_state(scsb_state, instance);
906 scsb->scsb_state &= ~SCSB_UP;
908 if (scsb->scsb_hsc_state & SCSB_HSC_INIT) {
909 (void) scsb_hsc_detach(dip, scsb, instance);
910 scsb->scsb_hsc_state &= ~SCSB_HSC_INIT;
912 if (scsb->scsb_state & SCSB_PSM_INT_ENABLED) {
919 if (scsb_write_mask(scsb, reg, (uchar_t)0, (uchar_t)0, wdata)) {
921 "scsb%d: Cannot turn off PSM_INT", instance);
923 (void) free_resources(dip, scsb, instance);
928 if (scsb_setall_intmasks(scsb)) {
930 "scsb%d: I2C TRANSFER Failed", instance);
932 (void) free_resources(dip, scsb, instance);
937 if (scsb_clear_intptrs(scsb)) {
939 "scsb%d: I2C TRANSFER Failed", instance);
941 (void) free_resources(dip, scsb, instance);
946 if (scsb->scsb_opens && scsb->scsb_rq != NULL)
947 qprocsoff(scsb->scsb_rq);
949 (void) scsb_queue_ops(scsb, QPROCSOFF, 0, NULL, NULL);
953 free_resources(dip, scsb, instance);
958 free_resources(dev_info_t *dip, scsb_state_t *scsb, int instance)
962 instance, scsb->scsb_state);
965 if (scsb->scsb_state & SCSB_P06_INTR_ON &&
966 scsb->scsb_state & SCSB_IMUTEX) {
967 scsb->scsb_state &= ~SCSB_P06_INTR_ON;
968 ddi_remove_intr(dip, 0, scsb->scsb_iblock);
970 if (scsb->scsb_state & SCSB_KSTATS) {
971 scsb_free_kstats(scsb);
972 scsb->scsb_state &= ~SCSB_KSTATS;
974 if (scsb->scsb_state & SCSB_TOPOLOGY) {
975 scsb_free_topology(scsb);
976 scsb->scsb_state &= ~SCSB_TOPOLOGY;
980 if (scsb->scsb_state & SCSB_IMUTEX) {
981 scsb->scsb_state &= ~SCSB_IMUTEX;
982 mutex_destroy(&scsb->scsb_imutex);
984 if (scsb->scsb_state & SCSB_I2C_TRANSFER) {
985 scsb->scsb_state &= ~SCSB_I2C_TRANSFER;
986 i2c_transfer_free(scsb->scsb_phandle, scsb->scsb_i2ctp);
988 if (scsb->scsb_state & SCSB_I2C_PHANDLE) {
989 scsb->scsb_state &= ~SCSB_I2C_PHANDLE;
990 i2c_client_unregister(scsb->scsb_phandle);
992 if (scsb->scsb_state & SCSB_MINOR_NODE) {
993 scsb->scsb_state &= ~SCSB_MINOR_NODE;
996 if (scsb->scsb_state & SCSB_PROP_CREATE) {
997 scsb->scsb_state &= ~SCSB_PROP_CREATE;
1002 if (scsb->scsb_state & SCSB_CONDVAR) {
1003 scsb->scsb_state &= ~SCSB_CONDVAR;
1004 cv_destroy(&scsb->scsb_cv);
1006 if (scsb->scsb_state & SCSB_UMUTEX) {
1007 scsb->scsb_state &= ~SCSB_UMUTEX;
1008 mutex_destroy(&scsb->scsb_mutex);
1014 * Just for testing scsb's poll function
1017 scsb_fake_intr(scsb_state_t *scsb, uint32_t evcode)
1025 scsb_event_code, (void *)scsb->scsb_rq);
1030 * if (scsb->scsb_state & SCSB_FROZEN) {
1035 check_fru_info(scsb, evcode);
1036 add_event_code(scsb, evcode);
1039 if (scsb_queue_ops(scsb, QPUT_INT32, 1, &evcode, "scsb_fake_intr")
1087 scsb_state_t *scsb;
1091 scsb = ddi_get_soft_state(scsb_state, instance);
1092 if (scsb == NULL)
1098 if (!(scsb->scsb_state & SCSB_UP)) {
1107 * if (scsb->scsb_state & SCSB_FROZEN) {
1116 /* scsb module is being pushed */
1124 /* scsb is being opened as a clonable driver */
1141 mutex_enter(&scsb->scsb_mutex);
1142 if ((clone = scsb_queue_ops(scsb, QFIRST_AVAILABLE, 0, NULL,
1144 mutex_exit(&scsb->scsb_mutex);
1147 clptr = &scsb->clone_devs[clone];
1152 scsb->scsb_clopens++;
1159 /* scsb is being opened as a regular driver */
1162 mutex_enter(&scsb->scsb_mutex);
1163 if (scsb->scsb_state & SCSB_EXCL) {
1168 mutex_exit(&scsb->scsb_mutex);
1175 if (scsb->scsb_state & SCSB_OPEN) {
1180 mutex_exit(&scsb->scsb_mutex);
1183 scsb->scsb_state |= SCSB_EXCL;
1185 if (scsb->scsb_opens && scsb->scsb_rq != NULL &&
1186 scsb->scsb_rq != RD(q)) {
1191 (void *)scsb->scsb_rq);
1193 scsb->scsb_rq = RD(q);
1194 scsb->scsb_opens++;
1196 scsb->scsb_state |= SCSB_OPEN;
1197 mutex_exit(&scsb->scsb_mutex);
1198 RD(q)->q_ptr = WR(q)->q_ptr = scsb;
1207 scsb_state_t *scsb;
1211 scsb = (scsb_state_t *)q->q_ptr;
1213 cmn_err(CE_NOTE, "sm_close[%d](0x%p)", scsb->scsb_instance,
1215 if (scsb->scsb_clopens) {
1216 mutex_enter(&scsb->scsb_mutex);
1217 if ((clone = scsb_queue_ops(scsb, QFIND_QUEUE, 0,
1219 clptr = &scsb->clone_devs[clone];
1222 scsb->scsb_clopens--;
1224 mutex_exit(&scsb->scsb_mutex);
1228 scsb->scsb_instance, clptr->cl_minor);
1230 if (clptr == NULL && scsb->scsb_opens) {
1233 scsb->scsb_instance, scsb->scsb_opens);
1234 if (RD(q) != scsb->scsb_rq) {
1238 scsb->scsb_instance);
1240 mutex_enter(&scsb->scsb_mutex);
1241 scsb->scsb_opens = 0;
1242 if (scsb->scsb_state & SCSB_EXCL) {
1243 scsb->scsb_state &= ~SCSB_EXCL;
1245 scsb->scsb_rq = (queue_t *)NULL;
1246 mutex_exit(&scsb->scsb_mutex);
1248 if (scsb->scsb_opens == 0 && scsb->scsb_clopens == 0) {
1249 scsb->scsb_state &= ~SCSB_OPEN;
1268 scsb_state_t *scsb = (scsb_state_t *)WR(q)->q_ptr;
1271 cmn_err(CE_NOTE, "sm_wput(%d): mp %p", scsb->scsb_instance,
1282 /* free any messages tied to scsb */
1295 scsb->scsb_instance);
1303 scsb->scsb_instance);
1304 if (!(scsb->scsb_state & SCSB_UP)) {
1314 scsb->scsb_instance);
1329 scsb_state_t *scsb = (scsb_state_t *)q->q_ptr;
1334 scsb->scsb_instance, (void *)mp, iocp->ioc_cmd);
1336 if (!(scsb->scsb_state & SCSB_UP)) {
1345 * if (scsb->scsb_state & SCSB_FROZEN) {
1359 scsb->scsb_instance, iocp->ioc_cmd);
1372 if (scsb->scsb_state & SCSB_DEBUG_MODE)
1374 else if (scsb->scsb_state & SCSB_DIAGS_MODE)
1397 scsb->scsb_state &=
1401 scsb->scsb_state |= SCSB_DIAGS_MODE;
1402 scsb->scsb_state &= ~SCSB_DEBUG_MODE;
1405 if (scsb->scsb_state &
1407 scsb->scsb_state &= ~SCSB_DIAGS_MODE;
1408 scsb->scsb_state |= SCSB_DEBUG_MODE;
1426 if (scsb->scsb_state & SCSB_APP_SLOTLED_CTRL)
1429 scsb->scsb_state |= SCSB_APP_SLOTLED_CTRL;
1435 scsb->scsb_state &= ~SCSB_APP_SLOTLED_CTRL;
1487 if (add_event_proc(scsb, *(pid_t *)mp->b_cont->b_rptr))
1495 if (del_event_proc(scsb, *(pid_t *)mp->b_cont->b_rptr))
1505 if (!(scsb->scsb_state & SCSB_DEBUG_MODE)) {
1529 mode_vals[0] = scsb->scsb_state;
1531 mode_vals[1] = scsb->scsb_hsc_state;
1552 if (!(scsb->scsb_state & SCSB_DEBUG_MODE)) {
1563 hsc_ac_op((int)scsb->scsb_instance, pslotnum,
1585 scsb->scsb_instance, iocp->ioc_cmd);
1597 if (!(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE))) {
1616 iocp->ioc_error = scsb_led_get(scsb, suip, OK);
1619 iocp->ioc_error = scsb_led_get(scsb, suip, NOK);
1622 iocp->ioc_error = scsb_led_set(scsb, suip, OK);
1625 iocp->ioc_error = scsb_led_set(scsb, suip, NOK);
1628 iocp->ioc_error = scsb_bhealthy_slot(scsb, suip);
1631 iocp->ioc_error = scsb_slot_occupancy(scsb, suip);
1634 iocp->ioc_error = scsb_reset_unit(scsb, suip);
1641 iocp->ioc_error = scsb_led_get(scsb, suip, NOUSE);
1648 iocp->ioc_error = scsb_led_set(scsb, suip, NOUSE);
1651 if (scsb->scsb_state & SCSB_FROZEN) {
1655 iocp->ioc_error = scsb_led_set(scsb, suip, NOUSE);
1664 if (!(scsb->scsb_state & SCSB_DEBUG_MODE)) {
1676 iocp->ioc_error = scsb_fake_intr(scsb, ui);
1681 if (!(scsb->scsb_state & SCSB_DEBUG_MODE)) {
1687 iocp->ioc_error = scsb_get_status(scsb,
1692 if (!(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE)))
1695 iocp->ioc_error = scsb_leds_switch(scsb, ON);
1699 if (!(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE)))
1702 iocp->ioc_error = scsb_leds_switch(scsb, OFF);
1707 if (!(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE))) {
1712 if (scsb->scsb_state & SCSB_FROZEN &&
1713 !(scsb->scsb_state & SCSB_DEBUG_MODE)) {
1742 if (!(scsb->scsb_state & SCSB_DEBUG_MODE)) {
1748 iocp->ioc_error = scsb_polled_int(scsb, iocp->ioc_cmd,
1753 if (!(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE)))
1756 scsb_restore(scsb);
1757 (void) scsb_toggle_psmint(scsb, 1);
1763 if (!(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE)))
1766 scsb_freeze_check(scsb);
1767 scsb_freeze(scsb);
1776 (void) scsb_hsc_ac_op(scsb, scsb->ac_slotnum,
1784 if (scsb->scsb_state & SCSB_FROZEN) {
1788 (void) scsb_hsc_ac_op(scsb, scsb->ac_slotnum,
1794 if (!(scsb->scsb_state & SCSB_DEBUG_MODE))
1797 mct_topology_dump(scsb, 1);
1955 * same interrupt line to register the interrupt handler with scsb.
1963 * happen even before scsb is attached, so do not depend on scsb
2063 scsb_state_t *scsb = (scsb_state_t *)q->q_ptr;
2070 cmn_err(CE_CONT, "sm_ioc_rdwr[%d]:", scsb->scsb_instance);
2087 error = scsb_rdwr_register(scsb, op, reg, len, uc, 1);
2113 scsb_get_led_regnum(scsb_state_t *scsb,
2133 * It was requested that the scsb driver allow accesses to SCB device
2142 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2152 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2167 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2182 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2199 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2214 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2229 ((scsb->scsb_state & SCSB_IS_TONGA) ?
2281 tonga_pslotnum_to_cfgbit(scsb_state_t *scsb, int sln)
2284 if (!(scsb->scsb_state & SCSB_IS_TONGA)) {
2331 tonga_slotnum_check(scsb_state_t *scsb, scsb_uinfo_t *suip)
2333 if (!(scsb->scsb_state & SCSB_IS_TONGA && scsb->scsb_state &
2353 tonga_psl_to_ssl(scsb_state_t *scsb, int slotnum)
2355 if (!(scsb->scsb_state & SCSB_IS_TONGA && scsb->scsb_state &
2375 tonga_ssl_to_psl(scsb_state_t *scsb, int slotnum)
2377 if (!(scsb->scsb_state & SCSB_IS_TONGA && scsb->scsb_state &
2402 tonga_slotnum_led_shift(scsb_state_t *scsb, uchar_t data)
2409 if (!(scsb->scsb_state & SCSB_IS_TONGA)) {
2451 scsb_led_get(scsb_state_t *scsb, scsb_uinfo_t *suip, scsb_led_t led_type)
2461 * if (scsb->scsb_state & SCSB_FROZEN) {
2473 scsb->scsb_instance, led_type);
2486 if (suip->unit_type == SLOT && !(scsb->scsb_state & SCSB_P10_PROM)) {
2487 tonga_slotnum_check(scsb, suip);
2490 if ((error = scsb_get_led_regnum(scsb, suip, &reg, &unit_number,
2493 mutex_enter(&scsb->scsb_mutex);
2494 if (scsb->scsb_data_reg[index] & (1 << unit_number)) {
2501 if (scsb->scsb_data_reg[index] &
2508 mutex_exit(&scsb->scsb_mutex);
2514 scsb_led_set(scsb_state_t *scsb, scsb_uinfo_t *suip, scsb_led_t led_type)
2522 if (scsb->scsb_state & SCSB_FROZEN)
2537 scsb->scsb_state & SCSB_APP_SLOTLED_CTRL &&
2538 !(scsb->scsb_state &
2557 if (suip->unit_type != SLOT && scsb->scsb_state &
2573 if (suip->unit_type == SLOT && !(scsb->scsb_state & SCSB_P10_PROM)) {
2574 tonga_slotnum_check(scsb, suip);
2579 if ((error = scsb_get_led_regnum(scsb, suip, &reg, &unit_number,
2582 mutex_enter(&scsb->scsb_mutex);
2584 scsb->scsb_data_reg[index] |= (1 << unit_number);
2586 scsb->scsb_data_reg[index] &= ~(1 << unit_number);
2590 scsb->scsb_data_reg[index], reg);
2592 error = scsb_rdwr_register(scsb, I2C_WR, reg, 1,
2593 &scsb->scsb_data_reg[index], 1);
2596 ddi_driver_name(scsb->scsb_dev),
2597 ddi_get_instance(scsb->scsb_dev),
2613 scsb->scsb_data_reg[index] |= (1 << unit_number);
2615 scsb->scsb_data_reg[index] &= ~(1 << unit_number);
2618 scsb->scsb_data_reg[index], reg);
2620 error = scsb_rdwr_register(scsb, I2C_WR, reg, 1,
2621 &scsb->scsb_data_reg[index], 1);
2624 ddi_driver_name(scsb->scsb_dev),
2625 ddi_get_instance(scsb->scsb_dev),
2629 mutex_exit(&scsb->scsb_mutex);
2635 scsb_state_t *scsb;
2657 if (scsb_write_mask(ppao->scsb, sysreg, rmask, ondata, (uchar_t)0)) {
2658 cmn_err(CE_WARN, "scsb%d: " "I2C TRANSFER Failed",
2659 ppao->scsb->scsb_instance);
2661 ppao->scsb->scsb_btid = 0;
2670 scsb_set_scfg_pres_leds(scsb_state_t *scsb, fru_info_t *int_fru_ptr)
2681 if (scsb->scsb_state & SCSB_FROZEN &&
2682 !(scsb->scsb_state & SCSB_IN_INTR)) {
2702 if (fru_type == SLOT && (scsb->scsb_state &
2723 if (scsb->scsb_state & SCSB_SCB_PRESENT) {
2734 if (scsb->scsb_data_reg[cfg_idx] &
2748 pao.scsb = scsb;
2766 if (!scsb->scsb_btid)
2767 scsb->scsb_btid =
2825 if ((error = scsb_rdwr_register(scsb, I2C_WR, reg, i, puc, 1)) != 0) {
2847 if (scsb_write_mask(scsb, reg, 0, 0, blink[i])) {
2861 scsb_check_config_status(scsb_state_t *scsb)
2878 mutex_enter(&scsb->scsb_mutex);
2881 if (error = scsb_rdwr_register(scsb, I2C_WR_RD, reg,
2882 SCTRL_CFG_NUMREGS, &scsb->scsb_data_reg[index], 1)) {
2893 if (!(scsb->scsb_state & SCSB_P06_PROM))
2896 mutex_exit(&scsb->scsb_mutex);
2899 if (!(scsb->scsb_state & SCSB_SCB_PRESENT))
2900 scsb->scsb_state |= SCSB_SCB_PRESENT;
2901 if (scsb_fru_op(scsb, SSB, 1, SCTRL_SYSCFG_BASE,
2903 scsb->scsb_state |= SCSB_SSB_PRESENT;
2905 scsb->scsb_state &= ~SCSB_SSB_PRESENT;
2911 scsb_set_topology(scsb_state_t *scsb)
2922 * in scsb->scsb_data_reg[]
2931 mct_system_info.mid_plane.fru_id = (int)((scsb->scsb_data_reg[index] &
2939 alarm_slot_num = scsb->ac_slotnum = SC_MC_AC_SLOT;
2954 scsb->scsb_state |= SCSB_IS_TONGA;
2964 alarm_slot_num = scsb->ac_slotnum = SC_TG_AC_SLOT;
2979 ddi_driver_name(scsb->scsb_dev),
2980 ddi_get_instance(scsb->scsb_dev),
3022 iunit = tonga_psl_to_ssl(scsb, unit);
3031 bit_num = tonga_pslotnum_to_cfgbit(scsb, unit);
3045 if (scsb->scsb_state & SCSB_P06_PROM) {
3047 } else if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3107 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3165 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3224 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3283 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3332 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3394 if (scsb->scsb_state & SCSB_SCB_PRESENT) {
3403 if (scsb_rdwr_register(scsb, I2C_WR_RD, index, 1, &t_uchar, 1))
3442 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3497 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3502 scsb->scsb_hsc_state |= SCSB_HSC_CTC_PRES;
3547 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3591 if (scsb->scsb_data_reg[index] & (1 << bit_num)) {
3611 scsb->scsb_state |= SCSB_TOPOLOGY;
3613 mct_topology_dump(scsb, 0);
3619 scsb_free_topology(scsb_state_t *scsb)
3645 mct_topology_dump(scsb_state_t *scsb, int force)
3652 if (force && !(scsb->scsb_state & (SCSB_DIAGS_MODE | SCSB_DEBUG_MODE)))
3654 if (!(scsb->scsb_state & SCSB_TOPOLOGY)) {
3715 scsb_failing_event(scsb_state_t *scsb)
3719 add_event_code(scsb, scsb_event_code);
3720 (void) scsb_queue_ops(scsb, QPUT_INT32, 1, &scsb_event_code,
3726 scsb_read_bhealthy(scsb_state_t *scsb)
3737 error = scsb_rdwr_register(scsb, I2C_WR_RD, reg,
3738 SCTRL_BHLTHY_NUMREGS, &scsb->scsb_data_reg[index], 1);
3746 scsb_read_slot_health(scsb_state_t *scsb, int pslotnum)
3748 int slotnum = tonga_psl_to_ssl(scsb, pslotnum);
3749 return (scsb_fru_op(scsb, SLOT, slotnum,
3758 scsb_bhealthy_slot(scsb_state_t *scsb, scsb_uinfo_t *suip)
3765 if (scsb->scsb_state & SCSB_FROZEN)
3782 tonga_slotnum_check(scsb, suip);
3790 if (scsb->scsb_state & SCSB_P10_PROM) {
3791 error = scsb_read_bhealthy(scsb);
3795 if (scsb->scsb_data_reg[index] & (1 << unit_number))
3808 scsb_reset_unit(scsb_state_t *scsb, scsb_uinfo_t *suip)
3815 if (scsb->scsb_state & SCSB_FROZEN)
3819 scsb->scsb_instance, suip->unit_number,
3822 if (suip->unit_type != ALARM && !(scsb->scsb_state &
3846 if (scsb->scsb_state & SCSB_IS_TONGA) {
3854 (scsb->scsb_hsc_state & SCSB_HSC_CTC_PRES &&
3859 return (scsb_reset_slot(scsb, slotnum, reset_state));
3864 mutex_enter(&scsb->scsb_mutex);
3866 scsb->scsb_data_reg[index] |= (1 << unit_number);
3868 scsb->scsb_data_reg[index] &= ~(1 << unit_number);
3869 if ((error = scsb_rdwr_register(scsb, I2C_WR, reg, 1,
3870 &scsb->scsb_data_reg[index], 0)) != 0) {
3876 mutex_exit(&scsb->scsb_mutex);
3883 * scsb h/w is doing its job!!!
3886 scsb_slot_occupancy(scsb_state_t *scsb, scsb_uinfo_t *suip)
3891 if (!(scsb->scsb_state & (SCSB_DEBUG_MODE | SCSB_DIAGS_MODE)))
3893 if (scsb->scsb_state & SCSB_FROZEN) {
3916 tonga_slotnum_check(scsb, suip);
3940 scsb_clear_intptrs(scsb_state_t *scsb)
3948 if (error = scsb_rdwr_register(scsb, I2C_WR,
3960 scsb_setall_intmasks(scsb_state_t *scsb)
3976 if (error = scsb_write_mask(scsb, reg, rmask, wdata, 0)) {
4000 scsb_clear_intmasks(scsb_state_t *scsb)
4009 if (scsb->scsb_state & SCSB_FROZEN &&
4010 !(scsb->scsb_state & SCSB_IN_INTR)) {
4092 mutex_enter(&scsb->scsb_mutex);
4093 if (error = scsb_write_mask(scsb, msk_reg, rmask,
4095 mutex_exit(&scsb->scsb_mutex);
4103 mutex_exit(&scsb->scsb_mutex);
4110 scsb_get_status(scsb_state_t *scsb, scsb_status_t *smp)
4118 (scsb->scsb_state & SCSB_DEBUG_MODE ||
4119 scsb->scsb_state & SCSB_DIAGS_MODE)) {
4120 if (scsb->scsb_state & SCSB_FROZEN) {
4123 mutex_enter(&scsb->scsb_mutex);
4125 if ((i = scsb_readall_regs(scsb)) != 0 &&
4126 scsb->scsb_state & SCSB_DEBUG_MODE)
4130 if ((i = scsb_check_config_status(scsb)) == 0) {
4131 i = scsb_set_scfg_pres_leds(scsb, NULL);
4134 mutex_exit(&scsb->scsb_mutex);
4142 smp->scsb_reg[i] = scsb->scsb_data_reg[i];
4149 * the state of what we have for scsb. This routine is called only when
4152 * Also, set state to SCSB_FROZEN which denies access to scsb while in
4161 scsb_freeze_check(scsb_state_t *scsb)
4172 cmn_err(CE_NOTE, "scsb_freeze_check(%d):", scsb->scsb_instance);
4174 if (scsb->scsb_state & SCSB_FROZEN) {
4177 mutex_enter(&scsb->scsb_mutex);
4189 slotnum = tonga_psl_to_ssl(scsb, unit);
4197 if (scsb->scsb_data_reg[index] & (1 << offset)) {
4201 scsb->scsb_instance, unit);
4205 mutex_exit(&scsb->scsb_mutex);
4209 scsb_freeze(scsb_state_t *scsb)
4214 scsb->scsb_instance);
4216 if (scsb->scsb_state & SCSB_FROZEN)
4218 scsb->scsb_state |= SCSB_FROZEN;
4219 scsb->scsb_state &= ~SCSB_SCB_PRESENT;
4220 (void) scsb_hsc_freeze(scsb->scsb_dev);
4226 if (!(scsb->scsb_state & SCSB_IN_INTR))
4228 check_fru_info(scsb, code);
4229 add_event_code(scsb, code);
4230 (void) scsb_queue_ops(scsb, QPUT_INT32, 1, &code, "scsb_freeze");
4239 scsb_restore(scsb_state_t *scsb)
4242 cmn_err(CE_NOTE, "scsb_restore(%d):", scsb->scsb_instance);
4244 if (initialize_scb(scsb) != DDI_SUCCESS) {
4251 if (scsb_clear_intmasks(scsb)) {
4253 "scsb%d: I2C TRANSFER Failed", scsb->scsb_instance);
4262 if (scsb_fru_op(scsb, ALARM, 1, SCTRL_SYSCFG_BASE,
4264 scsb->scsb_hsc_state |= SCSB_ALARM_CARD_PRES;
4266 scsb->scsb_hsc_state &= ~SCSB_ALARM_CARD_PRES;
4268 scsb->scsb_state &= ~SCSB_FROZEN;
4269 (void) scsb_hsc_restore(scsb->scsb_dev);
4303 * scsb interrupt handler for (MC) PSM_INT vector
4320 * needs to do is to ask scsb to release the interrupt line.
4326 scsb_state_t *scsb = (scsb_state_t *)arg;
4333 * happen only if the interrupt does not belong to scsb, and some
4338 if (scsb->scsb_state & SCSB_IN_INTR) {
4341 (void) scsb_toggle_psmint(scsb, 1);
4342 scsb->scsb_state &= ~SCSB_IN_INTR;
4345 scsb->scsb_state |= SCSB_IN_INTR;
4348 * Stop scsb from interrupting first.
4350 if (scsb_quiesce_psmint(scsb) != DDI_SUCCESS) {
4367 static void scsb_healthy_intr(scsb_state_t *scsb, int pslotnum);
4371 scsb_state_t *scsb = (scsb_state_t *)arg;
4386 mutex_enter(&scsb->scsb_mutex);
4388 cv_wait(&scsb->scsb_cv, &scsb->scsb_mutex);
4390 mutex_exit(&scsb->scsb_mutex);
4394 cmn_err(CE_NOTE, "scsb_intr(%d)", scsb->scsb_instance);
4407 if (!(scsb->scsb_state & SCSB_SSB_PRESENT)) {
4408 if (scb_check_version(scsb) != DDI_SUCCESS) {
4410 if (scsb->scsb_state & SCSB_SSB_PRESENT &&
4411 scsb->scsb_i2c_errcnt > scsb_err_threshold)
4412 scsb_failing_event(scsb);
4434 /* read the interrupt register from scsb */
4435 if (scsb_rdwr_register(scsb, I2C_WR_RD, intr_addr,
4440 if (scsb->scsb_state & SCSB_SSB_PRESENT &&
4441 scsb->scsb_i2c_errcnt > scsb_err_threshold)
4442 scsb_failing_event(scsb);
4501 scsb->scsb_instance);
4503 scsb_restore(scsb);
4512 * scsb_write_mask(scsb, tmp_reg, 0, clr_bits, 0);
4532 if (scsb_rdwr_register(scsb, I2C_WR_RD, tmp_reg,
4556 if (retval == 0 && scsb_check_config_status(scsb)) {
4559 if (scsb->scsb_state & SCSB_P06_NOINT_KLUGE) {
4565 if (scsb->scsb_state & SCSB_SSB_PRESENT &&
4566 scsb->scsb_i2c_errcnt > scsb_err_threshold) {
4567 scsb_failing_event(scsb);
4584 scsb->scsb_data_reg[index++] =
4589 if (intr_reg && scsb_read_bhealthy(scsb) != 0) {
4591 " Registers", ddi_driver_name(scsb->scsb_dev),
4592 ddi_get_instance(scsb->scsb_dev));
4594 if (scsb->scsb_state & SCSB_SSB_PRESENT &&
4595 scsb->scsb_i2c_errcnt > scsb_err_threshold) {
4596 scsb_failing_event(scsb);
4610 if (scsb_rdwr_register(scsb, I2C_WR, intr_addr,
4615 if (scsb->scsb_state & SCSB_SSB_PRESENT &&
4616 scsb->scsb_i2c_errcnt > scsb_err_threshold) {
4617 scsb_failing_event(scsb);
4643 cstatus_regs[i] = scsb->scsb_data_reg[index + i];
4690 scsb->scsb_data_reg[index] = scb_intr_regs[intr_idx];
4741 " INT.", scsb->scsb_instance);
4744 if (scsb->scsb_state & SCSB_OPEN &&
4745 scsb->scsb_rq != (queue_t *)NULL) {
4749 * event code to EnvMon scsb policy
4752 (void) scsb_queue_put(scsb->scsb_rq, 1,
4762 scsb->scsb_instance);
4764 scsb_freeze_check(scsb);
4765 scsb_freeze(scsb);
4778 scsb->scsb_instance);
4785 * scsb_restore(scsb);
4806 scsb->scsb_instance);
4859 slotnum = tonga_ssl_to_psl(scsb, unit);
4869 if (scsb->scsb_state & SCSB_IS_TONGA) {
4884 (scsb->scsb_hsc_state &
4903 DEBUG2("AC Intr %d(%d)\n", scsb->ac_slotnum, idx+1);
4904 val = scsb_fru_op(scsb, SLOT,
4905 tonga_ssl_to_psl(scsb, scsb->ac_slotnum),
4907 ac_present = scsb_fru_op(scsb, ALARM, 1,
4918 (scsb->scsb_hsc_state &
4925 if (scsb->scsb_hsc_state & SCSB_AC_SLOT_INTR_DONE)
4926 scsb->scsb_hsc_state &= ~SCSB_AC_SLOT_INTR_DONE;
4928 scsb->scsb_hsc_state |= SCSB_AC_SLOT_INTR_DONE;
4935 if (scsb->scsb_state & SCSB_IS_TONGA) {
4943 (scsb->scsb_hsc_state & SCSB_HSC_CTC_PRES &&
4948 if (scsb_is_alarm_card_slot(scsb, slotnum) == B_TRUE) {
4952 val = scsb_fru_op(scsb, SLOT, unit, SCTRL_SYSCFG_BASE,
4955 ac_present = scsb_fru_op(scsb, ALARM, 1,
4961 (scsb->scsb_hsc_state &
4969 if (scsb->scsb_hsc_state & SCSB_AC_SLOT_INTR_DONE)
4970 scsb->scsb_hsc_state &= ~SCSB_AC_SLOT_INTR_DONE;
4972 scsb->scsb_hsc_state |= SCSB_AC_SLOT_INTR_DONE;
4981 scsb->scsb_hsc_state |= SCSB_ALARM_CARD_PRES;
4993 (void) scsb_connect_slot(scsb, slotnum, B_FALSE);
4996 (scsb->scsb_hsc_state & SCSB_ALARM_CARD_PRES)) {
5006 scsb->scsb_hsc_state &= ~SCSB_ALARM_CARD_PRES;
5012 (void) scsb_disconnect_slot(scsb, B_FALSE, slotnum);
5043 error = scsb_set_scfg_pres_leds(scsb, fru_ptr);
5048 if (!(scsb->scsb_state &
5071 scsb->scsb_data_reg[index++] = scb_intr_regs[intr_idx];
5079 slotnum = tonga_ssl_to_psl(scsb, idx + 1);
5080 if (scsb->scsb_state & SCSB_IS_TONGA) {
5088 (scsb->scsb_hsc_state &
5094 scsb_healthy_intr(scsb, slotnum);
5103 !(scsb->scsb_state & SCSB_P06_NOINT_KLUGE)) {
5104 check_fru_info(scsb, code);
5105 add_event_code(scsb, code);
5106 (void) scsb_queue_ops(scsb, QPUT_INT32, 1, &scsb_event_code,
5118 mutex_enter(&scsb->scsb_mutex);
5120 cv_broadcast(&scsb->scsb_cv);
5121 mutex_exit(&scsb->scsb_mutex);
5126 (void) scsb_toggle_psmint(scsb, 1);
5127 scsb->scsb_state &= ~SCSB_IN_INTR;
5131 scsb_polled_int(scsb_state_t *scsb, int cmd, uint32_t *set)
5134 cmn_err(CE_NOTE, "scsb_polled_int(scsb,0x%x)", cmd);
5142 if (scsb->scsb_state & SCSB_P06_NOINT_KLUGE) {
5147 (void) scsb_intr((caddr_t)scsb);
5164 scsb_leds_switch(scsb_state_t *scsb, scsb_ustate_t op)
5170 if (scsb->scsb_state & SCSB_FROZEN &&
5171 !(scsb->scsb_state & SCSB_IN_INTR)) {
5180 cmn_err(CE_NOTE, "scsb%d: turning all NOK LEDs %s",
5181 scsb->scsb_instance,
5192 scsb->scsb_data_reg[index + i] = idata;
5194 mutex_enter(&scsb->scsb_mutex);
5195 i = scsb_rdwr_register(scsb, I2C_WR, reg, SCTRL_LED_NOK_NUMREGS,
5197 mutex_exit(&scsb->scsb_mutex);
5206 cmn_err(CE_NOTE, "scsb%d: turning all OK LEDs %s",
5207 scsb->scsb_instance,
5214 scsb->scsb_data_reg[index + i] = idata;
5216 mutex_enter(&scsb->scsb_mutex);
5217 i = scsb_rdwr_register(scsb, I2C_WR, reg, SCTRL_LED_OK_NUMREGS,
5219 mutex_exit(&scsb->scsb_mutex);
5232 scsb->scsb_data_reg[index + i] = idata;
5234 mutex_enter(&scsb->scsb_mutex);
5235 i = scsb_rdwr_register(scsb, I2C_WR, reg, SCTRL_BLINK_NUMREGS,
5237 mutex_exit(&scsb->scsb_mutex);
5249 scsb_readall_regs(scsb_state_t *scsb)
5260 if (scsb->scsb_state & SCSB_FROZEN) {
5265 error = scsb_rdwr_register(scsb, I2C_WR_RD, reg, SCSB_DATA_REGISTERS,
5266 &scsb->scsb_data_reg[index], 1);
5278 scsb_write_mask(scsb_state_t *scsb,
5292 if (scsb->scsb_state & SCSB_FROZEN &&
5293 !(scsb->scsb_state & SCSB_IN_INTR)) {
5297 i2cxferp = (i2c_transfer_t *)scsb->scsb_i2ctp;
5303 scsb->scsb_kstat_flag = B_TRUE; /* we did a i2c transaction */
5304 if (error = nct_i2c_transfer(scsb->scsb_phandle, i2cxferp)) {
5308 scsb->scsb_i2c_errcnt = 0;
5323 if (error = nct_i2c_transfer(scsb->scsb_phandle, i2cxferp)) {
5329 scsb->scsb_data_reg[index] = reg_data;
5332 scsb->scsb_i2c_errcnt = 0;
5335 scsb->scsb_i2c_errcnt++;
5336 if (scsb->scsb_i2c_errcnt > scsb_err_threshold)
5337 scsb->scsb_err_flag = B_TRUE; /* latch error */
5338 if (scsb->scsb_state & SCSB_SSB_PRESENT) {
5347 if (scsb->scsb_i2c_errcnt >= scsb_freeze_count)
5348 scsb_freeze(scsb);
5359 scsb_rdwr_register(scsb_state_t *scsb, int op, uchar_t reg, int len,
5366 cmn_err(CE_NOTE, "scsb_rdwr_register(scsb,%s,%x,%x,buf):",
5369 if (scsb->scsb_state & SCSB_FROZEN &&
5370 !(scsb->scsb_state & SCSB_IN_INTR)) {
5374 i2cxferp = scsb_alloc_i2ctx(scsb->scsb_phandle, I2C_NOSLEEP);
5382 i2cxferp = scsb->scsb_i2ctp;
5391 scsb->scsb_data_reg[index + i] =
5406 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
5414 scsb->scsb_kstat_flag = B_TRUE; /* we did a i2c transaction */
5415 if (error = nct_i2c_transfer(scsb->scsb_phandle, i2cxferp)) {
5420 scsb->scsb_data_reg[index + i] = rwbuf[i] =
5429 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
5431 scsb->scsb_i2c_errcnt++;
5432 if (scsb->scsb_i2c_errcnt > scsb_err_threshold)
5433 scsb->scsb_err_flag = B_TRUE; /* latch error */
5434 if (!(scsb->scsb_state & SCSB_SSB_PRESENT)) {
5435 if (scsb->scsb_i2c_errcnt >= scsb_freeze_count)
5436 scsb_freeze(scsb);
5444 scsb->scsb_i2c_errcnt = 0;
5458 check_fru_info(scsb_state_t *scsb, int evcode)
5467 cmn_err(CE_NOTE, "check_fru_info(scsb,0x%x)", evcode);
5476 check_fru_info(scsb, new_evcode);
5482 check_fru_info(scsb, new_evcode);
5485 update_fru_info(scsb, fru_ptr);
5495 scsb_freeze_check(scsb);
5519 check_fru_info(scsb, new_evcode);
5524 * scsb kstat support functions.
5531 scsb_alloc_kstats(scsb_state_t *scsb)
5541 if ((scsb->ks_leddata = kstat_create(scsb_name, scsb->scsb_instance,
5545 scsb->scsb_state |= SCSB_KSTATS;
5546 scsb_free_kstats(scsb);
5549 scsb->ks_leddata->ks_update = update_ks_leddata;
5550 scsb->ks_leddata->ks_private = (void *)scsb;
5551 if (update_ks_leddata(scsb->ks_leddata, KSTAT_READ) != DDI_SUCCESS) {
5552 scsb->scsb_state |= SCSB_KSTATS;
5553 scsb_free_kstats(scsb);
5556 kstat_install(scsb->ks_leddata);
5564 if ((scsb->ks_state = kstat_create(scsb_name, scsb->scsb_instance,
5568 scsb->scsb_state |= SCSB_KSTATS;
5569 scsb_free_kstats(scsb);
5572 scsb->ks_state->ks_update = update_ks_state;
5573 scsb->ks_state->ks_private = (void *)scsb;
5574 if (update_ks_state(scsb->ks_state, KSTAT_READ) != DDI_SUCCESS) {
5575 scsb->scsb_state |= SCSB_KSTATS;
5576 scsb_free_kstats(scsb);
5579 kstat_install(scsb->ks_state);
5587 if ((scsb->ks_topology = kstat_create(scsb_name, scsb->scsb_instance,
5591 scsb->scsb_state |= SCSB_KSTATS;
5592 scsb_free_kstats(scsb);
5595 scsb->ks_topology->ks_update = update_ks_topology;
5596 scsb->ks_topology->ks_private = (void *)scsb;
5597 if (update_ks_topology(scsb->ks_topology, KSTAT_READ) != DDI_SUCCESS) {
5598 scsb->scsb_state |= SCSB_KSTATS;
5599 scsb_free_kstats(scsb);
5602 kstat_install(scsb->ks_topology);
5610 if ((scsb->ks_evcreg = kstat_create(scsb_name, scsb->scsb_instance,
5613 scsb->scsb_state |= SCSB_KSTATS;
5614 scsb_free_kstats(scsb);
5617 scsb->ks_evcreg->ks_update = update_ks_evcreg;
5618 scsb->ks_evcreg->ks_private = (void *)scsb;
5619 kn = KSTAT_NAMED_PTR(scsb->ks_evcreg);
5622 kstat_install(scsb->ks_evcreg);
5626 scsb->scsb_state |= SCSB_KSTATS;
5633 scsb_state_t *scsb;
5638 scsb = (scsb_state_t *)ksp->ks_private;
5641 scsb->scsb_state & SCSB_KS_UPDATE ? " " : " not ");
5647 * if (scsb->scsb_state & SCSB_FROZEN) {
5654 mutex_enter(&scsb->scsb_mutex);
5655 while (scsb->scsb_state & SCSB_KS_UPDATE) {
5656 if (cv_wait_sig(&scsb->scsb_cv, &scsb->scsb_mutex) <= 0) {
5657 mutex_exit(&scsb->scsb_mutex);
5661 scsb->scsb_state |= SCSB_KS_UPDATE;
5662 mutex_exit(&scsb->scsb_mutex);
5678 reg = tonga_slotnum_led_shift(scsb, scsb->scsb_data_reg[index]);
5680 reg = scsb->scsb_data_reg[index];
5683 pks_leddata->scb_led_regs[i] = scsb->scsb_data_reg[index];
5689 reg = tonga_slotnum_led_shift(scsb, scsb->scsb_data_reg[index]);
5691 reg = scsb->scsb_data_reg[index];
5694 pks_leddata->scb_led_regs[i] = scsb->scsb_data_reg[index];
5700 reg = tonga_slotnum_led_shift(scsb, scsb->scsb_data_reg[index]);
5702 reg = scsb->scsb_data_reg[index];
5705 pks_leddata->scb_led_regs[i] = scsb->scsb_data_reg[index];
5706 mutex_enter(&scsb->scsb_mutex);
5707 scsb->scsb_state &= ~SCSB_KS_UPDATE;
5708 cv_signal(&scsb->scsb_cv);
5709 mutex_exit(&scsb->scsb_mutex);
5718 scsb_state_t *scsb;
5723 scsb = (scsb_state_t *)ksp->ks_private;
5727 scsb->scsb_state & SCSB_KS_UPDATE ? " " : " not ");
5731 * if (scsb->scsb_state & SCSB_FROZEN) {
5735 mutex_enter(&scsb->scsb_mutex);
5736 while (scsb->scsb_state & SCSB_KS_UPDATE) {
5737 if (cv_wait_sig(&scsb->scsb_cv, &scsb->scsb_mutex) <= 0) {
5738 mutex_exit(&scsb->scsb_mutex);
5742 scsb->scsb_state |= SCSB_KS_UPDATE;
5743 mutex_exit(&scsb->scsb_mutex);
5753 if (add_event_proc(scsb, pid)) {
5764 if (del_event_proc(scsb, pid)) {
5777 rew_event_proc(scsb);
5784 mutex_enter(&scsb->scsb_mutex);
5785 scsb->scsb_state &= ~SCSB_KS_UPDATE;
5786 cv_signal(&scsb->scsb_cv);
5787 mutex_exit(&scsb->scsb_mutex);
5794 scsb_state_t *scsb;
5799 scsb = (scsb_state_t *)ksp->ks_private;
5802 scsb->scsb_state & SCSB_KS_UPDATE ? " " : " not ");
5806 * if (scsb->scsb_state & SCSB_FROZEN) {
5813 mutex_enter(&scsb->scsb_mutex);
5814 while (scsb->scsb_state & SCSB_KS_UPDATE) {
5815 if (cv_wait_sig(&scsb->scsb_cv, &scsb->scsb_mutex) <= 0) {
5816 mutex_exit(&scsb->scsb_mutex);
5820 scsb->scsb_state |= SCSB_KS_UPDATE;
5822 * If SSB not present and scsb not SCSB_FROZEN, check for SCB presence
5824 * scsb_freeze() will be called to update SCB info and scsb state.
5826 if (!(scsb->scsb_state & SCSB_SSB_PRESENT) &&
5827 !(scsb->scsb_state & SCSB_FROZEN)) {
5830 if (data = scsb_rdwr_register(scsb, I2C_WR_RD,
5836 mutex_exit(&scsb->scsb_mutex);
5838 pks_state->scb_present = (scsb->scsb_state & SCSB_SCB_PRESENT) ? 1 : 0;
5839 pks_state->ssb_present = (scsb->scsb_state & SCSB_SSB_PRESENT) ? 1 : 0;
5840 pks_state->scsb_frozen = (scsb->scsb_state & SCSB_FROZEN) ? 1 : 0;
5841 if (scsb->scsb_state & SCSB_DEBUG_MODE)
5843 else if (scsb->scsb_state & SCSB_DIAGS_MODE)
5851 if (scsb->scsb_state & SCSB_KSTATS) {
5872 mutex_enter(&scsb->scsb_mutex);
5873 scsb->scsb_state &= ~SCSB_KS_UPDATE;
5874 cv_signal(&scsb->scsb_cv);
5875 mutex_exit(&scsb->scsb_mutex);
5882 scsb_state_t *scsb;
5887 scsb = (scsb_state_t *)ksp->ks_private;
5890 scsb->scsb_state & SCSB_KS_UPDATE ? " " : " not ");
5894 * if (scsb->scsb_state & SCSB_FROZEN) {
5901 mutex_enter(&scsb->scsb_mutex);
5902 while (scsb->scsb_state & SCSB_KS_UPDATE) {
5903 if (cv_wait_sig(&scsb->scsb_cv, &scsb->scsb_mutex) <= 0) {
5904 mutex_exit(&scsb->scsb_mutex);
5908 scsb->scsb_state |= SCSB_KS_UPDATE;
5910 * If SSB not present and scsb not SCSB_FROZEN, check for SCB presence
5912 * scsb_freeze() will be called to update SCB info and scsb state.
5914 if (!(scsb->scsb_state & SCSB_SSB_PRESENT) &&
5915 !(scsb->scsb_state & SCSB_FROZEN)) {
5918 if (data = scsb_rdwr_register(scsb, I2C_WR_RD,
5924 mutex_exit(&scsb->scsb_mutex);
5946 slotnum = tonga_psl_to_ssl(scsb, i+1);
5947 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_BHLTHY_BASE,
5996 * To get the scsb health, if there was no i2c transaction
5999 if (scsb->scsb_kstat_flag == B_FALSE) {
6001 (void) scsb_blind_read(scsb, I2C_WR_RD,
6004 pks_topo->mct_scb[i].fru_health = ((scsb->scsb_err_flag ==
6005 B_TRUE || scsb->scsb_i2c_errcnt > scsb_err_threshold)
6012 scsb->scsb_err_flag = B_FALSE; /* clear error flag once read */
6013 scsb->scsb_kstat_flag = B_FALSE; /* false? read from i2c */
6060 mutex_enter(&scsb->scsb_mutex);
6061 scsb->scsb_state &= ~SCSB_KS_UPDATE;
6062 cv_signal(&scsb->scsb_cv);
6063 mutex_exit(&scsb->scsb_mutex);
6068 scsb_free_kstats(scsb_state_t *scsb)
6070 if (!(scsb->scsb_state & SCSB_KSTATS))
6075 if (scsb->ks_evcreg != NULL) {
6076 kstat_delete(scsb->ks_evcreg);
6078 if (scsb->ks_topology != NULL) {
6079 kstat_delete(scsb->ks_topology);
6081 if (scsb->ks_state != NULL) {
6082 kstat_delete(scsb->ks_state);
6084 if (scsb->ks_leddata != NULL) {
6085 kstat_delete(scsb->ks_leddata);
6087 scsb->ks_leddata = NULL;
6088 scsb->ks_state = NULL;
6089 scsb->ks_topology = NULL;
6090 scsb->ks_evcreg = NULL;
6091 scsb->scsb_state &= ~SCSB_KSTATS;
6097 * Miscellaneous scsb internal functions.
6124 update_fru_info(scsb_state_t *scsb, fru_info_t *fru_ptr)
6131 cmn_err(CE_NOTE, "update_fru_info(scsb,0x%p)", (void *)fru_ptr);
6144 acslot_id = fru_id_table[(scsb->ac_slotnum - 1)];
6150 if (scsb->scsb_state & SCSB_SCB_PRESENT)
6156 if (scsb->scsb_data_reg[index] & (1 << bit)) {
6223 prom_printf("scsb: ");
6241 signal_evc_procs(scsb_state_t *scsb)
6251 "scsb:signal_evc_procs: "
6255 (void) del_event_proc(scsb,
6284 reset_evc_fifo(scsb_state_t *scsb)
6297 add_event_code(scsb_state_t *scsb, uint32_t event_code)
6299 if (event_proc_count(scsb) == 0) {
6312 signal_evc_procs(scsb);
6357 add_event_proc(scsb_state_t *scsb, pid_t pid)
6401 del_event_proc(scsb_state_t *scsb, pid_t pid)
6418 reset_evc_fifo(scsb);
6441 rew_event_proc(scsb_state_t *scsb)
6459 event_proc_count(scsb_state_t *scsb)
6564 scsb_queue_ops(scsb_state_t *scsb,
6575 if (scsb->scsb_opens && scsb->scsb_rq != NULL &&
6576 scsb_queue_put(scsb->scsb_rq, oparg,
6595 clptr = &scsb->clone_devs[clone];
6637 scsb_fru_op(scsb_state_t *scsb, scsb_utype_t fru_type, int unit, int base,
6647 ac_val = scsb->scsb_data_reg[index+1] & ac_mask;
6669 rc = (scsb->scsb_data_reg[idx] & (1 << offset))
6673 rc = scsb->scsb_data_reg[idx];
6691 scsb_get_slot_state(scsb_state_t *scsb, int pslotnum, int *rstate)
6699 * If scsb is already in the doing interrupt postprocess, wait..
6702 rc = scsb_check_config_status(scsb);
6707 slotnum = tonga_psl_to_ssl(scsb, pslotnum);
6708 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_SYSCFG_BASE,
6718 rc = scsb_reset_slot(scsb, pslotnum, SCSB_GET_SLOT_RESET_STATUS);
6722 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_RESET_BASE,
6727 if (scsb_fru_op(scsb, SLOT, slotnum, SCTRL_BHLTHY_BASE,
6733 ddi_driver_name(scsb->scsb_dev),
6734 ddi_get_instance(scsb->scsb_dev), slotnum);
6742 scsb_reset_slot(scsb_state_t *scsb, int pslotnum, int reset_flag)
6752 if (scsb->scsb_state & SCSB_FROZEN)
6754 if ((i2cxferp = scsb_alloc_i2ctx(scsb->scsb_phandle,
6758 slotnum = tonga_psl_to_ssl(scsb, pslotnum);
6760 if (scsb_is_alarm_card_slot(scsb, pslotnum) == B_TRUE) {
6767 mutex_enter(&scsb->scsb_mutex);
6772 scsb->scsb_kstat_flag = B_TRUE; /* we did an i2c transaction */
6773 if ((error = nct_i2c_transfer(scsb->scsb_phandle, i2cxferp)) == 0) {
6774 scsb->scsb_i2c_errcnt = 0;
6779 scsb->scsb_data_reg[index] = i2cxferp->i2c_rbuf[0];
6780 scsb->scsb_data_reg[index+1] = i2cxferp->i2c_rbuf[1];
6782 scsb->scsb_i2c_errcnt++;
6783 if (scsb->scsb_i2c_errcnt > scsb_err_threshold)
6784 scsb->scsb_err_flag = B_TRUE; /* latch until kstat */
6785 if (!(scsb->scsb_state & SCSB_SSB_PRESENT)) {
6786 if (scsb->scsb_i2c_errcnt >= scsb_freeze_count)
6787 mutex_exit(&scsb->scsb_mutex);
6788 scsb_freeze(scsb);
6789 mutex_enter(&scsb->scsb_mutex);
6793 ddi_driver_name(scsb->scsb_dev),
6794 ddi_get_instance(scsb->scsb_dev));
6798 DEBUG2("pre-reset regs = %x,%x\n", scsb->scsb_data_reg[index],
6799 scsb->scsb_data_reg[index+1]);
6801 mutex_exit(&scsb->scsb_mutex);
6802 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
6806 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_RESET_BASE,
6809 ac_val = scsb_fru_op(scsb, ALARM, 1, SCTRL_RESET_BASE,
6851 i2cxferp->i2c_wbuf[0] = scsb_fru_op(scsb, SLOT, slotnum,
6855 scsb_fru_op(scsb, SLOT, slotnum,
6858 scsb_fru_op(scsb, SLOT, slotnum,
6864 scsb_fru_op(scsb, ALARM, 1,
6870 scsb_fru_op(scsb, SLOT, slotnum,
6873 ~(scsb_fru_op(scsb, SLOT, slotnum,
6879 scsb_fru_op(scsb, ALARM, 1,
6885 if (error = nct_i2c_transfer(scsb->scsb_phandle, i2cxferp)) {
6886 scsb->scsb_i2c_errcnt++;
6887 if (scsb->scsb_i2c_errcnt > scsb_err_threshold)
6888 scsb->scsb_err_flag = B_TRUE; /* latch error */
6889 mutex_exit(&scsb->scsb_mutex);
6890 if (!(scsb->scsb_state & SCSB_SSB_PRESENT)) {
6891 if (scsb->scsb_i2c_errcnt >= scsb_freeze_count)
6892 scsb_freeze(scsb);
6896 ddi_driver_name(scsb->scsb_dev),
6897 ddi_get_instance(scsb->scsb_dev),
6899 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
6903 scsb->scsb_i2c_errcnt = 0;
6904 /* now read back and update our scsb structure */
6909 if ((error = nct_i2c_transfer(scsb->scsb_phandle,
6911 scsb->scsb_i2c_errcnt = 0;
6912 scsb->scsb_data_reg[index] = i2cxferp->i2c_rbuf[0];
6913 scsb->scsb_data_reg[index+1] = i2cxferp->i2c_rbuf[1];
6915 scsb->scsb_i2c_errcnt++;
6916 if (scsb->scsb_i2c_errcnt > scsb_err_threshold)
6917 scsb->scsb_err_flag = B_TRUE; /* latch error */
6918 mutex_exit(&scsb->scsb_mutex);
6919 if (!(scsb->scsb_state & SCSB_SSB_PRESENT)) {
6920 if (scsb->scsb_i2c_errcnt >= scsb_freeze_count)
6921 scsb_freeze(scsb);
6925 ddi_driver_name(scsb->scsb_dev),
6926 ddi_get_instance(scsb->scsb_dev));
6927 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
6931 DEBUG2("post-reset regs = %x,%x\n", scsb->scsb_data_reg[index],
6932 scsb->scsb_data_reg[index+1]);
6933 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_RESET_BASE,
6937 ac_val = scsb_fru_op(scsb, ALARM, 1, SCTRL_RESET_BASE,
6943 scsb_fru_op(scsb, SLOT, slotnum,
6958 scsb_fru_op(scsb, SLOT, slotnum,
6971 mutex_exit(&scsb->scsb_mutex);
6972 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
6978 scsb_connect_slot(scsb_state_t *scsb, int pslotnum, int healthy)
6991 slotnum = tonga_psl_to_ssl(scsb, pslotnum);
7003 if (scsb_read_bhealthy(scsb) != 0)
7005 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_BHLTHY_BASE,
7018 " slot %d", ddi_driver_name(scsb->scsb_dev),
7019 ddi_get_instance(scsb->scsb_dev), pslotnum);
7022 if ((scsb_is_alarm_card_slot(scsb, pslotnum) == B_TRUE) &&
7023 (scsb->scsb_hsc_state & SCSB_ALARM_CARD_PRES))
7029 scsb_disconnect_slot(scsb_state_t *scsb, int occupied, int slotnum)
7034 if (scsb_reset_slot(scsb, slotnum, SCSB_RESET_SLOT) != 0) {
7050 if ((scsb_is_alarm_card_slot(scsb, slotnum) == B_TRUE) &&
7051 (scsb->scsb_hsc_state & SCSB_ALARM_CARD_PRES))
7057 scsb_is_alarm_card_slot(scsb_state_t *scsb, int slotnum)
7059 return ((scsb->ac_slotnum == slotnum)? B_TRUE:B_FALSE);
7063 * Invoked both by the hsc and the scsb module to exchanges necessary
7065 * scsb calls this function to unconfigure the alarm card while the
7071 scsb_hsc_ac_op(scsb_state_t *scsb, int pslotnum, int op)
7076 if (!(scsb->scsb_hsc_state & SCSB_HSC_INIT &&
7077 scsb->scsb_hsc_state & SCSB_ALARM_CARD_PRES)) {
7079 "scsb: HSC not initialized or AC not present!");
7083 /* hsc -> scsb */
7085 if (scsb->scsb_hsc_state & SCSB_ALARM_CARD_IN_USE)
7089 /* API -> scsb */
7101 scsb->scsb_hsc_state |= SCSB_ALARM_CARD_IN_USE;
7105 /* hsc -> scsb */
7114 * Send the ALARM_CARD_CONFIGURE Event to all scsb
7118 (void) scsb_queue_ops(scsb, QPUT_INT32, 1,
7123 /* hsc -> scsb */
7136 (void) scsb_queue_ops(scsb, QPUT_INT32, 1,
7141 /* API -> scsb -> hsc */
7154 scsb->scsb_hsc_state &= ~SCSB_ALARM_CARD_IN_USE;
7155 hsc_ac_op((int)scsb->scsb_instance, pslotnum,
7167 scsb_healthy_intr(scsb_state_t *scsb, int pslotnum)
7179 if (scsb->scsb_state & SCSB_IS_TONGA) {
7188 (scsb->scsb_hsc_state & SCSB_HSC_CTC_PRES &&
7201 slotnum = tonga_psl_to_ssl(scsb, pslotnum);
7206 val = scsb_fru_op(scsb, SLOT, slotnum, SCTRL_BHLTHY_BASE,
7214 * This function will try to read from scsb irrespective of whether
7218 scsb_blind_read(scsb_state_t *scsb, int op, uchar_t reg, int len,
7225 cmn_err(CE_NOTE, "scsb_rdwr_register(scsb,%s,%x,%x,buf):",
7230 i2cxferp = scsb_alloc_i2ctx(scsb->scsb_phandle, I2C_NOSLEEP);
7238 i2cxferp = scsb->scsb_i2ctp;
7260 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
7268 scsb->scsb_kstat_flag = B_TRUE; /* we did a i2c transaction */
7269 if (error = nct_i2c_transfer(scsb->scsb_phandle, i2cxferp)) {
7282 scsb_free_i2ctx(scsb->scsb_phandle, i2cxferp);
7284 scsb->scsb_i2c_errcnt++;
7285 if (scsb->scsb_i2c_errcnt > scsb_err_threshold)
7286 scsb->scsb_err_flag = B_TRUE; /* latch error */
7288 scsb->scsb_i2c_errcnt = 0;
7300 scsb_quiesce_psmint(scsb_state_t *scsb)
7324 error = scsb_rdwr_register(scsb, I2C_WR_RD, tmp_reg,
7333 error = scsb_rdwr_register(scsb, I2C_WR, reg, 1,
7341 error = scsb_rdwr_register(scsb, I2C_WR, tmp_reg,
7346 cmn_err(CE_WARN, "scsb%d:scsb_quiesce_psmint: "
7347 " I2C TRANSFER Failed", scsb->scsb_instance);
7353 scsb->scsb_state &= ~SCSB_PSM_INT_ENABLED;
7359 /* read the interrupt register from scsb */
7360 if (error = scsb_rdwr_register(scsb, I2C_WR_RD, intr_addr,
7364 scsb->scsb_state &= ~SCSB_IN_INTR;
7368 * Write to the interrupt source registers to stop scsb
7371 if (error = scsb_rdwr_register(scsb, I2C_WR, intr_addr,
7375 scsb->scsb_state &= ~SCSB_IN_INTR;
7391 scsb_toggle_psmint(scsb_state_t *scsb, int enable)
7404 if (scsb_write_mask(scsb, reg, rmask, on, off)) {
7410 scsb->scsb_state &= ~SCSB_PSM_INT_ENABLED;
7412 scsb->scsb_state |= SCSB_PSM_INT_ENABLED;
7428 * If scsb interrupt mutex is initialized, also hold the