예제 #1
0
int
safte_read_config(struct safte_softc *sc)
{
	struct safte_readbuf_cmd	cmd;
	struct safte_config		config;
	struct safte_sensor		*s;
	int				flags, i, j;

	memset(&cmd, 0, sizeof(cmd));
	cmd.opcode = READ_BUFFER;
	cmd.flags |= SAFTE_RD_MODE;
	cmd.bufferid = SAFTE_RD_CONFIG;
	cmd.length = htobe16(sizeof(config));
	flags = SCSI_DATA_IN;
#ifndef SCSIDEBUG
	flags |= SCSI_SILENT;
#endif

	if (cold)
		flags |= SCSI_AUTOCONF;

	if (scsi_scsi_cmd(sc->sc_link, (struct scsi_generic *)&cmd,
	    sizeof(cmd), (u_char *)&config, sizeof(config), 2, 30000, NULL,
	    flags) != 0)
		return (1);

	DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d"
	    " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config.nfans,
	    config.npwrsup, config.nslots, config.doorlock, config.ntemps,
	    config.alarm, SAFTE_CFG_CELSIUS(config.therm),
	    SAFTE_CFG_NTHERM(config.therm)));

	sc->sc_encbuflen = config.nfans * sizeof(u_int8_t) + /* fan status */
	    config.npwrsup * sizeof(u_int8_t) + /* power supply status */
	    config.nslots * sizeof(u_int8_t) + /* device scsi id (lun) */
	    sizeof(u_int8_t) + /* door lock status */
	    sizeof(u_int8_t) + /* speaker status */
	    config.ntemps * sizeof(u_int8_t) + /* temp sensors */
	    sizeof(u_int16_t); /* temp out of range sensors */

	sc->sc_encbuf = malloc(sc->sc_encbuflen, M_DEVBUF, M_NOWAIT);
	if (sc->sc_encbuf == NULL)
		return (1);

	sc->sc_nsensors = config.nfans + config.npwrsup + config.ntemps + 
		(config.doorlock ? 1 : 0) + (config.alarm ? 1 : 0);

	sc->sc_sensors = malloc(sc->sc_nsensors * sizeof(struct safte_sensor),
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_sensors == NULL) {
		free(sc->sc_encbuf, M_DEVBUF);
		sc->sc_encbuf = NULL;
		sc->sc_nsensors = 0;
		return (1);
	}

	strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
	    sizeof(sc->sc_sensordev.xname));

	s = sc->sc_sensors;

	for (i = 0; i < config.nfans; i++) {
		s->se_type = SAFTE_T_FAN;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + i);
		s->se_sensor.type = SENSOR_INDICATOR;
		snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
		    "Fan%d", i);

		s++;
	}
	j = config.nfans;

	for (i = 0; i < config.npwrsup; i++) {
		s->se_type = SAFTE_T_PWRSUP;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
		s->se_sensor.type = SENSOR_INDICATOR;
		snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
		    "PSU%d", i);

		s++;
	}
	j += config.npwrsup;

#if NBIO > 0
	sc->sc_nslots = config.nslots;
	sc->sc_slots = (u_int8_t *)(sc->sc_encbuf + j);
