Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Aug 2011 14:09:32 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r225144 - in projects/zfsd/head/sys/cam: ata scsi
Message-ID:  <201108241409.p7OE9Wm6057870@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Wed Aug 24 14:09:32 2011
New Revision: 225144
URL: http://svn.freebsd.org/changeset/base/225144

Log:
  First part of SAF-TE driver refactoring to the new fsm-based model:
   - make configuration and status reading asynchronous.

Modified:
  projects/zfsd/head/sys/cam/ata/ata_all.c
  projects/zfsd/head/sys/cam/ata/ata_all.h
  projects/zfsd/head/sys/cam/scsi/scsi_all.c
  projects/zfsd/head/sys/cam/scsi/scsi_all.h
  projects/zfsd/head/sys/cam/scsi/scsi_enc.c
  projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
  projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c
  projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c

Modified: projects/zfsd/head/sys/cam/ata/ata_all.c
==============================================================================
--- projects/zfsd/head/sys/cam/ata/ata_all.c	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/ata/ata_all.c	Wed Aug 24 14:09:32 2011	(r225144)
@@ -762,3 +762,44 @@ semb_send_diagnostic(struct ccb_ataio *a
 	    length > 0 ? data_ptr[0] : 0, 0x82, length / 4);
 }
 
+void
+semb_read_buffer(struct ccb_ataio *ataio,
+    u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+    uint8_t tag_action, uint8_t page_code,
+    uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+	length = min(length, 1020);
+	length = (length + 3) & ~3;
+	cam_fill_ataio(ataio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_IN,
+		      tag_action,
+		      data_ptr,
+		      length,
+		      timeout);
+	ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+	    page_code, 0x00, length / 4);
+}
+
+void
+semb_write_buffer(struct ccb_ataio *ataio,
+    u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+    uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
+{
+
+	length = min(length, 1020);
+	length = (length + 3) & ~3;
+	cam_fill_ataio(ataio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
+		      tag_action,
+		      data_ptr,
+		      length,
+		      timeout);
+	ata_28bit_cmd(ataio, ATA_SEP_ATTN,
+	    length > 0 ? data_ptr[0] : 0, 0x80, length / 4);
+}
+

Modified: projects/zfsd/head/sys/cam/ata/ata_all.h
==============================================================================
--- projects/zfsd/head/sys/cam/ata/ata_all.h	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/ata/ata_all.h	Wed Aug 24 14:09:32 2011	(r225144)
@@ -152,4 +152,14 @@ void semb_send_diagnostic(struct ccb_ata
 	uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
 	uint32_t timeout);
 
+void semb_read_buffer(struct ccb_ataio *ataio,
+	u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
+	uint8_t tag_action, uint8_t page_code,
+	uint8_t *data_ptr, uint16_t allocation_length, uint32_t timeout);
+
+void semb_write_buffer(struct ccb_ataio *ataio,
+	u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
+	uint8_t tag_action, uint8_t *data_ptr, uint16_t param_list_length,
+	uint32_t timeout);
+
 #endif

Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_all.c	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_all.c	Wed Aug 24 14:09:32 2011	(r225144)
@@ -3564,7 +3564,7 @@ scsi_devid_is_naa_ieee_reg(uint8_t *bufp
 		return 0;
 	if (descr->length < sizeof(struct scsi_vpd_id_naa_ieee_reg))
 		return 0;
-	if ((naa->naa >> SVPD_ID_NAA_NAA_SHIFT) != SVPD_ID_NAA_IEEE_REG)
+	if (0 && (naa->naa >> SVPD_ID_NAA_NAA_SHIFT) != SVPD_ID_NAA_IEEE_REG)
 		return 0;
 	return 1;
 }
@@ -4276,6 +4276,66 @@ scsi_send_diagnostic(struct ccb_scsiio *
 		      timeout);
 }
 
+void
+scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+			void (*cbfcnp)(struct cam_periph *, union ccb*),
+			uint8_t tag_action, int mode,
+			uint8_t buffer_id, u_int32_t offset,
+			uint8_t *data_ptr, uint32_t allocation_length,
+			uint8_t sense_len, uint32_t timeout)
+{
+	struct scsi_read_buffer *scsi_cmd;
+
+	scsi_cmd = (struct scsi_read_buffer *)&csio->cdb_io.cdb_bytes;
+	memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+	scsi_cmd->opcode = READ_BUFFER;
+	scsi_cmd->byte2 = mode;
+	scsi_cmd->buffer_id = buffer_id;
+	scsi_ulto3b(offset, scsi_cmd->offset);
+	scsi_ulto3b(allocation_length, scsi_cmd->length);
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_IN,
+		      tag_action,
+		      data_ptr,
+		      allocation_length,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+}
+
+void
+scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+			void (*cbfcnp)(struct cam_periph *, union ccb *),
+			uint8_t tag_action, int mode,
+			uint8_t buffer_id, u_int32_t offset,
+			uint8_t *data_ptr, uint32_t param_list_length,
+			uint8_t sense_len, uint32_t timeout)
+{
+	struct scsi_write_buffer *scsi_cmd;
+
+	scsi_cmd = (struct scsi_write_buffer *)&csio->cdb_io.cdb_bytes;
+	memset(scsi_cmd, 0, sizeof(*scsi_cmd));
+	scsi_cmd->opcode = WRITE_BUFFER;
+	scsi_cmd->byte2 = mode;
+	scsi_cmd->buffer_id = buffer_id;
+	scsi_ulto3b(offset, scsi_cmd->offset);
+	scsi_ulto3b(param_list_length, scsi_cmd->length);
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/param_list_length ? CAM_DIR_OUT : CAM_DIR_NONE,
+		      tag_action,
+		      data_ptr,
+		      param_list_length,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+}
+
 void 
 scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
 		void (*cbfcnp)(struct cam_periph *, union ccb *),

Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_all.h	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_all.h	Wed Aug 24 14:09:32 2011	(r225144)
@@ -1487,6 +1487,20 @@ void scsi_send_diagnostic(struct ccb_scs
 			  uint16_t param_list_length, uint8_t sense_len,
 			  uint32_t timeout);
 
