Home | History | Annotate | Line # | Download | only in dev
lom.c revision 1.15.16.1
      1  1.15.16.1  pgoyette /*	$NetBSD: lom.c,v 1.15.16.1 2018/09/06 06:55:42 pgoyette Exp $	*/
      2        1.6  nakayama /*	$OpenBSD: lom.c,v 1.21 2010/02/28 20:44:39 kettenis Exp $	*/
      3        1.1  nakayama /*
      4        1.1  nakayama  * Copyright (c) 2009 Mark Kettenis
      5        1.1  nakayama  *
      6        1.1  nakayama  * Permission to use, copy, modify, and distribute this software for any
      7        1.1  nakayama  * purpose with or without fee is hereby granted, provided that the above
      8        1.1  nakayama  * copyright notice and this permission notice appear in all copies.
      9        1.1  nakayama  *
     10        1.1  nakayama  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11        1.1  nakayama  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12        1.1  nakayama  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13        1.1  nakayama  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14        1.1  nakayama  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15        1.1  nakayama  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16        1.1  nakayama  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17        1.1  nakayama  */
     18        1.1  nakayama 
     19        1.1  nakayama #include <sys/cdefs.h>
     20  1.15.16.1  pgoyette __KERNEL_RCSID(0, "$NetBSD: lom.c,v 1.15.16.1 2018/09/06 06:55:42 pgoyette Exp $");
     21        1.1  nakayama 
     22        1.1  nakayama #include <sys/param.h>
     23        1.1  nakayama #include <sys/device.h>
     24        1.1  nakayama #include <sys/kernel.h>
     25        1.1  nakayama #include <sys/proc.h>
     26        1.1  nakayama #include <sys/envsys.h>
     27        1.1  nakayama #include <sys/systm.h>
     28        1.1  nakayama #include <sys/callout.h>
     29        1.5  nakayama #include <sys/sysctl.h>
     30        1.1  nakayama 
     31        1.1  nakayama #include <machine/autoconf.h>
     32        1.1  nakayama 
     33        1.1  nakayama #include <dev/ebus/ebusreg.h>
     34        1.1  nakayama #include <dev/ebus/ebusvar.h>
     35        1.1  nakayama #include <dev/sysmon/sysmonvar.h>
     36        1.1  nakayama 
     37        1.1  nakayama /*
     38        1.1  nakayama  * LOMlite is a so far unidentified microcontroller.
     39        1.1  nakayama  */
     40        1.1  nakayama #define LOM1_STATUS		0x00	/* R */
     41        1.1  nakayama #define  LOM1_STATUS_BUSY	0x80
     42        1.1  nakayama #define LOM1_CMD		0x00	/* W */
     43        1.1  nakayama #define LOM1_DATA		0x01	/* R/W */
     44        1.1  nakayama 
     45        1.1  nakayama /*
     46        1.1  nakayama  * LOMlite2 is implemented as a H8/3437 microcontroller which has its
     47        1.1  nakayama  * on-chip host interface hooked up to EBus.
     48        1.1  nakayama  */
     49        1.1  nakayama #define LOM2_DATA		0x00	/* R/W */
     50        1.1  nakayama #define LOM2_CMD		0x01	/* W */
     51        1.1  nakayama #define LOM2_STATUS		0x01	/* R */
     52        1.1  nakayama #define  LOM2_STATUS_OBF	0x01	/* Output Buffer Full */
     53        1.1  nakayama #define  LOM2_STATUS_IBF	0x02	/* Input Buffer Full  */
     54        1.1  nakayama 
     55        1.1  nakayama #define LOM_IDX_CMD		0x00
     56        1.1  nakayama #define  LOM_IDX_CMD_GENERIC	0x00
     57        1.1  nakayama #define  LOM_IDX_CMD_TEMP	0x04
     58        1.1  nakayama #define  LOM_IDX_CMD_FAN	0x05
     59        1.1  nakayama 
     60        1.1  nakayama #define LOM_IDX_FW_REV		0x01	/* Firmware revision  */
     61        1.1  nakayama 
     62        1.1  nakayama #define LOM_IDX_FAN1		0x04	/* Fan speed */
     63        1.1  nakayama #define LOM_IDX_FAN2		0x05
     64        1.1  nakayama #define LOM_IDX_FAN3		0x06
     65        1.1  nakayama #define LOM_IDX_FAN4		0x07
     66        1.1  nakayama #define LOM_IDX_PSU1		0x08	/* PSU status */
     67        1.1  nakayama #define LOM_IDX_PSU2		0x09
     68        1.1  nakayama #define LOM_IDX_PSU3		0x0a
     69        1.1  nakayama #define  LOM_PSU_INPUTA		0x01
     70        1.1  nakayama #define  LOM_PSU_INPUTB		0x02
     71        1.1  nakayama #define  LOM_PSU_OUTPUT		0x04
     72        1.1  nakayama #define  LOM_PSU_PRESENT	0x08
     73        1.1  nakayama #define  LOM_PSU_STANDBY	0x10
     74        1.1  nakayama 
     75        1.1  nakayama #define LOM_IDX_TEMP1		0x18	/* Temperature */
     76        1.1  nakayama #define LOM_IDX_TEMP2		0x19
     77        1.1  nakayama #define LOM_IDX_TEMP3		0x1a
     78        1.1  nakayama #define LOM_IDX_TEMP4		0x1b
     79        1.1  nakayama #define LOM_IDX_TEMP5		0x1c
     80        1.1  nakayama #define LOM_IDX_TEMP6		0x1d
     81        1.1  nakayama #define LOM_IDX_TEMP7		0x1e
     82        1.1  nakayama #define LOM_IDX_TEMP8		0x1f
     83        1.1  nakayama 
     84        1.1  nakayama #define LOM_IDX_LED1		0x25
     85        1.1  nakayama 
     86        1.1  nakayama #define LOM_IDX_ALARM		0x30
     87        1.3  nakayama #define  LOM_ALARM_1		0x01
     88        1.3  nakayama #define  LOM_ALARM_2		0x02
     89        1.3  nakayama #define  LOM_ALARM_3		0x04
     90        1.3  nakayama #define  LOM_ALARM_FAULT	0xf0
     91        1.1  nakayama #define LOM_IDX_WDOG_CTL	0x31
     92        1.1  nakayama #define  LOM_WDOG_ENABLE	0x01
     93        1.1  nakayama #define  LOM_WDOG_RESET		0x02
     94        1.1  nakayama #define  LOM_WDOG_AL3_WDOG	0x04
     95        1.1  nakayama #define  LOM_WDOG_AL3_FANPSU	0x08
     96        1.1  nakayama #define LOM_IDX_WDOG_TIME	0x32
     97        1.1  nakayama #define  LOM_WDOG_TIME_MAX	126
     98        1.1  nakayama 
     99        1.1  nakayama #define LOM1_IDX_HOSTNAME1	0x33
    100        1.1  nakayama #define LOM1_IDX_HOSTNAME2	0x34
    101        1.1  nakayama #define LOM1_IDX_HOSTNAME3	0x35
    102        1.1  nakayama #define LOM1_IDX_HOSTNAME4	0x36
    103        1.1  nakayama #define LOM1_IDX_HOSTNAME5	0x37
    104        1.1  nakayama #define LOM1_IDX_HOSTNAME6	0x38
    105        1.1  nakayama #define LOM1_IDX_HOSTNAME7	0x39
    106        1.1  nakayama #define LOM1_IDX_HOSTNAME8	0x3a
    107        1.1  nakayama #define LOM1_IDX_HOSTNAME9	0x3b
    108        1.1  nakayama #define LOM1_IDX_HOSTNAME10	0x3c
    109        1.1  nakayama #define LOM1_IDX_HOSTNAME11	0x3d
    110        1.1  nakayama #define LOM1_IDX_HOSTNAME12	0x3e
    111        1.1  nakayama 
    112        1.1  nakayama #define LOM2_IDX_HOSTNAMELEN	0x38
    113        1.1  nakayama #define LOM2_IDX_HOSTNAME	0x39
    114        1.1  nakayama 
    115        1.1  nakayama #define LOM_IDX_CONFIG		0x5d
    116        1.1  nakayama #define LOM_IDX_FAN1_CAL	0x5e
    117        1.1  nakayama #define LOM_IDX_FAN2_CAL	0x5f
    118        1.1  nakayama #define LOM_IDX_FAN3_CAL	0x60
    119        1.1  nakayama #define LOM_IDX_FAN4_CAL	0x61
    120        1.1  nakayama #define LOM_IDX_FAN1_LOW	0x62
    121        1.1  nakayama #define LOM_IDX_FAN2_LOW	0x63
    122        1.1  nakayama #define LOM_IDX_FAN3_LOW	0x64
    123        1.1  nakayama #define LOM_IDX_FAN4_LOW	0x65
    124        1.1  nakayama 
    125        1.1  nakayama #define LOM_IDX_CONFIG2		0x66
    126        1.1  nakayama #define LOM_IDX_CONFIG3		0x67
    127        1.1  nakayama 
    128        1.1  nakayama #define LOM_IDX_PROBE55		0x7e	/* Always returns 0x55 */
    129        1.1  nakayama #define LOM_IDX_PROBEAA		0x7f	/* Always returns 0xaa */
    130        1.1  nakayama 
    131        1.1  nakayama #define LOM_IDX_WRITE		0x80
    132        1.1  nakayama 
    133        1.1  nakayama #define LOM_IDX4_TEMP_NAME_START	0x40
    134        1.1  nakayama #define LOM_IDX4_TEMP_NAME_END		0xff
    135        1.1  nakayama 
    136        1.1  nakayama #define LOM_IDX5_FAN_NAME_START		0x40
    137        1.1  nakayama #define LOM_IDX5_FAN_NAME_END		0xff
    138        1.1  nakayama 
    139        1.3  nakayama #define LOM_MAX_ALARM	4
    140        1.1  nakayama #define LOM_MAX_FAN	4
    141        1.1  nakayama #define LOM_MAX_PSU	3
    142        1.1  nakayama #define LOM_MAX_TEMP	8
    143        1.1  nakayama 
    144        1.1  nakayama struct lom_cmd {
    145        1.1  nakayama 	uint8_t			lc_cmd;
    146        1.1  nakayama 	uint8_t			lc_data;
    147        1.1  nakayama 
    148        1.1  nakayama 	TAILQ_ENTRY(lom_cmd)	lc_next;
    149        1.1  nakayama };
    150        1.1  nakayama 
    151        1.1  nakayama struct lom_softc {
    152        1.1  nakayama 	device_t		sc_dev;
    153        1.1  nakayama 	bus_space_tag_t		sc_iot;
    154        1.1  nakayama 	bus_space_handle_t	sc_ioh;
    155        1.1  nakayama 
    156        1.1  nakayama 	int			sc_type;
    157        1.1  nakayama #define LOM_LOMLITE		0
    158        1.1  nakayama #define LOM_LOMLITE2		2
    159        1.1  nakayama 	int			sc_space;
    160        1.1  nakayama 
    161        1.1  nakayama 	struct sysmon_envsys	*sc_sme;
    162        1.3  nakayama 	envsys_data_t		sc_alarm[LOM_MAX_ALARM];
    163        1.1  nakayama 	envsys_data_t		sc_fan[LOM_MAX_FAN];
    164        1.1  nakayama 	envsys_data_t		sc_psu[LOM_MAX_PSU];
    165        1.1  nakayama 	envsys_data_t		sc_temp[LOM_MAX_TEMP];
    166        1.1  nakayama 
    167        1.3  nakayama 	int			sc_num_alarm;
    168        1.1  nakayama 	int			sc_num_fan;
    169        1.1  nakayama 	int			sc_num_psu;
    170        1.1  nakayama 	int			sc_num_temp;
    171        1.1  nakayama 
    172        1.5  nakayama 	int32_t			sc_sysctl_num[LOM_MAX_ALARM];
    173        1.5  nakayama 
    174        1.8  nakayama 	struct timeval		sc_alarm_lastread;
    175        1.8  nakayama 	uint8_t			sc_alarm_lastval;
    176        1.8  nakayama 	struct timeval		sc_fan_lastread[LOM_MAX_FAN];
    177        1.8  nakayama 	struct timeval		sc_psu_lastread[LOM_MAX_PSU];
    178        1.8  nakayama 	struct timeval		sc_temp_lastread[LOM_MAX_TEMP];
    179        1.8  nakayama 
    180        1.1  nakayama 	uint8_t			sc_fan_cal[LOM_MAX_FAN];
    181        1.1  nakayama 	uint8_t			sc_fan_low[LOM_MAX_FAN];
    182        1.1  nakayama 
    183        1.1  nakayama 	char			sc_hostname[MAXHOSTNAMELEN];
    184        1.1  nakayama 
    185        1.1  nakayama 	struct sysmon_wdog	sc_smw;
    186        1.1  nakayama 	int			sc_wdog_period;
    187        1.1  nakayama 	uint8_t			sc_wdog_ctl;
    188        1.1  nakayama 	struct lom_cmd		sc_wdog_pat;
    189        1.1  nakayama 
    190        1.1  nakayama 	TAILQ_HEAD(, lom_cmd)	sc_queue;
    191        1.1  nakayama 	kmutex_t		sc_queue_mtx;
    192        1.1  nakayama 	struct callout		sc_state_to;
    193        1.1  nakayama 	int			sc_state;
    194        1.1  nakayama #define LOM_STATE_IDLE		0
    195        1.1  nakayama #define LOM_STATE_CMD		1
    196        1.1  nakayama #define LOM_STATE_DATA		2
    197        1.1  nakayama 	int			sc_retry;
    198        1.1  nakayama };
    199        1.1  nakayama 
    200        1.1  nakayama static int	lom_match(device_t, cfdata_t, void *);
    201        1.1  nakayama static void	lom_attach(device_t, device_t, void *);
    202        1.1  nakayama 
    203        1.1  nakayama CFATTACH_DECL_NEW(lom, sizeof(struct lom_softc),
    204        1.1  nakayama     lom_match, lom_attach, NULL, NULL);
    205        1.1  nakayama 
    206        1.1  nakayama static int	lom_read(struct lom_softc *, uint8_t, uint8_t *);
    207        1.1  nakayama static int	lom_write(struct lom_softc *, uint8_t, uint8_t);
    208        1.1  nakayama static void	lom_queue_cmd(struct lom_softc *, struct lom_cmd *);
    209        1.2  nakayama static void	lom_dequeue_cmd(struct lom_softc *, struct lom_cmd *);
    210        1.1  nakayama static int	lom1_read(struct lom_softc *, uint8_t, uint8_t *);
    211        1.1  nakayama static int	lom1_write(struct lom_softc *, uint8_t, uint8_t);
    212        1.1  nakayama static int	lom1_read_polled(struct lom_softc *, uint8_t, uint8_t *);
    213        1.1  nakayama static int	lom1_write_polled(struct lom_softc *, uint8_t, uint8_t);
    214        1.1  nakayama static void	lom1_queue_cmd(struct lom_softc *, struct lom_cmd *);
    215        1.1  nakayama static void	lom1_process_queue(void *);
    216        1.1  nakayama static void	lom1_process_queue_locked(struct lom_softc *);
    217        1.1  nakayama static int	lom2_read(struct lom_softc *, uint8_t, uint8_t *);
    218        1.1  nakayama static int	lom2_write(struct lom_softc *, uint8_t, uint8_t);
    219        1.2  nakayama static int	lom2_read_polled(struct lom_softc *, uint8_t, uint8_t *);
    220        1.2  nakayama static int	lom2_write_polled(struct lom_softc *, uint8_t, uint8_t);
    221        1.1  nakayama static void	lom2_queue_cmd(struct lom_softc *, struct lom_cmd *);
    222        1.2  nakayama static int	lom2_intr(void *);
    223        1.1  nakayama 
    224        1.1  nakayama static int	lom_init_desc(struct lom_softc *);
    225        1.1  nakayama static void	lom_refresh(struct sysmon_envsys *, envsys_data_t *);
    226        1.7  nakayama static void	lom_refresh_alarm(struct lom_softc *, envsys_data_t *, uint32_t);
    227        1.7  nakayama static void	lom_refresh_fan(struct lom_softc *, envsys_data_t *, uint32_t);
    228        1.7  nakayama static void	lom_refresh_psu(struct lom_softc *, envsys_data_t *, uint32_t);
    229        1.7  nakayama static void	lom_refresh_temp(struct lom_softc *, envsys_data_t *, uint32_t);
    230        1.1  nakayama static void	lom1_write_hostname(struct lom_softc *);
    231        1.1  nakayama static void	lom2_write_hostname(struct lom_softc *);
    232        1.1  nakayama 
    233        1.1  nakayama static int	lom_wdog_tickle(struct sysmon_wdog *);
    234        1.1  nakayama static int	lom_wdog_setmode(struct sysmon_wdog *);
    235        1.1  nakayama 
    236        1.2  nakayama static bool	lom_shutdown(device_t, int);
    237        1.2  nakayama 
    238        1.5  nakayama SYSCTL_SETUP_PROTO(sysctl_lom_setup);
    239        1.5  nakayama static int	lom_sysctl_alarm(SYSCTLFN_PROTO);
    240        1.5  nakayama 
    241        1.5  nakayama static const char *nodename[LOM_MAX_ALARM] =
    242        1.5  nakayama     { "fault_led", "alarm1", "alarm2", "alarm3" };
    243        1.5  nakayama #ifdef SYSCTL_INCLUDE_DESCR
    244        1.5  nakayama static const char *nodedesc[LOM_MAX_ALARM] =
    245        1.5  nakayama     { "Fault LED status", "Alarm1 status", "Alarm2 status ", "Alarm3 status" };
    246        1.5  nakayama #endif
    247        1.8  nakayama static const struct timeval refresh_interval = { 1, 0 };
    248        1.5  nakayama 
    249        1.1  nakayama static int
    250        1.1  nakayama lom_match(device_t parent, cfdata_t match, void *aux)
    251        1.1  nakayama {
    252        1.1  nakayama 	struct ebus_attach_args *ea = aux;
    253        1.1  nakayama 
    254        1.1  nakayama 	if (strcmp(ea->ea_name, "SUNW,lom") == 0 ||
    255        1.1  nakayama 	    strcmp(ea->ea_name, "SUNW,lomh") == 0)
    256        1.1  nakayama 		return (1);
    257        1.1  nakayama 
    258        1.1  nakayama 	return (0);
    259        1.1  nakayama }
    260        1.1  nakayama 
    261        1.1  nakayama static void
    262        1.1  nakayama lom_attach(device_t parent, device_t self, void *aux)
    263        1.1  nakayama {
    264        1.1  nakayama 	struct lom_softc *sc = device_private(self);
    265        1.1  nakayama 	struct ebus_attach_args *ea = aux;
    266        1.1  nakayama 	uint8_t reg, fw_rev, config, config2, config3;
    267        1.1  nakayama 	uint8_t cal, low;
    268       1.15    martin 	int i, err;
    269        1.5  nakayama 	const struct sysctlnode *node = NULL, *newnode;
    270        1.1  nakayama 
    271        1.2  nakayama 	if (strcmp(ea->ea_name, "SUNW,lomh") == 0) {
    272        1.2  nakayama 		if (ea->ea_nintr < 1) {
    273        1.2  nakayama 			aprint_error(": no interrupt\n");
    274        1.2  nakayama 			return;
    275        1.2  nakayama 		}
    276        1.1  nakayama 		sc->sc_type = LOM_LOMLITE2;
    277        1.2  nakayama 	}
    278        1.1  nakayama 
    279        1.1  nakayama 	sc->sc_dev = self;
    280        1.1  nakayama 	sc->sc_iot = ea->ea_bustag;
    281        1.1  nakayama 	if (bus_space_map(sc->sc_iot, EBUS_ADDR_FROM_REG(&ea->ea_reg[0]),
    282        1.1  nakayama 	    ea->ea_reg[0].size, 0, &sc->sc_ioh) != 0) {
    283        1.1  nakayama 		aprint_error(": can't map register space\n");
    284        1.1  nakayama 		return;
    285        1.1  nakayama 	}
    286        1.1  nakayama 
    287        1.1  nakayama 	if (sc->sc_type < LOM_LOMLITE2) {
    288        1.1  nakayama 		/* XXX Magic */
    289        1.1  nakayama 		(void)bus_space_read_1(sc->sc_iot, sc->sc_ioh, 0);
    290        1.1  nakayama 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, 3, 0xca);
    291        1.1  nakayama 	}
    292        1.1  nakayama 
    293        1.1  nakayama 	if (lom_read(sc, LOM_IDX_PROBE55, &reg) || reg != 0x55 ||
    294        1.1  nakayama 	    lom_read(sc, LOM_IDX_PROBEAA, &reg) || reg != 0xaa ||
    295        1.1  nakayama 	    lom_read(sc, LOM_IDX_FW_REV, &fw_rev) ||
    296        1.1  nakayama 	    lom_read(sc, LOM_IDX_CONFIG, &config))
    297        1.1  nakayama 	{
    298        1.1  nakayama 		aprint_error(": not responding\n");
    299        1.1  nakayama 		return;
    300        1.1  nakayama 	}
    301        1.1  nakayama 
    302        1.1  nakayama 	aprint_normal(": %s: %s rev %d.%d\n", ea->ea_name,
    303        1.1  nakayama 	    sc->sc_type < LOM_LOMLITE2 ? "LOMlite" : "LOMlite2",
    304        1.1  nakayama 	    fw_rev >> 4, fw_rev & 0x0f);
    305        1.1  nakayama 
    306        1.2  nakayama 	TAILQ_INIT(&sc->sc_queue);
    307        1.2  nakayama 	mutex_init(&sc->sc_queue_mtx, MUTEX_DEFAULT, IPL_BIO);
    308        1.2  nakayama 
    309        1.1  nakayama 	config2 = config3 = 0;
    310        1.2  nakayama 	if (sc->sc_type < LOM_LOMLITE2) {
    311        1.2  nakayama 		/*
    312        1.2  nakayama 		 * LOMlite doesn't do interrupts so we limp along on
    313        1.2  nakayama 		 * timeouts.
    314        1.2  nakayama 		 */
    315        1.2  nakayama 		callout_init(&sc->sc_state_to, 0);
    316        1.2  nakayama 		callout_setfunc(&sc->sc_state_to, lom1_process_queue, sc);
    317        1.2  nakayama 	} else {
    318        1.1  nakayama 		lom_read(sc, LOM_IDX_CONFIG2, &config2);
    319        1.1  nakayama 		lom_read(sc, LOM_IDX_CONFIG3, &config3);
    320        1.2  nakayama 
    321        1.2  nakayama 		bus_intr_establish(sc->sc_iot, ea->ea_intr[0],
    322        1.2  nakayama 		    IPL_BIO, lom2_intr, sc);
    323        1.1  nakayama 	}
    324        1.1  nakayama 
    325        1.3  nakayama 	sc->sc_num_alarm = LOM_MAX_ALARM;
    326  1.15.16.1  pgoyette 	sc->sc_num_fan = uimin((config >> 5) & 0x7, LOM_MAX_FAN);
    327  1.15.16.1  pgoyette 	sc->sc_num_psu = uimin((config >> 3) & 0x3, LOM_MAX_PSU);
    328  1.15.16.1  pgoyette 	sc->sc_num_temp = uimin((config2 >> 4) & 0xf, LOM_MAX_TEMP);
    329        1.1  nakayama 
    330        1.1  nakayama 	aprint_verbose_dev(self, "%d fan(s), %d PSU(s), %d temp sensor(s)\n",
    331        1.1  nakayama 	    sc->sc_num_fan, sc->sc_num_psu, sc->sc_num_temp);
    332        1.1  nakayama 
    333        1.1  nakayama 	for (i = 0; i < sc->sc_num_fan; i++) {
    334        1.1  nakayama 		if (lom_read(sc, LOM_IDX_FAN1_CAL + i, &cal) ||
    335        1.1  nakayama 		    lom_read(sc, LOM_IDX_FAN1_LOW + i, &low)) {
    336        1.1  nakayama 			aprint_error_dev(self, "can't read fan information\n");
    337        1.1  nakayama 			return;
    338        1.1  nakayama 		}
    339        1.1  nakayama 		sc->sc_fan_cal[i] = cal;
    340        1.1  nakayama 		sc->sc_fan_low[i] = low;
    341        1.1  nakayama 	}
    342        1.1  nakayama 
    343        1.5  nakayama 	/* Setup our sysctl subtree, hw.lomN */
    344       1.13     pooka 	sysctl_createv(NULL, 0, NULL, &node,
    345       1.13     pooka 	    0, CTLTYPE_NODE, device_xname(self), NULL,
    346       1.13     pooka 	    NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
    347        1.5  nakayama 
    348        1.1  nakayama 	/* Initialize sensor data. */
    349        1.1  nakayama 	sc->sc_sme = sysmon_envsys_create();
    350        1.3  nakayama 	for (i = 0; i < sc->sc_num_alarm; i++) {
    351        1.3  nakayama 		sc->sc_alarm[i].units = ENVSYS_INDICATOR;
    352        1.9  pgoyette 		sc->sc_alarm[i].state = ENVSYS_SINVALID;
    353       1.12     joerg 		if (i == 0)
    354       1.12     joerg 			strlcpy(sc->sc_alarm[i].desc, "Fault LED",
    355       1.12     joerg 			    sizeof(sc->sc_alarm[i].desc));
    356       1.12     joerg 		else
    357       1.12     joerg 			snprintf(sc->sc_alarm[i].desc,
    358       1.12     joerg 			    sizeof(sc->sc_alarm[i].desc), "Alarm%d", i);
    359        1.3  nakayama 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_alarm[i])) {
    360        1.3  nakayama 			sysmon_envsys_destroy(sc->sc_sme);
    361        1.3  nakayama 			aprint_error_dev(self, "can't attach alarm sensor\n");
    362        1.3  nakayama 			return;
    363        1.3  nakayama 		}
    364        1.5  nakayama 		if (node != NULL) {
    365        1.5  nakayama 			sysctl_createv(NULL, 0, NULL, &newnode,
    366        1.5  nakayama 			    CTLFLAG_READWRITE, CTLTYPE_INT, nodename[i],
    367        1.5  nakayama 			    SYSCTL_DESCR(nodedesc[i]),
    368       1.10       dsl 			    lom_sysctl_alarm, 0, (void *)sc, 0,
    369        1.5  nakayama 			    CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
    370        1.5  nakayama 			if (newnode != NULL)
    371        1.5  nakayama 				sc->sc_sysctl_num[i] = newnode->sysctl_num;
    372        1.5  nakayama 			else
    373        1.5  nakayama 				sc->sc_sysctl_num[i] = 0;
    374        1.5  nakayama 		}
    375        1.3  nakayama 	}
    376        1.1  nakayama 	for (i = 0; i < sc->sc_num_fan; i++) {
    377        1.1  nakayama 		sc->sc_fan[i].units = ENVSYS_SFANRPM;
    378        1.9  pgoyette 		sc->sc_fan[i].state = ENVSYS_SINVALID;
    379        1.1  nakayama 		snprintf(sc->sc_fan[i].desc, sizeof(sc->sc_fan[i].desc),
    380        1.1  nakayama 		    "fan%d", i + 1);
    381        1.1  nakayama 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_fan[i])) {
    382        1.1  nakayama 			sysmon_envsys_destroy(sc->sc_sme);
    383        1.1  nakayama 			aprint_error_dev(self, "can't attach fan sensor\n");
    384        1.1  nakayama 			return;
    385        1.1  nakayama 		}
    386        1.1  nakayama 	}
    387        1.1  nakayama 	for (i = 0; i < sc->sc_num_psu; i++) {
    388        1.1  nakayama 		sc->sc_psu[i].units = ENVSYS_INDICATOR;
    389        1.9  pgoyette 		sc->sc_psu[i].state = ENVSYS_SINVALID;
    390        1.1  nakayama 		snprintf(sc->sc_psu[i].desc, sizeof(sc->sc_psu[i].desc),
    391        1.1  nakayama 		    "PSU%d", i + 1);
    392        1.1  nakayama 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_psu[i])) {
    393        1.1  nakayama 			sysmon_envsys_destroy(sc->sc_sme);
    394        1.1  nakayama 			aprint_error_dev(self, "can't attach PSU sensor\n");
    395        1.1  nakayama 			return;
    396        1.1  nakayama 		}
    397        1.1  nakayama 	}
    398        1.1  nakayama 	for (i = 0; i < sc->sc_num_temp; i++) {
    399        1.1  nakayama 		sc->sc_temp[i].units = ENVSYS_STEMP;
    400        1.9  pgoyette 		sc->sc_temp[i].state = ENVSYS_SINVALID;
    401        1.1  nakayama 		snprintf(sc->sc_temp[i].desc, sizeof(sc->sc_temp[i].desc),
    402        1.1  nakayama 		    "temp%d", i + 1);
    403        1.1  nakayama 		if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_temp[i])) {
    404        1.1  nakayama 			sysmon_envsys_destroy(sc->sc_sme);
    405        1.1  nakayama 			aprint_error_dev(self, "can't attach temp sensor\n");
    406        1.1  nakayama 			return;
    407        1.1  nakayama 		}
    408        1.1  nakayama 	}
    409        1.1  nakayama 	if (lom_init_desc(sc)) {
    410        1.1  nakayama 		aprint_error_dev(self, "can't read sensor names\n");
    411        1.1  nakayama 		sysmon_envsys_destroy(sc->sc_sme);
    412        1.1  nakayama 		return;
    413        1.1  nakayama 	}
    414        1.1  nakayama 
    415        1.1  nakayama 	sc->sc_sme->sme_name = device_xname(self);
    416        1.1  nakayama 	sc->sc_sme->sme_cookie = sc;
    417        1.1  nakayama 	sc->sc_sme->sme_refresh = lom_refresh;
    418       1.15    martin 	err = sysmon_envsys_register(sc->sc_sme);
    419       1.15    martin 	if (err) {
    420        1.1  nakayama 		aprint_error_dev(self,
    421       1.15    martin 		    "unable to register envsys with sysmon, error %d\n", err);
    422        1.1  nakayama 		sysmon_envsys_destroy(sc->sc_sme);
    423        1.1  nakayama 		return;
    424        1.1  nakayama 	}
    425        1.1  nakayama 
    426        1.1  nakayama 	/* Initialize watchdog. */
    427        1.1  nakayama 	lom_write(sc, LOM_IDX_WDOG_TIME, LOM_WDOG_TIME_MAX);
    428        1.1  nakayama 	lom_read(sc, LOM_IDX_WDOG_CTL, &sc->sc_wdog_ctl);
    429        1.1  nakayama 	sc->sc_wdog_ctl &= ~(LOM_WDOG_ENABLE|LOM_WDOG_RESET);
    430        1.1  nakayama 	lom_write(sc, LOM_IDX_WDOG_CTL, sc->sc_wdog_ctl);
    431        1.1  nakayama 
    432        1.1  nakayama 	sc->sc_wdog_period = LOM_WDOG_TIME_MAX;
    433        1.1  nakayama 
    434        1.1  nakayama 	sc->sc_smw.smw_name = device_xname(self);
    435        1.1  nakayama 	sc->sc_smw.smw_cookie = sc;
    436        1.1  nakayama 	sc->sc_smw.smw_setmode = lom_wdog_setmode;
    437        1.1  nakayama 	sc->sc_smw.smw_tickle = lom_wdog_tickle;
    438        1.1  nakayama 	sc->sc_smw.smw_period = sc->sc_wdog_period;
    439        1.1  nakayama 	if (sysmon_wdog_register(&sc->sc_smw)) {
    440        1.1  nakayama 		aprint_error_dev(self,
    441        1.1  nakayama 		    "unable to register wdog with sysmon\n");
    442        1.1  nakayama 		return;
    443        1.1  nakayama 	}
    444        1.1  nakayama 
    445        1.1  nakayama 	aprint_verbose_dev(self, "Watchdog timer configured.\n");
    446        1.2  nakayama 
    447        1.2  nakayama 	if (!pmf_device_register1(self, NULL, NULL, lom_shutdown))
    448        1.2  nakayama 		aprint_error_dev(self, "unable to register power handler\n");
    449        1.1  nakayama }
    450        1.1  nakayama 
    451        1.1  nakayama static int
    452        1.1  nakayama lom_read(struct lom_softc *sc, uint8_t reg, uint8_t *val)
    453        1.1  nakayama {
    454        1.1  nakayama 	if (sc->sc_type < LOM_LOMLITE2)
    455        1.1  nakayama 		return lom1_read(sc, reg, val);
    456        1.1  nakayama 	else
    457        1.1  nakayama 		return lom2_read(sc, reg, val);
    458        1.1  nakayama }
    459        1.1  nakayama 
    460        1.1  nakayama static int
    461        1.1  nakayama lom_write(struct lom_softc *sc, uint8_t reg, uint8_t val)
    462        1.1  nakayama {
    463        1.1  nakayama 	if (sc->sc_type < LOM_LOMLITE2)
    464        1.1  nakayama 		return lom1_write(sc, reg, val);
    465        1.1  nakayama 	else
    466        1.1  nakayama 		return lom2_write(sc, reg, val);
    467        1.1  nakayama }
    468        1.1  nakayama 
    469        1.1  nakayama static void
    470        1.1  nakayama lom_queue_cmd(struct lom_softc *sc, struct lom_cmd *lc)
    471        1.1  nakayama {
    472        1.1  nakayama 	if (sc->sc_type < LOM_LOMLITE2)
    473        1.1  nakayama 		return lom1_queue_cmd(sc, lc);
    474        1.1  nakayama 	else
    475        1.1  nakayama 		return lom2_queue_cmd(sc, lc);
    476        1.1  nakayama }
    477        1.1  nakayama 
    478        1.2  nakayama static void
    479        1.2  nakayama lom_dequeue_cmd(struct lom_softc *sc, struct lom_cmd *lc)
    480        1.2  nakayama {
    481        1.2  nakayama 	struct lom_cmd *lcp;
    482        1.2  nakayama 
    483        1.2  nakayama 	mutex_enter(&sc->sc_queue_mtx);
    484        1.2  nakayama 	TAILQ_FOREACH(lcp, &sc->sc_queue, lc_next) {
    485        1.2  nakayama 		if (lcp == lc) {
    486        1.2  nakayama 			TAILQ_REMOVE(&sc->sc_queue, lc, lc_next);
    487        1.2  nakayama 			break;
    488        1.2  nakayama 		}
    489        1.2  nakayama 	}
    490        1.2  nakayama 	mutex_exit(&sc->sc_queue_mtx);
    491        1.2  nakayama }
    492        1.2  nakayama 
    493        1.1  nakayama static int
    494        1.1  nakayama lom1_read(struct lom_softc *sc, uint8_t reg, uint8_t *val)
    495        1.1  nakayama {
    496        1.1  nakayama 	struct lom_cmd lc;
    497        1.1  nakayama 	int error;
    498        1.1  nakayama 
    499        1.1  nakayama 	if (cold)
    500        1.1  nakayama 		return lom1_read_polled(sc, reg, val);
    501        1.1  nakayama 
    502        1.1  nakayama 	lc.lc_cmd = reg;
    503        1.1  nakayama 	lc.lc_data = 0xff;
    504        1.1  nakayama 	lom1_queue_cmd(sc, &lc);
    505        1.1  nakayama 
    506        1.1  nakayama 	error = tsleep(&lc, PZERO, "lomrd", hz);
    507        1.1  nakayama 	if (error)
    508        1.2  nakayama 		lom_dequeue_cmd(sc, &lc);
    509        1.1  nakayama 
    510        1.1  nakayama 	*val = lc.lc_data;
    511        1.1  nakayama 
    512        1.1  nakayama 	return (error);
    513        1.1  nakayama }
    514        1.1  nakayama 
    515        1.1  nakayama static int
    516        1.2  nakayama lom1_write(struct lom_softc *sc, uint8_t reg, uint8_t val)
    517        1.1  nakayama {
    518        1.1  nakayama 	struct lom_cmd lc;
    519        1.1  nakayama 	int error;
    520        1.1  nakayama 
    521        1.1  nakayama 	if (cold)
    522        1.1  nakayama 		return lom1_write_polled(sc, reg, val);
    523        1.1  nakayama 
    524        1.1  nakayama 	lc.lc_cmd = reg | LOM_IDX_WRITE;
    525        1.1  nakayama 	lc.lc_data = val;
    526        1.1  nakayama 	lom1_queue_cmd(sc, &lc);
    527        1.1  nakayama 
    528        1.2  nakayama 	error = tsleep(&lc, PZERO, "lomwr", 2 * hz);
    529        1.1  nakayama 	if (error)
    530        1.2  nakayama 		lom_dequeue_cmd(sc, &lc);
    531        1.1  nakayama 
    532        1.1  nakayama 	return (error);
    533        1.1  nakayama }
    534        1.1  nakayama 
    535        1.1  nakayama static int
    536        1.1  nakayama lom1_read_polled(struct lom_softc *sc, uint8_t reg, uint8_t *val)
    537        1.1  nakayama {
    538        1.1  nakayama 	uint8_t str;
    539        1.1  nakayama 	int i;
    540        1.1  nakayama 
    541        1.1  nakayama 	/* Wait for input buffer to become available. */
    542        1.1  nakayama 	for (i = 30; i > 0; i--) {
    543        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_STATUS);
    544        1.1  nakayama 		delay(1000);
    545        1.1  nakayama 		if ((str & LOM1_STATUS_BUSY) == 0)
    546        1.1  nakayama 			break;
    547        1.1  nakayama 	}
    548        1.1  nakayama 	if (i == 0)
    549        1.1  nakayama 		return (ETIMEDOUT);
    550        1.1  nakayama 
    551        1.1  nakayama 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM1_CMD, reg);
    552        1.1  nakayama 
    553        1.1  nakayama 	/* Wait until the microcontroller fills output buffer. */
    554        1.1  nakayama 	for (i = 30; i > 0; i--) {
    555        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_STATUS);
    556        1.1  nakayama 		delay(1000);
    557        1.1  nakayama 		if ((str & LOM1_STATUS_BUSY) == 0)
    558        1.1  nakayama 			break;
    559        1.1  nakayama 	}
    560        1.1  nakayama 	if (i == 0)
    561        1.1  nakayama 		return (ETIMEDOUT);
    562        1.1  nakayama 
    563        1.1  nakayama 	*val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_DATA);
    564        1.1  nakayama 	return (0);
    565        1.1  nakayama }
    566        1.1  nakayama 
    567        1.1  nakayama static int
    568        1.2  nakayama lom1_write_polled(struct lom_softc *sc, uint8_t reg, uint8_t val)
    569        1.1  nakayama {
    570        1.1  nakayama 	uint8_t str;
    571        1.1  nakayama 	int i;
    572        1.1  nakayama 
    573        1.1  nakayama 	/* Wait for input buffer to become available. */
    574        1.1  nakayama 	for (i = 30; i > 0; i--) {
    575        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_STATUS);
    576        1.1  nakayama 		delay(1000);
    577        1.1  nakayama 		if ((str & LOM1_STATUS_BUSY) == 0)
    578        1.1  nakayama 			break;
    579        1.1  nakayama 	}
    580        1.1  nakayama 	if (i == 0)
    581        1.1  nakayama 		return (ETIMEDOUT);
    582        1.1  nakayama 
    583        1.1  nakayama 	reg |= LOM_IDX_WRITE;
    584        1.1  nakayama 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM1_CMD, reg);
    585        1.1  nakayama 
    586        1.1  nakayama 	/* Wait until the microcontroller fills output buffer. */
    587        1.1  nakayama 	for (i = 30; i > 0; i--) {
    588        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_STATUS);
    589        1.1  nakayama 		delay(1000);
    590        1.1  nakayama 		if ((str & LOM1_STATUS_BUSY) == 0)
    591        1.1  nakayama 			break;
    592        1.1  nakayama 	}
    593        1.1  nakayama 	if (i == 0)
    594        1.1  nakayama 		return (ETIMEDOUT);
    595        1.1  nakayama 
    596        1.1  nakayama 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM1_DATA, val);
    597        1.1  nakayama 
    598        1.1  nakayama 	return (0);
    599        1.1  nakayama }
    600        1.1  nakayama 
    601        1.1  nakayama static void
    602        1.1  nakayama lom1_queue_cmd(struct lom_softc *sc, struct lom_cmd *lc)
    603        1.1  nakayama {
    604       1.14  nakayama 	struct lom_cmd *lcp;
    605       1.14  nakayama 
    606        1.1  nakayama 	mutex_enter(&sc->sc_queue_mtx);
    607       1.14  nakayama 	TAILQ_FOREACH(lcp, &sc->sc_queue, lc_next) {
    608       1.14  nakayama 		if (lcp == lc) {
    609       1.14  nakayama 			mutex_exit(&sc->sc_queue_mtx);
    610       1.14  nakayama 			return;
    611       1.14  nakayama 		}
    612       1.14  nakayama 	}
    613        1.1  nakayama 	TAILQ_INSERT_TAIL(&sc->sc_queue, lc, lc_next);
    614        1.1  nakayama 	if (sc->sc_state == LOM_STATE_IDLE) {
    615        1.1  nakayama 		sc->sc_state = LOM_STATE_CMD;
    616        1.1  nakayama 		lom1_process_queue_locked(sc);
    617        1.1  nakayama 	}
    618        1.1  nakayama 	mutex_exit(&sc->sc_queue_mtx);
    619        1.1  nakayama }
    620        1.1  nakayama 
    621        1.1  nakayama static void
    622        1.1  nakayama lom1_process_queue(void *arg)
    623        1.1  nakayama {
    624        1.1  nakayama 	struct lom_softc *sc = arg;
    625        1.1  nakayama 
    626        1.1  nakayama 	mutex_enter(&sc->sc_queue_mtx);
    627        1.1  nakayama 	lom1_process_queue_locked(sc);
    628        1.1  nakayama 	mutex_exit(&sc->sc_queue_mtx);
    629        1.1  nakayama }
    630        1.1  nakayama 
    631        1.1  nakayama static void
    632        1.1  nakayama lom1_process_queue_locked(struct lom_softc *sc)
    633        1.1  nakayama {
    634        1.1  nakayama 	struct lom_cmd *lc;
    635        1.1  nakayama 	uint8_t str;
    636        1.1  nakayama 
    637        1.1  nakayama 	lc = TAILQ_FIRST(&sc->sc_queue);
    638        1.2  nakayama 	if (lc == NULL) {
    639        1.2  nakayama 		sc->sc_state = LOM_STATE_IDLE;
    640        1.2  nakayama 		return;
    641        1.2  nakayama 	}
    642        1.1  nakayama 
    643        1.1  nakayama 	str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_STATUS);
    644        1.1  nakayama 	if (str & LOM1_STATUS_BUSY) {
    645        1.2  nakayama 		if (sc->sc_retry++ < 30) {
    646        1.2  nakayama 			callout_schedule(&sc->sc_state_to, mstohz(1));
    647        1.1  nakayama 			return;
    648        1.2  nakayama 		}
    649        1.2  nakayama 
    650        1.2  nakayama 		/*
    651        1.2  nakayama 		 * Looks like the microcontroller got wedged.  Unwedge
    652        1.2  nakayama 		 * it by writing this magic value.  Give it some time
    653        1.2  nakayama 		 * to recover.
    654        1.2  nakayama 		 */
    655        1.2  nakayama 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM1_DATA, 0xac);
    656        1.2  nakayama 		callout_schedule(&sc->sc_state_to, mstohz(1000));
    657        1.2  nakayama 		sc->sc_state = LOM_STATE_CMD;
    658        1.1  nakayama 		return;
    659        1.1  nakayama 	}
    660        1.1  nakayama 
    661        1.1  nakayama 	sc->sc_retry = 0;
    662        1.1  nakayama 
    663        1.1  nakayama 	if (sc->sc_state == LOM_STATE_CMD) {
    664        1.1  nakayama 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM1_CMD, lc->lc_cmd);
    665        1.1  nakayama 		sc->sc_state = LOM_STATE_DATA;
    666        1.1  nakayama 		callout_schedule(&sc->sc_state_to, mstohz(250));
    667        1.1  nakayama 		return;
    668        1.1  nakayama 	}
    669        1.1  nakayama 
    670        1.1  nakayama 	KASSERT(sc->sc_state == LOM_STATE_DATA);
    671        1.1  nakayama 	if ((lc->lc_cmd & LOM_IDX_WRITE) == 0)
    672        1.1  nakayama 		lc->lc_data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM1_DATA);
    673        1.1  nakayama 	else
    674        1.1  nakayama 		bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM1_DATA, lc->lc_data);
    675        1.1  nakayama 
    676        1.1  nakayama 	TAILQ_REMOVE(&sc->sc_queue, lc, lc_next);
    677        1.1  nakayama 
    678        1.1  nakayama 	wakeup(lc);
    679        1.1  nakayama 
    680        1.1  nakayama 	if (!TAILQ_EMPTY(&sc->sc_queue)) {
    681        1.1  nakayama 		sc->sc_state = LOM_STATE_CMD;
    682        1.1  nakayama 		callout_schedule(&sc->sc_state_to, mstohz(1));
    683        1.1  nakayama 		return;
    684        1.1  nakayama 	}
    685        1.1  nakayama 
    686        1.1  nakayama 	sc->sc_state = LOM_STATE_IDLE;
    687        1.1  nakayama }
    688        1.1  nakayama 
    689        1.1  nakayama static int
    690        1.1  nakayama lom2_read(struct lom_softc *sc, uint8_t reg, uint8_t *val)
    691        1.1  nakayama {
    692        1.2  nakayama 	struct lom_cmd lc;
    693        1.2  nakayama 	int error;
    694        1.2  nakayama 
    695        1.2  nakayama 	if (cold)
    696        1.2  nakayama 		return lom2_read_polled(sc, reg, val);
    697        1.2  nakayama 
    698        1.2  nakayama 	lc.lc_cmd = reg;
    699        1.2  nakayama 	lc.lc_data = 0xff;
    700        1.2  nakayama 	lom2_queue_cmd(sc, &lc);
    701        1.2  nakayama 
    702        1.2  nakayama 	error = tsleep(&lc, PZERO, "lom2rd", hz);
    703        1.2  nakayama 	if (error)
    704        1.4  nakayama 		lom_dequeue_cmd(sc, &lc);
    705        1.2  nakayama 
    706        1.2  nakayama 	*val = lc.lc_data;
    707        1.2  nakayama 
    708        1.2  nakayama 	return (error);
    709        1.2  nakayama }
    710        1.2  nakayama 
    711        1.2  nakayama static int
    712        1.2  nakayama lom2_read_polled(struct lom_softc *sc, uint8_t reg, uint8_t *val)
    713        1.2  nakayama {
    714        1.1  nakayama 	uint8_t str;
    715        1.1  nakayama 	int i;
    716        1.1  nakayama 
    717        1.1  nakayama 	/* Wait for input buffer to become available. */
    718        1.1  nakayama 	for (i = 1000; i > 0; i--) {
    719        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    720        1.1  nakayama 		delay(10);
    721        1.1  nakayama 		if ((str & LOM2_STATUS_IBF) == 0)
    722        1.1  nakayama 			break;
    723        1.1  nakayama 	}
    724        1.1  nakayama 	if (i == 0)
    725        1.1  nakayama 		return (ETIMEDOUT);
    726        1.1  nakayama 
    727        1.1  nakayama 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM2_CMD, reg);
    728        1.1  nakayama 
    729        1.1  nakayama 	/* Wait until the microcontroller fills output buffer. */
    730        1.1  nakayama 	for (i = 1000; i > 0; i--) {
    731        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    732        1.1  nakayama 		delay(10);
    733        1.1  nakayama 		if (str & LOM2_STATUS_OBF)
    734        1.1  nakayama 			break;
    735        1.1  nakayama 	}
    736        1.1  nakayama 	if (i == 0)
    737        1.1  nakayama 		return (ETIMEDOUT);
    738        1.1  nakayama 
    739        1.1  nakayama 	*val = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_DATA);
    740        1.1  nakayama 	return (0);
    741        1.1  nakayama }
    742        1.1  nakayama 
    743        1.1  nakayama static int
    744        1.1  nakayama lom2_write(struct lom_softc *sc, uint8_t reg, uint8_t val)
    745        1.1  nakayama {
    746        1.2  nakayama 	struct lom_cmd lc;
    747        1.2  nakayama 	int error;
    748        1.2  nakayama 
    749        1.2  nakayama 	if (cold)
    750        1.2  nakayama 		return lom2_write_polled(sc, reg, val);
    751        1.2  nakayama 
    752        1.2  nakayama 	lc.lc_cmd = reg | LOM_IDX_WRITE;
    753        1.2  nakayama 	lc.lc_data = val;
    754        1.2  nakayama 	lom2_queue_cmd(sc, &lc);
    755        1.2  nakayama 
    756        1.2  nakayama 	error = tsleep(&lc, PZERO, "lom2wr", hz);
    757        1.2  nakayama 	if (error)
    758        1.2  nakayama 		lom_dequeue_cmd(sc, &lc);
    759        1.2  nakayama 
    760        1.2  nakayama 	return (error);
    761        1.2  nakayama }
    762        1.2  nakayama 
    763        1.2  nakayama static int
    764        1.2  nakayama lom2_write_polled(struct lom_softc *sc, uint8_t reg, uint8_t val)
    765        1.2  nakayama {
    766        1.1  nakayama 	uint8_t str;
    767        1.1  nakayama 	int i;
    768        1.1  nakayama 
    769        1.1  nakayama 	/* Wait for input buffer to become available. */
    770        1.1  nakayama 	for (i = 1000; i > 0; i--) {
    771        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    772        1.1  nakayama 		delay(10);
    773        1.1  nakayama 		if ((str & LOM2_STATUS_IBF) == 0)
    774        1.1  nakayama 			break;
    775        1.1  nakayama 	}
    776        1.1  nakayama 	if (i == 0)
    777        1.1  nakayama 		return (ETIMEDOUT);
    778        1.1  nakayama 
    779        1.1  nakayama 	if (sc->sc_space == LOM_IDX_CMD_GENERIC && reg != LOM_IDX_CMD)
    780        1.2  nakayama 		reg |= LOM_IDX_WRITE;
    781        1.1  nakayama 
    782        1.1  nakayama 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM2_CMD, reg);
    783        1.1  nakayama 
    784        1.1  nakayama 	/* Wait until the microcontroller fills output buffer. */
    785        1.1  nakayama 	for (i = 1000; i > 0; i--) {
    786        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    787        1.1  nakayama 		delay(10);
    788        1.1  nakayama 		if (str & LOM2_STATUS_OBF)
    789        1.1  nakayama 			break;
    790        1.1  nakayama 	}
    791        1.1  nakayama 	if (i == 0)
    792        1.1  nakayama 		return (ETIMEDOUT);
    793        1.1  nakayama 
    794        1.1  nakayama 	(void)bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_DATA);
    795        1.1  nakayama 
    796        1.1  nakayama 	/* Wait for input buffer to become available. */
    797        1.1  nakayama 	for (i = 1000; i > 0; i--) {
    798        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    799        1.1  nakayama 		delay(10);
    800        1.1  nakayama 		if ((str & LOM2_STATUS_IBF) == 0)
    801        1.1  nakayama 			break;
    802        1.1  nakayama 	}
    803        1.1  nakayama 	if (i == 0)
    804        1.1  nakayama 		return (ETIMEDOUT);
    805        1.1  nakayama 
    806        1.1  nakayama 	bus_space_write_1(sc->sc_iot, sc->sc_ioh, LOM2_DATA, val);
    807        1.1  nakayama 
    808        1.1  nakayama 	/* Wait until the microcontroller fills output buffer. */
    809        1.1  nakayama 	for (i = 1000; i > 0; i--) {
    810        1.1  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    811        1.1  nakayama 		delay(10);
    812        1.1  nakayama 		if (str & LOM2_STATUS_OBF)
    813        1.1  nakayama 			break;
    814        1.1  nakayama 	}
    815        1.1  nakayama 	if (i == 0)
    816        1.1  nakayama 		return (ETIMEDOUT);
    817        1.1  nakayama 
    818        1.1  nakayama 	(void)bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_DATA);
    819        1.1  nakayama 
    820        1.1  nakayama 	/* If we switched spaces, remember the one we're in now. */
    821        1.1  nakayama 	if (reg == LOM_IDX_CMD)
    822        1.1  nakayama 		sc->sc_space = val;
    823        1.1  nakayama 
    824        1.1  nakayama 	return (0);
    825        1.1  nakayama }
    826        1.1  nakayama 
    827        1.1  nakayama static void
    828        1.1  nakayama lom2_queue_cmd(struct lom_softc *sc, struct lom_cmd *lc)
    829        1.1  nakayama {
    830       1.14  nakayama 	struct lom_cmd *lcp;
    831        1.2  nakayama 	uint8_t str;
    832        1.2  nakayama 
    833        1.2  nakayama 	mutex_enter(&sc->sc_queue_mtx);
    834       1.14  nakayama 	TAILQ_FOREACH(lcp, &sc->sc_queue, lc_next) {
    835       1.14  nakayama 		if (lcp == lc) {
    836       1.14  nakayama 			mutex_exit(&sc->sc_queue_mtx);
    837       1.14  nakayama 			return;
    838       1.14  nakayama 		}
    839       1.14  nakayama 	}
    840        1.2  nakayama 	TAILQ_INSERT_TAIL(&sc->sc_queue, lc, lc_next);
    841        1.2  nakayama 	if (sc->sc_state == LOM_STATE_IDLE) {
    842        1.2  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    843        1.2  nakayama 		if ((str & LOM2_STATUS_IBF) == 0) {
    844       1.14  nakayama 			lc = TAILQ_FIRST(&sc->sc_queue);
    845        1.2  nakayama 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
    846        1.2  nakayama 			    LOM2_CMD, lc->lc_cmd);
    847        1.2  nakayama 			sc->sc_state = LOM_STATE_DATA;
    848        1.2  nakayama 		}
    849        1.2  nakayama 	}
    850        1.2  nakayama 	mutex_exit(&sc->sc_queue_mtx);
    851        1.2  nakayama }
    852        1.2  nakayama 
    853        1.2  nakayama static int
    854        1.2  nakayama lom2_intr(void *arg)
    855        1.2  nakayama {
    856        1.2  nakayama 	struct lom_softc *sc = arg;
    857        1.2  nakayama 	struct lom_cmd *lc;
    858        1.2  nakayama 	uint8_t str, obr;
    859        1.2  nakayama 
    860        1.2  nakayama 	mutex_enter(&sc->sc_queue_mtx);
    861        1.2  nakayama 
    862        1.2  nakayama 	str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    863        1.2  nakayama 	obr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_DATA);
    864        1.2  nakayama 
    865        1.2  nakayama 	lc = TAILQ_FIRST(&sc->sc_queue);
    866        1.2  nakayama 	if (lc == NULL) {
    867        1.2  nakayama 		mutex_exit(&sc->sc_queue_mtx);
    868        1.2  nakayama 		return (0);
    869        1.2  nakayama 	}
    870        1.2  nakayama 
    871        1.2  nakayama 	if (lc->lc_cmd & LOM_IDX_WRITE) {
    872       1.14  nakayama 		if ((str & LOM2_STATUS_IBF) == 0) {
    873       1.14  nakayama 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
    874       1.14  nakayama 			    LOM2_DATA, lc->lc_data);
    875       1.14  nakayama 			lc->lc_cmd &= ~LOM_IDX_WRITE;
    876       1.14  nakayama 		}
    877        1.2  nakayama 		mutex_exit(&sc->sc_queue_mtx);
    878        1.2  nakayama 		return (1);
    879        1.2  nakayama 	}
    880        1.2  nakayama 
    881       1.11  nakayama 	KASSERT(sc->sc_state == LOM_STATE_DATA);
    882        1.2  nakayama 	lc->lc_data = obr;
    883        1.2  nakayama 
    884        1.2  nakayama 	TAILQ_REMOVE(&sc->sc_queue, lc, lc_next);
    885        1.2  nakayama 
    886        1.2  nakayama 	wakeup(lc);
    887        1.2  nakayama 
    888        1.2  nakayama 	sc->sc_state = LOM_STATE_IDLE;
    889        1.2  nakayama 
    890        1.2  nakayama 	if (!TAILQ_EMPTY(&sc->sc_queue)) {
    891        1.2  nakayama 		str = bus_space_read_1(sc->sc_iot, sc->sc_ioh, LOM2_STATUS);
    892        1.2  nakayama 		if ((str & LOM2_STATUS_IBF) == 0) {
    893       1.14  nakayama 			lc = TAILQ_FIRST(&sc->sc_queue);
    894        1.2  nakayama 			bus_space_write_1(sc->sc_iot, sc->sc_ioh,
    895        1.2  nakayama 			    LOM2_CMD, lc->lc_cmd);
    896        1.2  nakayama 			sc->sc_state = LOM_STATE_DATA;
    897        1.2  nakayama 		}
    898        1.2  nakayama 	}
    899        1.2  nakayama 
    900        1.2  nakayama 	mutex_exit(&sc->sc_queue_mtx);
    901        1.2  nakayama 
    902        1.2  nakayama 	return (1);
    903        1.1  nakayama }
    904        1.1  nakayama 
    905        1.1  nakayama static int
    906        1.1  nakayama lom_init_desc(struct lom_softc *sc)
    907        1.1  nakayama {
    908        1.1  nakayama 	uint8_t val;
    909        1.1  nakayama 	int i, j, k;
    910        1.1  nakayama 	int error;
    911        1.1  nakayama 
    912        1.1  nakayama 	/* LOMlite doesn't provide sensor descriptions. */
    913        1.1  nakayama 	if (sc->sc_type < LOM_LOMLITE2)
    914        1.1  nakayama 		return (0);
    915        1.1  nakayama 
    916        1.1  nakayama 	/*
    917        1.1  nakayama 	 * Read temperature sensor names.
    918        1.1  nakayama 	 */
    919        1.1  nakayama 	error = lom_write(sc, LOM_IDX_CMD, LOM_IDX_CMD_TEMP);
    920        1.1  nakayama 	if (error)
    921        1.1  nakayama 		return (error);
    922        1.1  nakayama 
    923        1.1  nakayama 	i = 0;
    924        1.1  nakayama 	j = 0;
    925        1.1  nakayama 	k = LOM_IDX4_TEMP_NAME_START;
    926        1.1  nakayama 	while (k <= LOM_IDX4_TEMP_NAME_END) {
    927        1.1  nakayama 		error = lom_read(sc, k++, &val);
    928        1.1  nakayama 		if (error)
    929        1.1  nakayama 			goto fail;
    930        1.1  nakayama 
    931        1.1  nakayama 		if (val == 0xff)
    932        1.1  nakayama 			break;
    933        1.1  nakayama 
    934        1.1  nakayama 		if (j < sizeof (sc->sc_temp[i].desc) - 1)
    935        1.1  nakayama 			sc->sc_temp[i].desc[j++] = val;
    936        1.1  nakayama 
    937        1.1  nakayama 		if (val == '\0') {
    938        1.1  nakayama 			i++;
    939        1.1  nakayama 			j = 0;
    940        1.1  nakayama 			if (i < sc->sc_num_temp)
    941        1.1  nakayama 				continue;
    942        1.1  nakayama 
    943        1.1  nakayama 			break;
    944        1.1  nakayama 		}
    945        1.1  nakayama 	}
    946        1.1  nakayama 
    947        1.1  nakayama 	/*
    948        1.1  nakayama 	 * Read fan names.
    949        1.1  nakayama 	 */
    950        1.1  nakayama 	error = lom_write(sc, LOM_IDX_CMD, LOM_IDX_CMD_FAN);
    951        1.1  nakayama 	if (error)
    952        1.1  nakayama 		return (error);
    953        1.1  nakayama 
    954        1.1  nakayama 	i = 0;
    955        1.1  nakayama 	j = 0;
    956        1.1  nakayama 	k = LOM_IDX5_FAN_NAME_START;
    957        1.1  nakayama 	while (k <= LOM_IDX5_FAN_NAME_END) {
    958        1.1  nakayama 		error = lom_read(sc, k++, &val);
    959        1.1  nakayama 		if (error)
    960        1.1  nakayama 			goto fail;
    961        1.1  nakayama 
    962        1.1  nakayama 		if (val == 0xff)
    963        1.1  nakayama 			break;
    964        1.1  nakayama 
    965        1.1  nakayama 		if (j < sizeof (sc->sc_fan[i].desc) - 1)
    966        1.1  nakayama 			sc->sc_fan[i].desc[j++] = val;
    967        1.1  nakayama 
    968        1.1  nakayama 		if (val == '\0') {
    969        1.1  nakayama 			i++;
    970        1.1  nakayama 			j = 0;
    971        1.1  nakayama 			if (i < sc->sc_num_fan)
    972        1.1  nakayama 				continue;
    973        1.1  nakayama 
    974        1.1  nakayama 			break;
    975        1.1  nakayama 		}
    976        1.1  nakayama 	}
    977        1.1  nakayama 
    978        1.1  nakayama fail:
    979        1.1  nakayama 	lom_write(sc, LOM_IDX_CMD, LOM_IDX_CMD_GENERIC);
    980        1.1  nakayama 	return (error);
    981        1.1  nakayama }
    982        1.1  nakayama 
    983        1.1  nakayama static void
    984        1.1  nakayama lom_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    985        1.1  nakayama {
    986        1.1  nakayama 	struct lom_softc *sc = sme->sme_cookie;
    987        1.7  nakayama 	uint32_t i;
    988        1.7  nakayama 
    989        1.7  nakayama 	/* Sensor number */
    990        1.7  nakayama 	i = edata->sensor;
    991        1.7  nakayama 
    992        1.7  nakayama 	/* Sensor type */
    993        1.7  nakayama 	switch (edata->units) {
    994        1.7  nakayama 	case ENVSYS_INDICATOR:
    995        1.7  nakayama 		if (i < sc->sc_num_alarm)
    996        1.7  nakayama 			lom_refresh_alarm(sc, edata, i);
    997        1.7  nakayama 		else
    998        1.7  nakayama 			lom_refresh_psu(sc, edata,
    999        1.7  nakayama 			    i - sc->sc_num_alarm - sc->sc_num_fan);
   1000        1.7  nakayama 		break;
   1001        1.7  nakayama 	case ENVSYS_SFANRPM:
   1002        1.7  nakayama 		lom_refresh_fan(sc, edata, i - sc->sc_num_alarm);
   1003        1.7  nakayama 		break;
   1004        1.7  nakayama 	case ENVSYS_STEMP:
   1005        1.7  nakayama 		lom_refresh_temp(sc, edata,
   1006        1.7  nakayama 		    i - sc->sc_num_alarm - sc->sc_num_fan - sc->sc_num_psu);
   1007        1.7  nakayama 		break;
   1008        1.7  nakayama 	default:
   1009        1.7  nakayama 		edata->state = ENVSYS_SINVALID;
   1010        1.7  nakayama 		break;
   1011        1.7  nakayama 	}
   1012        1.7  nakayama 
   1013        1.7  nakayama 	/*
   1014        1.7  nakayama 	 * If our hostname is set and differs from what's stored in
   1015        1.7  nakayama 	 * the LOM, write the new hostname back to the LOM.  Note that
   1016        1.7  nakayama 	 * we include the terminating NUL when writing the hostname
   1017        1.7  nakayama 	 * back to the LOM, otherwise the LOM will print any trailing
   1018        1.7  nakayama 	 * garbage.
   1019        1.7  nakayama 	 */
   1020        1.7  nakayama 	if (i == 0 && hostnamelen > 0 &&
   1021        1.7  nakayama 	    strncmp(sc->sc_hostname, hostname, sizeof(hostname)) != 0) {
   1022        1.7  nakayama 		if (sc->sc_type < LOM_LOMLITE2)
   1023        1.7  nakayama 			lom1_write_hostname(sc);
   1024        1.7  nakayama 		else
   1025        1.7  nakayama 			lom2_write_hostname(sc);
   1026        1.7  nakayama 		strlcpy(sc->sc_hostname, hostname, sizeof(hostname));
   1027        1.7  nakayama 	}
   1028        1.7  nakayama }
   1029        1.7  nakayama 
   1030        1.7  nakayama static void
   1031        1.7  nakayama lom_refresh_alarm(struct lom_softc *sc, envsys_data_t *edata, uint32_t i)
   1032        1.7  nakayama {
   1033        1.1  nakayama 	uint8_t val;
   1034        1.7  nakayama 
   1035        1.7  nakayama 	/* Fault LED or Alarms */
   1036        1.7  nakayama 	KASSERT(i < sc->sc_num_alarm);
   1037        1.1  nakayama 
   1038        1.8  nakayama 	/* Read new value at most once every second. */
   1039        1.8  nakayama 	if (ratecheck(&sc->sc_alarm_lastread, &refresh_interval)) {
   1040        1.8  nakayama 		if (lom_read(sc, LOM_IDX_ALARM, &val)) {
   1041        1.8  nakayama 			edata->state = ENVSYS_SINVALID;
   1042        1.8  nakayama 			return;
   1043        1.8  nakayama 		}
   1044        1.8  nakayama 		sc->sc_alarm_lastval = val;
   1045        1.8  nakayama 	} else {
   1046        1.8  nakayama 		val = sc->sc_alarm_lastval;
   1047        1.8  nakayama 	}
   1048        1.8  nakayama 
   1049        1.8  nakayama 	if (i == 0) {
   1050        1.8  nakayama 		/* Fault LED */
   1051        1.8  nakayama 		if ((val & LOM_ALARM_FAULT) == LOM_ALARM_FAULT)
   1052        1.8  nakayama 			edata->value_cur = 0;
   1053        1.8  nakayama 		else
   1054        1.8  nakayama 			edata->value_cur = 1;
   1055        1.3  nakayama 	} else {
   1056        1.8  nakayama 		/* Alarms */
   1057        1.8  nakayama 		if ((val & (LOM_ALARM_1 << (i - 1))) == 0)
   1058        1.8  nakayama 			edata->value_cur = 0;
   1059        1.8  nakayama 		else
   1060        1.8  nakayama 			edata->value_cur = 1;
   1061        1.3  nakayama 	}
   1062        1.8  nakayama 	edata->state = ENVSYS_SVALID;
   1063        1.7  nakayama }
   1064        1.7  nakayama 
   1065        1.7  nakayama static void
   1066        1.7  nakayama lom_refresh_fan(struct lom_softc *sc, envsys_data_t *edata, uint32_t i)
   1067        1.7  nakayama {
   1068        1.7  nakayama 	uint8_t val;
   1069        1.3  nakayama 
   1070        1.7  nakayama 	/* Fan speed */
   1071        1.7  nakayama 	KASSERT(i < sc->sc_num_fan);
   1072        1.1  nakayama 
   1073        1.8  nakayama 	/* Read new value at most once every second. */
   1074        1.8  nakayama 	if (!ratecheck(&sc->sc_fan_lastread[i], &refresh_interval))
   1075        1.8  nakayama 		return;
   1076        1.8  nakayama 
   1077        1.7  nakayama 	if (lom_read(sc, LOM_IDX_FAN1 + i, &val)) {
   1078        1.7  nakayama 		edata->state = ENVSYS_SINVALID;
   1079        1.7  nakayama 	} else {
   1080        1.7  nakayama 		edata->value_cur = (60 * sc->sc_fan_cal[i] * val) / 100;
   1081        1.1  nakayama 		if (val < sc->sc_fan_low[i])
   1082        1.7  nakayama 			edata->state = ENVSYS_SCRITICAL;
   1083        1.1  nakayama 		else
   1084        1.7  nakayama 			edata->state = ENVSYS_SVALID;
   1085        1.1  nakayama 	}
   1086        1.7  nakayama }
   1087        1.7  nakayama 
   1088        1.7  nakayama static void
   1089        1.7  nakayama lom_refresh_psu(struct lom_softc *sc, envsys_data_t *edata, uint32_t i)
   1090        1.7  nakayama {
   1091        1.7  nakayama 	uint8_t val;
   1092        1.1  nakayama 
   1093        1.7  nakayama 	/* PSU status */
   1094        1.7  nakayama 	KASSERT(i < sc->sc_num_psu);
   1095        1.1  nakayama 
   1096        1.8  nakayama 	/* Read new value at most once every second. */
   1097        1.8  nakayama 	if (!ratecheck(&sc->sc_psu_lastread[i], &refresh_interval))
   1098        1.8  nakayama 		return;
   1099        1.8  nakayama 
   1100        1.7  nakayama 	if (lom_read(sc, LOM_IDX_PSU1 + i, &val) ||
   1101        1.7  nakayama 	    !ISSET(val, LOM_PSU_PRESENT)) {
   1102        1.7  nakayama 		edata->state = ENVSYS_SINVALID;
   1103        1.7  nakayama 	} else {
   1104        1.1  nakayama 		if (val & LOM_PSU_STANDBY) {
   1105        1.7  nakayama 			edata->value_cur = 0;
   1106        1.7  nakayama 			edata->state = ENVSYS_SVALID;
   1107        1.1  nakayama 		} else {
   1108        1.7  nakayama 			edata->value_cur = 1;
   1109        1.1  nakayama 			if (ISSET(val, LOM_PSU_INPUTA) &&
   1110        1.1  nakayama 			    ISSET(val, LOM_PSU_INPUTB) &&
   1111        1.1  nakayama 			    ISSET(val, LOM_PSU_OUTPUT))
   1112        1.7  nakayama 				edata->state = ENVSYS_SVALID;
   1113        1.1  nakayama 			else
   1114        1.7  nakayama 				edata->state = ENVSYS_SCRITICAL;
   1115        1.1  nakayama 		}
   1116        1.1  nakayama 	}
   1117        1.7  nakayama }
   1118        1.1  nakayama 
   1119        1.7  nakayama static void
   1120        1.7  nakayama lom_refresh_temp(struct lom_softc *sc, envsys_data_t *edata, uint32_t i)
   1121        1.7  nakayama {
   1122        1.7  nakayama 	uint8_t val;
   1123        1.1  nakayama 
   1124        1.7  nakayama 	/* Temperature */
   1125        1.7  nakayama 	KASSERT(i < sc->sc_num_temp);
   1126        1.1  nakayama 
   1127        1.8  nakayama 	/* Read new value at most once every second. */
   1128        1.8  nakayama 	if (!ratecheck(&sc->sc_temp_lastread[i], &refresh_interval))
   1129        1.8  nakayama 		return;
   1130        1.8  nakayama 
   1131        1.7  nakayama 	if (lom_read(sc, LOM_IDX_TEMP1 + i, &val)) {
   1132        1.7  nakayama 		edata->state = ENVSYS_SINVALID;
   1133        1.7  nakayama 	} else {
   1134        1.7  nakayama 		edata->value_cur = val * 1000000 + 273150000;
   1135        1.7  nakayama 		edata->state = ENVSYS_SVALID;
   1136        1.1  nakayama 	}
   1137        1.1  nakayama }
   1138        1.1  nakayama 
   1139        1.1  nakayama static void
   1140        1.1  nakayama lom1_write_hostname(struct lom_softc *sc)
   1141        1.1  nakayama {
   1142        1.6  nakayama 	char name[(LOM1_IDX_HOSTNAME12 - LOM1_IDX_HOSTNAME1 + 1) + 1];
   1143        1.1  nakayama 	char *p;
   1144        1.1  nakayama 	int i;
   1145        1.1  nakayama 
   1146        1.1  nakayama 	/*
   1147        1.1  nakayama 	 * LOMlite generally doesn't have enough space to store the
   1148        1.1  nakayama 	 * fully qualified hostname.  If the hostname is too long,
   1149        1.1  nakayama 	 * strip off the domain name.
   1150        1.1  nakayama 	 */
   1151        1.1  nakayama 	strlcpy(name, hostname, sizeof(name));
   1152        1.6  nakayama 	if (hostnamelen >= sizeof(name)) {
   1153        1.1  nakayama 		p = strchr(name, '.');
   1154        1.1  nakayama 		if (p)
   1155        1.1  nakayama 			*p = '\0';
   1156        1.1  nakayama 	}
   1157        1.1  nakayama 
   1158        1.1  nakayama 	for (i = 0; i < strlen(name) + 1; i++)
   1159        1.1  nakayama 		if (lom_write(sc, LOM1_IDX_HOSTNAME1 + i, name[i]))
   1160        1.1  nakayama 			break;
   1161        1.1  nakayama }
   1162        1.1  nakayama 
   1163        1.1  nakayama static void
   1164        1.1  nakayama lom2_write_hostname(struct lom_softc *sc)
   1165        1.1  nakayama {
   1166        1.1  nakayama 	int i;
   1167        1.1  nakayama 
   1168        1.1  nakayama 	lom_write(sc, LOM2_IDX_HOSTNAMELEN, hostnamelen + 1);
   1169        1.1  nakayama 	for (i = 0; i < hostnamelen + 1; i++)
   1170        1.1  nakayama 		lom_write(sc, LOM2_IDX_HOSTNAME, hostname[i]);
   1171        1.1  nakayama }
   1172        1.1  nakayama 
   1173        1.1  nakayama static int
   1174        1.1  nakayama lom_wdog_tickle(struct sysmon_wdog *smw)
   1175        1.1  nakayama {
   1176        1.1  nakayama 	struct lom_softc *sc = smw->smw_cookie;
   1177        1.1  nakayama 
   1178        1.1  nakayama 	/* Pat the dog. */
   1179        1.1  nakayama 	sc->sc_wdog_pat.lc_cmd = LOM_IDX_WDOG_CTL | LOM_IDX_WRITE;
   1180        1.1  nakayama 	sc->sc_wdog_pat.lc_data = sc->sc_wdog_ctl;
   1181        1.1  nakayama 	lom_queue_cmd(sc, &sc->sc_wdog_pat);
   1182        1.1  nakayama 
   1183        1.1  nakayama 	return 0;
   1184        1.1  nakayama }
   1185        1.1  nakayama 
   1186        1.1  nakayama static int
   1187        1.1  nakayama lom_wdog_setmode(struct sysmon_wdog *smw)
   1188        1.1  nakayama {
   1189        1.1  nakayama 	struct lom_softc *sc = smw->smw_cookie;
   1190        1.1  nakayama 
   1191        1.1  nakayama 	if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
   1192        1.1  nakayama 		/* disable watchdog */
   1193        1.1  nakayama 		sc->sc_wdog_ctl &= ~(LOM_WDOG_ENABLE|LOM_WDOG_RESET);
   1194        1.1  nakayama 		lom_write(sc, LOM_IDX_WDOG_CTL, sc->sc_wdog_ctl);
   1195        1.1  nakayama 	} else {
   1196        1.1  nakayama 		if (smw->smw_period == WDOG_PERIOD_DEFAULT)
   1197        1.1  nakayama 			smw->smw_period = sc->sc_wdog_period;
   1198        1.1  nakayama 		else if (smw->smw_period == 0 ||
   1199        1.1  nakayama 		    smw->smw_period > LOM_WDOG_TIME_MAX)
   1200        1.1  nakayama 			return EINVAL;
   1201        1.1  nakayama 		lom_write(sc, LOM_IDX_WDOG_TIME, smw->smw_period);
   1202        1.1  nakayama 
   1203        1.1  nakayama 		/* enable watchdog */
   1204        1.2  nakayama 		lom_dequeue_cmd(sc, &sc->sc_wdog_pat);
   1205        1.1  nakayama 		sc->sc_wdog_ctl |= LOM_WDOG_ENABLE|LOM_WDOG_RESET;
   1206        1.1  nakayama 		sc->sc_wdog_pat.lc_cmd = LOM_IDX_WDOG_CTL | LOM_IDX_WRITE;
   1207        1.1  nakayama 		sc->sc_wdog_pat.lc_data = sc->sc_wdog_ctl;
   1208        1.1  nakayama 		lom_queue_cmd(sc, &sc->sc_wdog_pat);
   1209        1.1  nakayama 	}
   1210        1.1  nakayama 
   1211        1.1  nakayama 	return 0;
   1212        1.1  nakayama }
   1213        1.2  nakayama 
   1214        1.2  nakayama static bool
   1215        1.2  nakayama lom_shutdown(device_t dev, int how)
   1216        1.2  nakayama {
   1217        1.2  nakayama 	struct lom_softc *sc = device_private(dev);
   1218        1.2  nakayama 
   1219        1.2  nakayama 	sc->sc_wdog_ctl &= ~LOM_WDOG_ENABLE;
   1220        1.2  nakayama 	lom_write(sc, LOM_IDX_WDOG_CTL, sc->sc_wdog_ctl);
   1221        1.2  nakayama 	return true;
   1222        1.2  nakayama }
   1223        1.5  nakayama 
   1224        1.5  nakayama static int
   1225        1.5  nakayama lom_sysctl_alarm(SYSCTLFN_ARGS)
   1226        1.5  nakayama {
   1227        1.5  nakayama 	struct sysctlnode node;
   1228        1.5  nakayama 	struct lom_softc *sc;
   1229        1.5  nakayama 	int i, tmp, error;
   1230        1.5  nakayama 	uint8_t val;
   1231        1.5  nakayama 
   1232        1.5  nakayama 	node = *rnode;
   1233        1.5  nakayama 	sc = node.sysctl_data;
   1234        1.5  nakayama 
   1235        1.5  nakayama 	for (i = 0; i < sc->sc_num_alarm; i++) {
   1236        1.5  nakayama 		if (node.sysctl_num == sc->sc_sysctl_num[i]) {
   1237        1.7  nakayama 			lom_refresh_alarm(sc, &sc->sc_alarm[i], i);
   1238        1.5  nakayama 			tmp = sc->sc_alarm[i].value_cur;
   1239        1.5  nakayama 			node.sysctl_data = &tmp;
   1240        1.5  nakayama 			error = sysctl_lookup(SYSCTLFN_CALL(&node));
   1241        1.5  nakayama 			if (error || newp == NULL)
   1242        1.5  nakayama 				return error;
   1243        1.5  nakayama 			if (tmp < 0 || tmp > 1)
   1244        1.5  nakayama 				return EINVAL;
   1245        1.5  nakayama 
   1246        1.5  nakayama 			if (lom_read(sc, LOM_IDX_ALARM, &val))
   1247        1.5  nakayama 				return EINVAL;
   1248        1.5  nakayama 			if (i == 0) {
   1249        1.5  nakayama 				/* Fault LED */
   1250        1.5  nakayama 				if (tmp != 0)
   1251        1.5  nakayama 					val &= ~LOM_ALARM_FAULT;
   1252        1.5  nakayama 				else
   1253        1.5  nakayama 					val |= LOM_ALARM_FAULT;
   1254        1.5  nakayama 			} else {
   1255        1.5  nakayama 				/* Alarms */
   1256        1.5  nakayama 				if (tmp != 0)
   1257        1.5  nakayama 					val |= LOM_ALARM_1 << (i - 1);
   1258        1.5  nakayama 				else
   1259        1.5  nakayama 					val &= ~(LOM_ALARM_1 << (i - 1));
   1260        1.5  nakayama 			}
   1261        1.5  nakayama 			if (lom_write(sc, LOM_IDX_ALARM, val))
   1262        1.5  nakayama 				return EINVAL;
   1263        1.5  nakayama 
   1264        1.5  nakayama 			sc->sc_alarm[i].value_cur = tmp;
   1265        1.5  nakayama 			return 0;
   1266        1.5  nakayama 		}
   1267        1.5  nakayama 	}
   1268        1.5  nakayama 
   1269        1.5  nakayama 	return ENOENT;
   1270        1.5  nakayama }
   1271