#endif
	j += config.nslots;

	if (config.doorlock) {
		s->se_type = SAFTE_T_DOORLOCK;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
		s->se_sensor.type = SENSOR_INDICATOR;
		strlcpy(s->se_sensor.desc, "doorlock",
		    sizeof(s->se_sensor.desc));

		s++;
	}
	j++;

	if (config.alarm) {
		s->se_type = SAFTE_T_ALARM;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
		s->se_sensor.type = SENSOR_INDICATOR;
		strlcpy(s->se_sensor.desc, "alarm", sizeof(s->se_sensor.desc));

		s++;
	}
	j++;

	/*
	 * stash the temp info so we can get out of range status. limit the
	 * number so the out of temp checks cant go into memory it doesnt own
	 */
	sc->sc_ntemps = (config.ntemps > 15) ? 15 : config.ntemps;
	sc->sc_temps = s;
	sc->sc_celsius = SAFTE_CFG_CELSIUS(config.therm);
	for (i = 0; i < config.ntemps; i++) {
		s->se_type = SAFTE_T_TEMP;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
		s->se_sensor.type = SENSOR_TEMP;

		s++;
	}
	j += config.ntemps;

	sc->sc_temperrs = (u_int16_t *)(sc->sc_encbuf + j);

	return (0);
}
예제 #2
0
int
safte_read_config(struct safte_softc *sc)
{
	struct safte_config *config = NULL;
	struct safte_readbuf_cmd *cmd;
	struct safte_sensor *s;
	struct scsi_xfer *xs;
	int error = 0, flags = 0, i, j;

	config = dma_alloc(sizeof(*config), PR_NOWAIT);
	if (config == NULL)
		return (1);

	if (cold)
		flags |= SCSI_AUTOCONF;
	xs = scsi_xs_get(sc->sc_link, flags | SCSI_DATA_IN | SCSI_SILENT);
	if (xs == NULL) {
		error = 1;
		goto done;
	}
	xs->cmdlen = sizeof(*cmd);
	xs->data = (void *)config;
	xs->datalen = sizeof(*config);
	xs->retries = 2;
	xs->timeout = 30000;

	cmd = (struct safte_readbuf_cmd *)xs->cmd;
	cmd->opcode = READ_BUFFER;
	cmd->flags |= SAFTE_RD_MODE;
	cmd->bufferid = SAFTE_RD_CONFIG;
	cmd->length = htobe16(sizeof(*config));

	error = scsi_xs_sync(xs);
	scsi_xs_put(xs);

	if (error != 0) {
		error = 1;
		goto done;
	}

	DPRINTF(("%s: nfans: %d npwrsup: %d nslots: %d doorlock: %d ntemps: %d"
	    " alarm: %d celsius: %d ntherm: %d\n", DEVNAME(sc), config->nfans,
	    config->npwrsup, config->nslots, config->doorlock, config->ntemps,
	    config->alarm, SAFTE_CFG_CELSIUS(config->therm),
	    SAFTE_CFG_NTHERM(config->therm)));

	sc->sc_encbuflen = config->nfans * sizeof(u_int8_t) + /* fan status */
	    config->npwrsup * sizeof(u_int8_t) + /* power supply status */
	    config->nslots * sizeof(u_int8_t) + /* device scsi id (lun) */
	    sizeof(u_int8_t) + /* door lock status */
	    sizeof(u_int8_t) + /* speaker status */
	    config->ntemps * sizeof(u_int8_t) + /* temp sensors */
	    sizeof(u_int16_t); /* temp out of range sensors */

	sc->sc_encbuf = dma_alloc(sc->sc_encbuflen, PR_NOWAIT);
	if (sc->sc_encbuf == NULL) {
		error = 1;
		goto done;
	}

	sc->sc_nsensors = config->nfans + config->npwrsup + config->ntemps +
		(config->doorlock ? 1 : 0) + (config->alarm ? 1 : 0);

	sc->sc_sensors = mallocarray(sc->sc_nsensors, sizeof(struct safte_sensor),
	    M_DEVBUF, M_NOWAIT | M_ZERO);
	if (sc->sc_sensors == NULL) {
		dma_free(sc->sc_encbuf, sc->sc_encbuflen);
		sc->sc_encbuf = NULL;
		sc->sc_nsensors = 0;
		error = 1;
		goto done;
	}

	strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
	    sizeof(sc->sc_sensordev.xname));

	s = sc->sc_sensors;

	for (i = 0; i < config->nfans; i++) {
		s->se_type = SAFTE_T_FAN;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + i);
		s->se_sensor.type = SENSOR_INDICATOR;
		snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
		    "Fan%d", i);

		s++;
	}
	j = config->nfans;

	for (i = 0; i < config->npwrsup; i++) {
		s->se_type = SAFTE_T_PWRSUP;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
		s->se_sensor.type = SENSOR_INDICATOR;
		snprintf(s->se_sensor.desc, sizeof(s->se_sensor.desc),
		    "PSU%d", i);

		s++;
	}
	j += config->npwrsup;

#if NBIO > 0
	sc->sc_nslots = config->nslots;
	sc->sc_slots = (u_int8_t *)(sc->sc_encbuf + j);
#endif
	j += config->nslots;

	if (config->doorlock) {
		s->se_type = SAFTE_T_DOORLOCK;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
		s->se_sensor.type = SENSOR_INDICATOR;
		strlcpy(s->se_sensor.desc, "doorlock",
		    sizeof(s->se_sensor.desc));

		s++;
	}
	j++;

	if (config->alarm) {
		s->se_type = SAFTE_T_ALARM;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j);
		s->se_sensor.type = SENSOR_INDICATOR;
		strlcpy(s->se_sensor.desc, "alarm", sizeof(s->se_sensor.desc));

		s++;
	}
	j++;

	/*
	 * stash the temp info so we can get out of range status. limit the
	 * number so the out of temp checks cant go into memory it doesnt own
	 */
	sc->sc_ntemps = (config->ntemps > 15) ? 15 : config->ntemps;
	sc->sc_temps = s;
	sc->sc_celsius = SAFTE_CFG_CELSIUS(config->therm);
	for (i = 0; i < config->ntemps; i++) {
		s->se_type = SAFTE_T_TEMP;
		s->se_field = (u_int8_t *)(sc->sc_encbuf + j + i);
		s->se_sensor.type = SENSOR_TEMP;

		s++;
	}
	j += config->ntemps;

	sc->sc_temperrs = (u_int8_t *)(sc->sc_encbuf + j);
done:
	dma_free(config, sizeof(*config));
	return (error);
}