+void scsi_read_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+			void (*cbfcnp)(struct cam_periph *, union ccb*),
+			uint8_t tag_action, int mode,
+			uint8_t buffer_id, u_int32_t offset,
+			uint8_t *data_ptr, uint32_t allocation_length,
+			uint8_t sense_len, uint32_t timeout);
+
+void scsi_write_buffer(struct ccb_scsiio *csio, u_int32_t retries,
+			void (*cbfcnp)(struct cam_periph *, union ccb *),
+			uint8_t tag_action, int mode,
+			uint8_t buffer_id, u_int32_t offset,
+			uint8_t *data_ptr, uint32_t param_list_length,
+			uint8_t sense_len, uint32_t timeout);
+
 void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
 		     void (*cbfcnp)(struct cam_periph *, union ccb *),
 		     u_int8_t tag_action, int readop, u_int8_t byte2, 

Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc.c	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc.c	Wed Aug 24 14:09:32 2011	(r225144)
@@ -429,7 +429,7 @@ enc_ioctl(struct cdev *dev, u_long cmd, 
 			cam_periph_unlock(periph);
 			break;
 		}
-		tmp = cache->enc_status & ~ENCI_SVALID;
+		tmp = cache->enc_status;
 		cam_periph_unlock(periph);
 		error = copyout(&tmp, addr, sizeof(tmp));
 		cache->enc_status = tmp;

Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h	Wed Aug 24 14:09:32 2011	(r225144)
@@ -139,7 +139,6 @@ struct enc_softc {
 	enc_cache_t		 enc_daemon_cache;
 
 	struct sx		 enc_cache_lock;
-#define	ENCI_SVALID		0x80
 	uint8_t			 enc_flags;
 #define	ENC_FLAG_INVALID	0x01
 #define	ENC_FLAG_INITIALIZED	0x02

Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c	Wed Aug 24 13:35:56 2011	(r225143)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c	Wed Aug 24 14:09:32 2011	(r225144)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD: head/sys/cam/scsi/sc
 
 #include <cam/scsi/scsi_enc.h>
 #include <cam/scsi/scsi_enc_internal.h>
+#include <cam/scsi/scsi_message.h>
 
 #include <opt_enc.h>
 
@@ -52,8 +53,6 @@ __FBSDID("$FreeBSD: head/sys/cam/scsi/sc
  * SAF-TE Type Device Emulation
  */
 
-static int safte_getconfig(enc_softc_t *);
-static int safte_rdstat(enc_softc_t *, int);
 static int set_elm_status_sel(enc_softc_t *, encioc_elm_status_t *, int);
 static int wrbuf16(enc_softc_t *, uint8_t, uint8_t, uint8_t, uint8_t, int);
 static void wrslot_stat(enc_softc_t *, int);
@@ -81,8 +80,54 @@ static int perf_slotop(enc_softc_t *, ui
 #define	SAFTE_WT_ACTPWS	0x14	/* turn on/off power supply */
 #define	SAFTE_WT_GLOBAL	0x15	/* send global command */
 
-
 #define	SAFT_SCRATCH	64
+#define	SCSZ		0x8000
+
+typedef enum {
+	SAFTE_UPDATE_NONE,
+	SAFTE_UPDATE_READCONFIG,
+	SAFTE_UPDATE_READENCSTATUS,
+	SAFTE_UPDATE_READSLOTSTATUS,
+	SAFTE_NUM_UPDATE_STATES
+} safte_update_action;
+
+static fsm_fill_handler_t safte_fill_read_buf_io;
+static fsm_done_handler_t safte_process_config;
+static fsm_done_handler_t safte_process_status;
+static fsm_done_handler_t safte_process_slotstatus;
+
+static struct enc_fsm_state enc_fsm_states[SAFTE_NUM_UPDATE_STATES] =
+{
+	{ "SAFTE_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
+	{
+		"SAFTE_UPDATE_READCONFIG",
+		SAFTE_RD_RDCFG,
+		SAFT_SCRATCH,
+		60 * 1000,
+		safte_fill_read_buf_io,
+		safte_process_config,
+		enc_error
+	},
+	{
+		"SAFTE_UPDATE_READENCSTATUS",
+		SAFTE_RD_RDESTS,
+		SCSZ,
+		60 * 1000,
+		safte_fill_read_buf_io,
+		safte_process_status,
+		enc_error
+	},
+	{
+		"SAFTE_UPDATE_READSLOTSTATUS",
+		SAFTE_RD_RDDSTS,
+		SCSZ,
+		60 * 1000,
+		safte_fill_read_buf_io,
+		safte_process_slotstatus,
+		enc_error
+	}
+};
+
 #define	NPSEUDO_ALARM	1
 struct scfg {
 	/*
@@ -124,121 +169,127 @@ struct scfg {
 static char *safte_2little = "Too Little Data Returned (%d) at line %d\n";
 #define	SAFT_BAIL(r, x, k)	\
 	if ((r) >= (x)) { \
-		ENC_LOG(ssc, safte_2little, x, __LINE__);\
+		ENC_LOG(enc, safte_2little, x, __LINE__);\
 		ENC_FREE((k)); \
 		return (EIO); \
 	}
 
 static int
-safte_getconfig(enc_softc_t *ssc)
+safte_fill_read_buf_io(enc_softc_t *enc, struct enc_fsm_state *state,
+		       union ccb *ccb, uint8_t *buf)
+{
+
+	if (state->page_code != SAFTE_RD_RDCFG &&
+	    enc->enc_cache.nelms == 0) {
+		enc_update_request(enc, SAFTE_UPDATE_READCONFIG);
+		return (-1);
+	}
+
+	if (enc->enc_type == ENC_SEMB_SAFT) {
+		semb_read_buffer(&ccb->ataio, /*retries*/5,
+				enc_done, MSG_SIMPLE_Q_TAG,
+				state->page_code, buf, state->buf_size,
+				state->timeout);
+	} else {
+		scsi_read_buffer(&ccb->csio, /*retries*/5,
+				enc_done, MSG_SIMPLE_Q_TAG, 1,
+				state->page_code, 0, buf, state->buf_size,
+				SSD_FULL_SIZE, state->timeout);
+	}
+	return (0);
+}
+
+static int
+safte_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
+		   union ccb *ccb, uint8_t **bufp, int xfer_len)
 {
 	struct scfg *cfg;
-	int err, amt;
-	char *sdata;
-	static char cdb[10] =
-	    { READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SAFT_SCRATCH, 0 };
+	uint8_t *buf = *bufp;
+	int i, r;
 
-	cfg = ssc->enc_private;
+	cfg = enc->enc_private;
 	if (cfg == NULL)
 		return (ENXIO);
 
-	sdata = ENC_MALLOC(SAFT_SCRATCH);
-	if (sdata == NULL)
-		return (ENOMEM);
-
-	amt = SAFT_SCRATCH;
-	err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
-	if (err) {
-		ENC_FREE(sdata);
-		return (err);
-	}
-	amt = SAFT_SCRATCH - amt;
-	if (amt < 6) {
-		ENC_LOG(ssc, "too little data (%d) for configuration\n", amt);
-		ENC_FREE(sdata);
+	if (xfer_len < 6) {
+		ENC_LOG(enc, "too little data (%d) for configuration\n",
+		    xfer_len);
 		return (EIO);
 	}
-	cfg->Nfans = sdata[0];
-	cfg->Npwr = sdata[1];
-	cfg->Nslots = sdata[2];
-	cfg->DoorLock = sdata[3];
-	cfg->Ntherm = sdata[4];
-	cfg->Nspkrs = sdata[5];
+	cfg->Nfans = buf[0];
+	cfg->Npwr = buf[1];
+	cfg->Nslots = buf[2];
+	cfg->DoorLock = buf[3];
+	cfg->Ntherm = buf[4];
+	cfg->Nspkrs = buf[5];
 	cfg->Nalarm = NPSEUDO_ALARM;
-	if (amt >= 7)
-		cfg->Ntstats = sdata[6] & 0x0f;
+	if (xfer_len >= 7)
+		cfg->Ntstats = buf[6] & 0x0f;
 	else
 		cfg->Ntstats = 0;
-	ENC_VLOG(ssc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d "
+	ENC_VLOG(enc, "Nfans %d Npwr %d Nslots %d Lck %d Ntherm %d Nspkrs %d "
 	    "Ntstats %d\n",
 	    cfg->Nfans, cfg->Npwr, cfg->Nslots, cfg->DoorLock, cfg->Ntherm,
 	    cfg->Nspkrs, cfg->Ntstats);
-	ENC_FREE(sdata);
-	return (0);
-}
-
-static int
-safte_rdstat(enc_softc_t *ssc, int slpflg)
-{
-	int err, oid, r, i, hiwater, nitems, amt;
-	uint16_t tempflags;
-	size_t buflen;
-	uint8_t status, oencstat;
-	char *sdata, cdb[10];
-	struct scfg *cc = ssc->enc_private;
-	enc_cache_t *cache = &ssc->enc_cache;
-
 
-	/*
-	 * The number of objects overstates things a bit,
-	 * both for the bogus 'thermometer' entries and
-	 * the drive status (which isn't read at the same
-	 * time as the enclosure status), but that's okay.
-	 */
-	buflen = 4 * cc->Nslots;
-	if (cache->nelms > buflen)
-		buflen = cache->nelms;
-	sdata = ENC_MALLOC(buflen);
-	if (sdata == NULL)
+	enc->enc_cache.nelms = cfg->Nfans + cfg->Npwr + cfg->Nslots +
+	    cfg->DoorLock + cfg->Ntherm + cfg->Nspkrs + cfg->Ntstats + 1 +
+	    NPSEUDO_ALARM;
+	ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
+	enc->enc_cache.elm_map =
+	    ENC_MALLOCZ(enc->enc_cache.nelms * sizeof(enc_element_t));
+	if (enc->enc_cache.elm_map == NULL) {
+		enc->enc_cache.nelms = 0;
 		return (ENOMEM);
-
-	cdb[0] = READ_BUFFER;
-	cdb[1] = 1;
-	cdb[2] = SAFTE_RD_RDESTS;
-	cdb[3] = 0;
-	cdb[4] = 0;
-	cdb[5] = 0;
-	cdb[6] = 0;
-	cdb[7] = (buflen >> 8) & 0xff;
-	cdb[8] = buflen & 0xff;
-	cdb[9] = 0;
-	amt = buflen;
-	err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
-	if (err) {
-		ENC_FREE(sdata);
-		return (err);
 	}
-	hiwater = buflen - amt;
-
 
+	r = 0;
 	/*
-	 * invalidate all status bits.
+	 * Note that this is all arranged for the convenience
+	 * in later fetches of status.
 	 */
-	for (i = 0; i < cache->nelms; i++)
-		cache->elm_map[i].svalid = 0;
-	oencstat = cache->enc_status & ALL_ENC_STAT;
-	ssc->enc_cache.enc_status = 0;
+	for (i = 0; i < cfg->Nfans; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_FAN;
+	cfg->pwroff = (uint8_t) r;
+	for (i = 0; i < cfg->Npwr; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_POWER;
+	for (i = 0; i < cfg->DoorLock; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_DOORLOCK;
+	for (i = 0; i < cfg->Nspkrs; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_ALARM;
+	for (i = 0; i < cfg->Ntherm; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_THERM;
+	for (i = 0; i <= cfg->Ntstats; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_THERM;
+	enc->enc_cache.elm_map[r++].enctype = ELMTYP_ALARM;
+	cfg->slotoff = (uint8_t) r;
+	for (i = 0; i < cfg->Nslots; i++)
+		enc->enc_cache.elm_map[r++].enctype = ELMTYP_DEVICE;
 
+	enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
+	enc_update_request(enc, SAFTE_UPDATE_READSLOTSTATUS);
+
+	return (0);
+}
+
+static int
+safte_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
+		   union ccb *ccb, uint8_t **bufp, int xfer_len)
+{
+	struct scfg *cfg;
+	uint8_t *buf = *bufp;
+	int oid, r, i, nitems;
+	uint16_t tempflags;
+	enc_cache_t *cache = &enc->enc_cache;
+
+	cfg = enc->enc_private;
+	if (cfg == NULL)
+		return (ENXIO);
 
-	/*
-	 * Now parse returned buffer.
-	 * If we didn't get enough data back,
-	 * that's considered a fatal error.
-	 */
 	oid = r = 0;
 
-	for (nitems = i = 0; i < cc->Nfans; i++) {
-		SAFT_BAIL(r, hiwater, sdata);
+	for (nitems = i = 0; i < cfg->Nfans; i++) {
+		SAFT_BAIL(r, xfer_len, buf);
 		/*
 		 * 0 = Fan Operational
 		 * 1 = Fan is malfunctioning
@@ -247,7 +298,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 		 */
 		cache->elm_map[oid].encstat[1] = 0;	/* resvd */
 		cache->elm_map[oid].encstat[2] = 0;	/* resvd */
-		switch ((int)(uint8_t)sdata[r]) {
+		switch ((int)buf[r]) {
 		case 0:
 			nitems++;
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
@@ -271,7 +322,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 			 * if only one fan or no thermometers,
 			 * else the NONCRITICAL error is set.
 			 */
-			if (cc->Nfans == 1 || (cc->Ntherm + cc->Ntstats) == 0)
+			if (cfg->Nfans == 1 || (cfg->Ntherm + cfg->Ntstats) == 0)
 				cache->enc_status |= SES_ENCSTAT_CRITICAL;
 			else
 				cache->enc_status |= SES_ENCSTAT_NONCRITICAL;
@@ -285,7 +336,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 			 * if only one fan or no thermometers,
 			 * else the NONCRITICAL error is set.
 			 */
-			if (cc->Nfans == 1)
+			if (cfg->Nfans == 1)
 				cache->enc_status |= SES_ENCSTAT_CRITICAL;
 			else
 				cache->enc_status |= SES_ENCSTAT_NONCRITICAL;
@@ -297,8 +348,8 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 			break;
 		default:
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
-			ENC_LOG(ssc, "Unknown fan%d status 0x%x\n", i,
-			    sdata[r] & 0xff);
+			ENC_LOG(enc, "Unknown fan%d status 0x%x\n", i,
+			    buf[r] & 0xff);
 			break;
 		}
 		cache->elm_map[oid++].svalid = 1;
@@ -309,18 +360,18 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 	 * No matter how you cut it, no cooling elements when there
 	 * should be some there is critical.
 	 */
-	if (cc->Nfans && nitems == 0) {
+	if (cfg->Nfans && nitems == 0) {
 		cache->enc_status |= SES_ENCSTAT_CRITICAL;
 	}
 
 
-	for (i = 0; i < cc->Npwr; i++) {
-		SAFT_BAIL(r, hiwater, sdata);
+	for (i = 0; i < cfg->Npwr; i++) {
+		SAFT_BAIL(r, xfer_len, buf);
 		cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNKNOWN;
 		cache->elm_map[oid].encstat[1] = 0;	/* resvd */
 		cache->elm_map[oid].encstat[2] = 0;	/* resvd */
 		cache->elm_map[oid].encstat[3] = 0x20;	/* requested on */
-		switch ((uint8_t)sdata[r]) {
+		switch (buf[r]) {
 		case 0x00:	/* pws operational and on */
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
 			break;
@@ -359,25 +410,25 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 			cache->enc_status |= SES_ENCSTAT_INFO;
 			break;
 		default:
-			ENC_LOG(ssc, "unknown power supply %d status (0x%x)\n",
-			    i, sdata[r] & 0xff);
+			ENC_LOG(enc, "unknown power supply %d status (0x%x)\n",
+			    i, buf[r] & 0xff);
 			break;
 		}
-		ssc->enc_cache.elm_map[oid++].svalid = 1;
+		enc->enc_cache.elm_map[oid++].svalid = 1;
 		r++;
 	}
 
 	/*
 	 * Skip over Slot SCSI IDs
 	 */
-	r += cc->Nslots;
+	r += cfg->Nslots;
 
 	/*
 	 * We always have doorlock status, no matter what,
 	 * but we only save the status if we have one.
 	 */
-	SAFT_BAIL(r, hiwater, sdata);
-	if (cc->DoorLock) {
+	SAFT_BAIL(r, xfer_len, buf);
+	if (cfg->DoorLock) {
 		/*
 		 * 0 = Door Locked
 		 * 1 = Door Unlocked, or no Lock Installed
@@ -385,7 +436,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 		 */
 		cache->elm_map[oid].encstat[1] = 0;
 		cache->elm_map[oid].encstat[2] = 0;
-		switch ((uint8_t)sdata[r]) {
+		switch (buf[r]) {
 		case 0:
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
 			cache->elm_map[oid].encstat[3] = 0;
@@ -402,8 +453,8 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 		default:
 			cache->elm_map[oid].encstat[0] =
 			    SES_OBJSTAT_UNSUPPORTED;
-			ENC_LOG(ssc, "unknown lock status 0x%x\n",
-			    sdata[r] & 0xff);
+			ENC_LOG(enc, "unknown lock status 0x%x\n",
+			    buf[r] & 0xff);
 			break;
 		}
 		cache->elm_map[oid++].svalid = 1;
@@ -414,11 +465,11 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 	 * We always have speaker status, no matter what,
 	 * but we only save the status if we have one.
 	 */
-	SAFT_BAIL(r, hiwater, sdata);
-	if (cc->Nspkrs) {
+	SAFT_BAIL(r, xfer_len, buf);
+	if (cfg->Nspkrs) {
 		cache->elm_map[oid].encstat[1] = 0;
 		cache->elm_map[oid].encstat[2] = 0;
-		if (sdata[r] == 1) {
+		if (buf[r] == 1) {
 			/*
 			 * We need to cache tone urgency indicators.
 			 * Someday.
@@ -426,14 +477,14 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_NONCRIT;
 			cache->elm_map[oid].encstat[3] = 0x8;
 			cache->enc_status |= SES_ENCSTAT_NONCRITICAL;
-		} else if (sdata[r] == 0) {
+		} else if (buf[r] == 0) {
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
 			cache->elm_map[oid].encstat[3] = 0;
 		} else {
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
 			cache->elm_map[oid].encstat[3] = 0;
-			ENC_LOG(ssc, "unknown spkr status 0x%x\n",
-			    sdata[r] & 0xff);
+			ENC_LOG(enc, "unknown spkr status 0x%x\n",
+			    buf[r] & 0xff);
 		}
 		cache->elm_map[oid++].svalid = 1;
 	}
@@ -449,13 +500,13 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 	 * binary temperature sensor.
 	 */
 
-	SAFT_BAIL(r + cc->Ntherm, hiwater, sdata);
-	tempflags = sdata[r + cc->Ntherm];
-	SAFT_BAIL(r + cc->Ntherm + 1, hiwater, sdata);
-	tempflags |= (tempflags << 8) | sdata[r + cc->Ntherm + 1];
+	SAFT_BAIL(r + cfg->Ntherm, xfer_len, buf);
+	tempflags = buf[r + cfg->Ntherm];
+	SAFT_BAIL(r + cfg->Ntherm + 1, xfer_len, buf);
+	tempflags |= (tempflags << 8) | buf[r + cfg->Ntherm + 1];
 
-	for (i = 0; i < cc->Ntherm; i++) {
-		SAFT_BAIL(r, hiwater, sdata);
+	for (i = 0; i < cfg->Ntherm; i++) {
+		SAFT_BAIL(r, xfer_len, buf);
 		/*
 		 * Status is a range from -10 to 245 deg Celsius,
 		 * which we need to normalize to -20 to -245 according
@@ -492,16 +543,16 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 		} else
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_OK;
 		cache->elm_map[oid].encstat[1] = 0;
-		cache->elm_map[oid].encstat[2] = sdata[r];
+		cache->elm_map[oid].encstat[2] = buf[r];
 		cache->elm_map[oid].encstat[3] = 0;
 		cache->elm_map[oid++].svalid = 1;
 		r++;
 	}
 
-	for (i = 0; i <= cc->Ntstats; i++) {
+	for (i = 0; i <= cfg->Ntstats; i++) {
 		cache->elm_map[oid].encstat[1] = 0;
 		if (tempflags & (1 <<
-		    ((i == cc->Ntstats) ? 15 : (cc->Ntherm + i)))) {
+		    ((i == cfg->Ntstats) ? 15 : (cfg->Ntherm + i)))) {
 			cache->elm_map[oid].encstat[0] = SES_OBJSTAT_CRIT;
 			cache->elm_map[4].encstat[2] = 0xff;
 			/*
@@ -516,7 +567,7 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 			 * Just say 'OK', and use the reserved value of
 			 * zero.
 			 */
-			if ((cc->Ntherm + cc->Ntstats) == 0)
+			if ((cfg->Ntherm + cfg->Ntstats) == 0)
 				cache->elm_map[oid].encstat[0] =
 				    SES_OBJSTAT_NOTAVAIL;
 			else
@@ -536,24 +587,31 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 	cache->elm_map[oid].encstat[3] = cache->elm_map[oid].priv;
 	cache->elm_map[oid++].svalid = 1;
 
-	/*
-	 * Now get drive slot status
-	 */
-	cdb[2] = SAFTE_RD_RDDSTS;
-	amt = buflen;
-	err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
-	if (err) {
-		ENC_FREE(sdata);
-		return (err);
-	}
-	hiwater = buflen - amt;
-	for (r = i = 0; i < cc->Nslots; i++, r += 4) {
-		SAFT_BAIL(r+3, hiwater, sdata);
+	return (0);
+}
+
+static int
+safte_process_slotstatus(enc_softc_t *enc, struct enc_fsm_state *state,
+		   union ccb *ccb, uint8_t **bufp, int xfer_len)
+{
+	struct scfg *cfg;
+	uint8_t *buf = *bufp;
+	enc_cache_t *cache = &enc->enc_cache;
+	int oid, r, i;
+	uint8_t status;
+
+	cfg = enc->enc_private;
+	if (cfg == NULL)
+		return (ENXIO);
+
+	oid = cfg->slotoff;
+	for (r = i = 0; i < cfg->Nslots; i++, r += 4) {
+		SAFT_BAIL(r+3, xfer_len, buf);
 		cache->elm_map[oid].encstat[0] = SES_OBJSTAT_UNSUPPORTED;
 		cache->elm_map[oid].encstat[1] = (uint8_t) i;
 		cache->elm_map[oid].encstat[2] = 0;
 		cache->elm_map[oid].encstat[3] = 0;
-		status = sdata[r+3];
+		status = buf[r+3];
 		if ((status & 0x1) == 0) {	/* no device */
 			cache->elm_map[oid].encstat[0] =
 			    SES_OBJSTAT_NOTINSTALLED;
@@ -568,29 +626,28 @@ safte_rdstat(enc_softc_t *ssc, int slpfl
 		}
 		cache->elm_map[oid++].svalid = 1;
 	}
-	/* see comment below about sticky enclosure status */
-	cache->enc_status |= ENCI_SVALID | oencstat;
-	ENC_FREE(sdata);
 	return (0);
 }
 
 static int
-set_elm_status_sel(enc_softc_t *ssc, encioc_elm_status_t *elms, int slp)
+set_elm_status_sel(enc_softc_t *enc, encioc_elm_status_t *elms, int slp)
 {
 	int idx;
 	enc_element_t *ep;
-	struct scfg *cc = ssc->enc_private;
+	struct scfg *cc = enc->enc_private;
 
 	if (cc == NULL)
 		return (0);
 
 	idx = (int)elms->elm_idx;
-	ep = &ssc->enc_cache.elm_map[idx];
+	ep = &enc->enc_cache.elm_map[idx];
 
 	switch (ep->enctype) {
 	case ELMTYP_DEVICE:
 		if (elms->cstat[0] & SESCTL_PRDFAIL) {
 			ep->priv |= 0x40;
+		} else {
+			ep->priv &= ~0x40;
 		}
 		/* SESCTL_RSTSWAP has no correspondence in SAF-TE */
 		if (elms->cstat[0] & SESCTL_DISABLE) {
@@ -599,13 +656,15 @@ set_elm_status_sel(enc_softc_t *ssc, enc
 			 * Hmm. Try to set the 'No Drive' flag.
 			 * Maybe that will count as a 'disable'.
 			 */
+		} else {
+			ep->priv &= ~0x80;
 		}
 		if (ep->priv & 0xc6) {
 			ep->priv &= ~0x1;
 		} else {
 			ep->priv |= 0x1;	/* no errors */
 		}
-		wrslot_stat(ssc, slp);
+		wrslot_stat(enc, slp);
 		break;
 	case ELMTYP_POWER:
 		/*
@@ -613,7 +672,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
 		 * do the 'disable' for a power supply.
 		 */
 		if (elms->cstat[0] & SESCTL_DISABLE) {
-			(void) wrbuf16(ssc, SAFTE_WT_ACTPWS,
+			(void) wrbuf16(enc, SAFTE_WT_ACTPWS,
 				idx - cc->pwroff, 0, 0, slp);
 		}
 		break;
@@ -624,7 +683,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
 		 */
 		if (elms->cstat[0] & SESCTL_DISABLE) {
 			/* remember- fans are the first items, so idx works */
-			(void) wrbuf16(ssc, SAFTE_WT_FANSPD, idx, 0, 0, slp);
+			(void) wrbuf16(enc, SAFTE_WT_FANSPD, idx, 0, 0, slp);
 		}
 		break;
 	case ELMTYP_DOORLOCK:
@@ -633,7 +692,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
 		 */
 		if (elms->cstat[0] & SESCTL_DISABLE) {
 			cc->flag2 &= ~SAFT_FLG2_LOCKDOOR;
-			(void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
+			(void) wrbuf16(enc, SAFTE_WT_GLOBAL, cc->flag1,
 				cc->flag2, 0, slp);
 		}
 		break;
@@ -644,7 +703,7 @@ set_elm_status_sel(enc_softc_t *ssc, enc
 		if (elms->cstat[0] & SESCTL_DISABLE) {
 			cc->flag2 &= ~SAFT_FLG1_ALARM;
 			ep->priv |= 0x40;	/* Muted */
-			(void) wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1,
+			(void) wrbuf16(enc, SAFTE_WT_GLOBAL, cc->flag1,
 				cc->flag2, 0, slp);
 		}
 		break;
@@ -659,12 +718,12 @@ set_elm_status_sel(enc_softc_t *ssc, enc
  * This function handles all of the 16 byte WRITE BUFFER commands.
  */
 static int
-wrbuf16(enc_softc_t *ssc, uint8_t op, uint8_t b1, uint8_t b2,
+wrbuf16(enc_softc_t *enc, uint8_t op, uint8_t b1, uint8_t b2,
     uint8_t b3, int slp)
 {
 	int err, amt;
 	char *sdata;
-	struct scfg *cc = ssc->enc_private;
+	struct scfg *cc = enc->enc_private;
 	static char cdb[10] = { WRITE_BUFFER, 1, 0, 0, 0, 0, 0, 0, 16, 0 };
 
 	if (cc == NULL)
@@ -674,14 +733,14 @@ wrbuf16(enc_softc_t *ssc, uint8_t op, ui
 	if (sdata == NULL)
 		return (ENOMEM);
 
-	ENC_DLOG(ssc, "saf_wrbuf16 %x %x %x %x\n", op, b1, b2, b3);
+	ENC_DLOG(enc, "saf_wrbuf16 %x %x %x %x\n", op, b1, b2, b3);
 
 	sdata[0] = op;
 	sdata[1] = b1;
 	sdata[2] = b2;
 	sdata[3] = b3;
 	amt = -16;
-	err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
+	err = enc_runcmd(enc, cdb, 10, sdata, &amt);
 	ENC_FREE(sdata);
 	return (err);
 }
@@ -693,17 +752,17 @@ wrbuf16(enc_softc_t *ssc, uint8_t op, ui
  * returning an error.
  */
 static void
-wrslot_stat(enc_softc_t *ssc, int slp)
+wrslot_stat(enc_softc_t *enc, int slp)
 {
 	int i, amt;
 	enc_element_t *ep;
 	char cdb[10], *sdata;
-	struct scfg *cc = ssc->enc_private;
+	struct scfg *cc = enc->enc_private;
 
 	if (cc == NULL)
 		return;
 
-	ENC_DLOG(ssc, "saf_wrslot\n");
+	ENC_DLOG(enc, "saf_wrslot\n");
 	cdb[0] = WRITE_BUFFER;
 	cdb[1] = 1;
 	cdb[2] = 0;
@@ -721,12 +780,12 @@ wrslot_stat(enc_softc_t *ssc, int slp)
 
 	sdata[0] = SAFTE_WT_DSTAT;
 	for (i = 0; i < cc->Nslots; i++) {
-		ep = &ssc->enc_cache.elm_map[cc->slotoff + i];
-		ENC_DLOG(ssc, "saf_wrslot %d <- %x\n", i, ep->priv & 0xff);
+		ep = &enc->enc_cache.elm_map[cc->slotoff + i];
+		ENC_DLOG(enc, "saf_wrslot %d <- %x\n", i, ep->priv & 0xff);
 		sdata[1 + (3 * i)] = ep->priv & 0xff;
 	}
 	amt = -(cc->Nslots * 3 + 1);
-	(void) enc_runcmd(ssc, cdb, 10, sdata, &amt);
+	(void) enc_runcmd(enc, cdb, 10, sdata, &amt);
 	ENC_FREE(sdata);
 }
 
@@ -734,11 +793,11 @@ wrslot_stat(enc_softc_t *ssc, int slp)
  * This function issues the "PERFORM SLOT OPERATION" command.
  */
 static int
-perf_slotop(enc_softc_t *ssc, uint8_t slot, uint8_t opflag, int slp)
+perf_slotop(enc_softc_t *enc, uint8_t slot, uint8_t opflag, int slp)
 {
 	int err, amt;
 	char *sdata;
-	struct scfg *cc = ssc->enc_private;
+	struct scfg *cc = enc->enc_private;
 	static char cdb[10] =
 	    { WRITE_BUFFER, 1, 0, 0, 0, 0, 0, 0, SAFT_SCRATCH, 0 };
 
@@ -752,9 +811,9 @@ perf_slotop(enc_softc_t *ssc, uint8_t sl
 	sdata[0] = SAFTE_WT_SLTOP;
 	sdata[1] = slot;
 	sdata[2] = opflag;
-	ENC_DLOG(ssc, "saf_slotop slot %d op %x\n", slot, opflag);
+	ENC_DLOG(enc, "saf_slotop slot %d op %x\n", slot, opflag);
 	amt = -SAFT_SCRATCH;
-	err = enc_runcmd(ssc, cdb, 10, sdata, &amt);
+	err = enc_runcmd(enc, cdb, 10, sdata, &amt);
 	ENC_FREE(sdata);
 	return (err);
 }
@@ -762,39 +821,40 @@ perf_slotop(enc_softc_t *ssc, uint8_t sl
 static void
 safte_softc_cleanup(struct cam_periph *periph)
 {
-	enc_softc_t *ssc;
+	enc_softc_t *enc;
 
-	ssc = periph->softc;
-	ENC_FREE_AND_NULL(ssc->enc_cache.elm_map);
-	ENC_FREE_AND_NULL(ssc->enc_private);
-	ssc->enc_cache.nelms = 0;
+	enc = periph->softc;
+	ENC_FREE_AND_NULL(enc->enc_cache.elm_map);
+	ENC_FREE_AND_NULL(enc->enc_private);
+	enc->enc_cache.nelms = 0;
 }
 
 static int
-safte_init_enc(enc_softc_t *ssc)
+safte_init_enc(enc_softc_t *enc)
 {
 	int err;
 	static char cdb0[6] = { SEND_DIAGNOSTIC };
 
-	err = enc_runcmd(ssc, cdb0, 6, NULL, 0);
+	err = enc_runcmd(enc, cdb0, 6, NULL, 0);
 	if (err) {
 		return (err);
 	}
 	DELAY(5000);
-	err = wrbuf16(ssc, SAFTE_WT_GLOBAL, 0, 0, 0, 1);
+	err = wrbuf16(enc, SAFTE_WT_GLOBAL, 0, 0, 0, 1);
 	return (err);
 }
 
 static int
-safte_get_enc_status(enc_softc_t *ssc, int slpflg)
+safte_get_enc_status(enc_softc_t *enc, int slpflg)
 {
-	return (safte_rdstat(ssc, slpflg));
+
+	return (0);
 }
 
 static int
-safte_set_enc_status(enc_softc_t *ssc, uint8_t encstat, int slpflg)
+safte_set_enc_status(enc_softc_t *enc, uint8_t encstat, int slpflg)
 {
-	struct scfg *cc = ssc->enc_private;
+	struct scfg *cc = enc->enc_private;
 	if (cc == NULL)
 		return (0);
 	/*
@@ -803,46 +863,39 @@ safte_set_enc_status(enc_softc_t *ssc, u
 	 * that is, things set in enclosure status stay set (as implied
 	 * by conditions set in reading object status) until cleared.
 	 */
-	ssc->enc_cache.enc_status &= ~ALL_ENC_STAT;
-	ssc->enc_cache.enc_status |= (encstat & ALL_ENC_STAT);
-	ssc->enc_cache.enc_status |= ENCI_SVALID;
+	enc->enc_cache.enc_status &= ~ALL_ENC_STAT;
+	enc->enc_cache.enc_status |= (encstat & ALL_ENC_STAT);
 	cc->flag1 &= ~(SAFT_FLG1_ALARM|SAFT_FLG1_GLOBFAIL|SAFT_FLG1_GLOBWARN);
 	if ((encstat & (SES_ENCSTAT_CRITICAL|SES_ENCSTAT_UNRECOV)) != 0) {
 		cc->flag1 |= SAFT_FLG1_ALARM|SAFT_FLG1_GLOBFAIL;
 	} else if ((encstat & SES_ENCSTAT_NONCRITICAL) != 0) {
 		cc->flag1 |= SAFT_FLG1_GLOBWARN;
 	}
-	return (wrbuf16(ssc, SAFTE_WT_GLOBAL, cc->flag1, cc->flag2, 0, slpflg));
+	return (wrbuf16(enc, SAFTE_WT_GLOBAL, cc->flag1, cc->flag2, 0, slpflg));
 }
 
 static int
-safte_get_elm_status(enc_softc_t *ssc, encioc_elm_status_t *elms, int slpflg)
+safte_get_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slpflg)
 {
 	int i = (int)elms->elm_idx;
 
-	if ((ssc->enc_cache.enc_status & ENCI_SVALID) == 0 ||
-	    (ssc->enc_cache.elm_map[i].svalid) == 0) {
-		int err = safte_rdstat(ssc, slpflg);
-		if (err)
-			return (err);
-	}
-	elms->cstat[0] = ssc->enc_cache.elm_map[i].encstat[0];
-	elms->cstat[1] = ssc->enc_cache.elm_map[i].encstat[1];
-	elms->cstat[2] = ssc->enc_cache.elm_map[i].encstat[2];
-	elms->cstat[3] = ssc->enc_cache.elm_map[i].encstat[3];
+	elms->cstat[0] = enc->enc_cache.elm_map[i].encstat[0];
+	elms->cstat[1] = enc->enc_cache.elm_map[i].encstat[1];
+	elms->cstat[2] = enc->enc_cache.elm_map[i].encstat[2];
+	elms->cstat[3] = enc->enc_cache.elm_map[i].encstat[3];
 	return (0);
 }
 
 
 static int
-safte_set_elm_status(enc_softc_t *ssc, encioc_elm_status_t *elms, int slp)
+safte_set_elm_status(enc_softc_t *enc, encioc_elm_status_t *elms, int slp)
 {
 	int idx, err;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108241409.p7OE9Wm6057870>