Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Aug 2011 19:09:25 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r225047 - projects/zfsd/head/sys/cam/scsi
Message-ID:  <201108201909.p7KJ9PSK065364@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Aug 20 19:09:25 2011
New Revision: 225047
URL: http://svn.freebsd.org/changeset/base/225047

Log:
  Fetch list of supported diagnostic pages for SES to find whether optional
  Additional Element Status page is supported. If it's not, do not try to
  query it.

Modified:
  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_ses.c

Modified: projects/zfsd/head/sys/cam/scsi/scsi_all.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_all.h	Sat Aug 20 18:45:38 2011	(r225046)
+++ projects/zfsd/head/sys/cam/scsi/scsi_all.h	Sat Aug 20 19:09:25 2011	(r225047)
@@ -992,6 +992,13 @@ struct scsi_vpd_id_scsi_name
 	uint8_t name_string[256];
 };
 
+struct scsi_diag_page {
+	uint8_t page_code;
+	uint8_t page_specific_flags;
+	uint8_t length[2];
+	uint8_t params[0];
+};
+
 struct scsi_read_capacity
 {
 	u_int8_t opcode;

Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc.c	Sat Aug 20 18:45:38 2011	(r225046)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc.c	Sat Aug 20 19:09:25 2011	(r225047)
@@ -907,7 +907,7 @@ enc_ctor(struct cam_periph *periph, void
 		goto out;
 	}
 	enc->periph = periph;
-	enc->current_action = ENC_UPDATE_NONE;
+	enc->current_action = ENC_UPDATE_INVALID;
 
 	enc->enc_type = enc_type(cgd);
 	sx_init(&enc->enc_cache_lock, "enccache");

Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h	Sat Aug 20 18:45:38 2011	(r225046)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h	Sat Aug 20 19:09:25 2011	(r225047)
@@ -154,6 +154,7 @@ struct enc_softc {
 	/* The action on which the state machine is currently working. */
 	uint32_t		 current_action;
 #define	ENC_UPDATE_NONE		0x00
+#define	ENC_UPDATE_INVALID	0xff
 
 	/* Callout for auto-updating enclosure status */
 	struct callout		 status_updater;

Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c	Sat Aug 20 18:45:38 2011	(r225046)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c	Sat Aug 20 19:09:25 2011	(r225047)
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD: head/sys/cam/scsi/sc
 
 /* SES Diagnostic Page Codes */
 typedef enum {
+	SesSupportedPages	= 0x0,
 	SesConfigPage		= 0x1,
 	SesControlPage		= 0x2,
 	SesStatusPage		= SesControlPage,
@@ -237,6 +238,7 @@ struct ses_iterator {
 
 typedef enum {
 	SES_UPDATE_NONE,
+	SES_UPDATE_PAGES,
 	SES_UPDATE_GETCONFIG,
 	SES_UPDATE_GETSTATUS,
 	SES_UPDATE_GETELMDESCS,
@@ -253,6 +255,7 @@ static enc_softc_cleanup_t ses_softc_cle
 
 static fsm_fill_handler_t ses_fill_rcv_diag_io;
 static fsm_fill_handler_t ses_fill_control_request;
+static fsm_done_handler_t ses_process_pages;
 static fsm_done_handler_t ses_process_config;
 static fsm_done_handler_t ses_process_status;
 static fsm_done_handler_t ses_process_elm_descs;
@@ -265,6 +268,15 @@ struct enc_fsm_state enc_fsm_states[SES_
 {
 	{ "SES_UPDATE_NONE", 0, 0, 0, NULL, NULL, NULL },
 	{
+		"SES_UPDATE_PAGES",
+		SesSupportedPages,
+		SCSZ,
+		60 * 1000,
+		ses_fill_rcv_diag_io,
+		ses_process_pages,
+		enc_error
+	},
+	{
 		"SES_UPDATE_GETCONFIG",
 		SesConfigPage,
 		SCSZ,
@@ -352,6 +364,7 @@ typedef struct ses_cache {
 typedef struct ses_softc {
 	uint32_t		ses_flags;
 #define	SES_FLAG_TIMEDCOMP	0x01
+#define	SES_FLAG_ADDLSTATUS	0x02
 
 	ses_control_reqlist_t	ses_requests;
 	ses_control_reqlist_t	ses_pending_requests;
@@ -1211,6 +1224,55 @@ out:
 }
 
 /**
+ * \brief Process the list of supported pages and update flags.
+ *
+ * \param enc       SES device to query.
+ * \param buf       Buffer containing the config page.
+ * \param xfer_len  Length of the config page in the buffer.
+ *
+ * \return  0 on success, errno otherwise.
+ */
+static int
+ses_process_pages(enc_softc_t *enc, struct enc_fsm_state *state,
+		   union ccb *ccb, uint8_t **bufp, int xfer_len)
+{
+	ses_softc_t *ses;
+	struct scsi_diag_page *page;
+	int err, i, length;
+
+	CAM_DEBUG(enc->periph->path, CAM_DEBUG_SUBTRACE,
+	    ("entering %s(%p, %d)\n", __func__, bufp, xfer_len));
+	ses = enc->enc_private;
+	err = -1;
+
+	if (xfer_len < sizeof(*page)) {
+		ENC_LOG(enc, "Unable to parse Diag Pages List Header\n");
+		err = EIO;
+		goto out;
+	}
+	page = (struct scsi_diag_page *)*bufp;
+	length = scsi_2btoul(page->length);
+	if (length + offsetof(struct scsi_diag_page, params) > xfer_len) {
+		ENC_LOG(enc, "Diag Pages List Too Long\n");
+		goto out;
+	}
+	ENC_DLOG(enc, "%s: page length %d, xfer_len %d\n",
+		 __func__, length, xfer_len);
+
+	err = 0;
+	for (i = 0; i < length; i++) {
+		if (page->params[i] == SesAddlElementStatus) {
+			ses->ses_flags |= SES_FLAG_ADDLSTATUS;
+			break;
+		}
+	}
+
+out:
+	ENC_DLOG(enc, "%s: exiting with err %d\n", __func__, err);
+	return (err);
+}
+
+/**
  * \brief Process the config page and update associated structures.
  *
  * \param enc       SES device to query.
@@ -1411,7 +1473,8 @@ out:
 	else {
 		enc_update_request(enc, SES_UPDATE_GETSTATUS);
 		enc_update_request(enc, SES_UPDATE_GETELMDESCS);
-		enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+		if (ses->ses_flags & SES_FLAG_ADDLSTATUS)
+			enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
 		enc_update_request(enc, SES_PUBLISH_CACHE);
 	}
 	ENC_DLOG(enc, "%s: exiting with err %d\n", __func__, err);
@@ -1817,6 +1880,7 @@ static int
 ses_process_elm_descs(enc_softc_t *enc, struct enc_fsm_state *state,
 		     union ccb *ccb, uint8_t **bufp, int xfer_len)
 {
+	ses_softc_t *ses;
 	struct ses_iterator iter;
 	enc_element_t *element;
 	int err;
@@ -1829,6 +1893,7 @@ ses_process_elm_descs(enc_softc_t *enc, 
 	const struct ses_page_hdr *phdr;
 	const struct ses_elm_desc_hdr *hdr;
 
+	ses = enc->enc_private;
 	enc_cache = &enc->enc_daemon_cache;
 	ses_cache = enc_cache->private;
 	buf = *bufp;
@@ -1891,8 +1956,10 @@ ses_process_elm_descs(enc_softc_t *enc, 
 
 	err = 0;
 out:
-	if (err == 0)
-		enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+	if (err == 0) {
+		if (ses->ses_flags & SES_FLAG_ADDLSTATUS)
+			enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+	}
 	enc_update_request(enc, SES_PUBLISH_CACHE);
 	return (err);
 }
@@ -2633,8 +2700,12 @@ ses_handle_string(enc_softc_t *enc, enci
 static void
 ses_poll_status(enc_softc_t *enc)
 {
+	ses_softc_t *ses;
+
+	ses = enc->enc_private;
 	enc_update_request(enc, SES_UPDATE_GETSTATUS);
-	enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
+	if (ses->ses_flags & SES_FLAG_ADDLSTATUS)
+		enc_update_request(enc, SES_UPDATE_GETELMADDLSTATUS);
 }
 
 /**
@@ -2710,6 +2781,8 @@ ses_softc_init(enc_softc_t *enc, int doi
 	TAILQ_INIT(&ses_softc->ses_requests);
 	TAILQ_INIT(&ses_softc->ses_pending_requests);
 
+	enc_update_request(enc, SES_UPDATE_PAGES);
+
 	// XXX: Move this to the FSM so it doesn't hang init
 	if (0) (void) ses_set_timed_completion(enc, 1);
 



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