Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 18 Jul 2011 19:26:16 +0000 (UTC)
From:      "Justin T. Gibbs" <gibbs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r224197 - in projects/zfsd/head: share/examples/ses share/examples/ses/srcs sys/amd64/conf sys/cam/scsi sys/conf sys/i386/conf sys/ia64/conf sys/mips/conf sys/modules/cam sys/pc98/conf ...
Message-ID:  <201107181926.p6IJQG5W036152@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gibbs
Date: Mon Jul 18 19:26:16 2011
New Revision: 224197
URL: http://svn.freebsd.org/changeset/base/224197

Log:
  Revamp the CAM enclosure services driver, renaming it to "enc" from "ses" in
  the process.  This updated driver uses an in-kernel daemon to track state
  changes and publishes physical path location information for disk elements
  into the CAM device database.
  
  share/examples/ses/Makefile.inc:
  share/examples/ses/srcs/eltsub.c:
  share/examples/ses/srcs/sesd.c:
  share/examples/ses/srcs/getencstat.c:
  share/examples/ses/srcs/setobjstat.c:
  share/examples/ses/srcs/inienc.c:
  share/examples/ses/srcs/getobjstat.c:
  share/examples/ses/srcs/getnobj.c:
  share/examples/ses/srcs/getobjmap.c:
  share/examples/ses/srcs/setencstat.c:
  	Update for changes in driver name and API.  The ioctl interface
  	is largely unchanged and could use additional refinement.  It
  	would be nice to be able to fetch the status of all elements in
  	a single ioctl call and to have the ioctls that return variable
  	length data allow you to query the necessary allocation size
  	by passing in a zero length buffer.
  
  sys/sparc64/conf/GENERIC:
  sys/ia64/conf/GENERIC:
  sys/mips/conf/OCTEON1:
  sys/pc98/conf/GENERIC:
  sys/i386/conf/GENERIC:
  sys/amd64/conf/GENERIC:
  	ses -> enc
  
  sys/conf/files:
  sys/modules/cam/Makefile:
  sys/cam/scsi/scsi_enc_internal.h
  sys/cam/scsi/scsi_enc_ses.c
  sys/cam/scsi/scsi_enc_safte.c
  sys/cam/scsi/scsi_ses.c
  sys/cam/scsi/scsi_enc.c
  	Split the enc driver into a generic driver file and one file
  	each for the SES and SAF-TE personalities.
  
  sys/cam/scsi/scsi_ses.h:
  	o Retain this header, but use it to only hold structures derived
  	  from the T10 SES spec.  The driver interface can be found in
  	  scsi_enc.h.
  	o Add definitions for most SES pages.
  
  sys/cam/scsi/scsi_enc.c
  sys/cam/scsi/scsi_enc.h
  	o Use a function vector table to allow interaction between the
  	  generic and protocol specific portions of this driver.
  	o Provide a generic mechanism allowing personalities to define a
  	  finite state machine that is executed from a daemon thread context.
  	o Track CAM device arrival events and pass these on to personalities
  	  that have registered an interest in them.  These notifications are
  	  used to trigger physical path updates in the CAM EDT.
  
  sys/cam/scsi/scsi_enc_safte.c:
  	The SAF-TE personality.  This module is largely untouched by this
  	update.  To achieve the same level of support as we have for SES,
  	it will need to define an FSM and code to determine the physical
  	paths of elements within the enclosure.
  
  sys/cam/scsi/scsi_enc_ses.c:
  	o Implement a state machine to fetch configuration, status, element
  	  descriptors, and additional element status.
  	o Build a "element map" that indexes into the config and status
  	  data retrieved from a SES device.  Use this to simplify our
  	  responses to ioctls.
  	o Add support for using SAS domain/phy WWN data to determine the
  	  physical path (ence@<enc WWN>/type@<elm type>/slot@<slot #>)
  	  of an element.  Stubs are in place for FC, but both FC and SPI
  	  will need additional work in order to be supported.
  
  Sponsored by:	Spectra Logic Corporation
  Submitted by:	gibbs, will

Added:
  projects/zfsd/head/sys/cam/scsi/scsi_enc.c
  projects/zfsd/head/sys/cam/scsi/scsi_enc.h
  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
Deleted:
  projects/zfsd/head/sys/cam/scsi/scsi_ses.c
Modified:
  projects/zfsd/head/share/examples/ses/Makefile.inc
  projects/zfsd/head/share/examples/ses/srcs/eltsub.c
  projects/zfsd/head/share/examples/ses/srcs/getencstat.c
  projects/zfsd/head/share/examples/ses/srcs/getnobj.c
  projects/zfsd/head/share/examples/ses/srcs/getobjmap.c
  projects/zfsd/head/share/examples/ses/srcs/getobjstat.c
  projects/zfsd/head/share/examples/ses/srcs/inienc.c
  projects/zfsd/head/share/examples/ses/srcs/sesd.c
  projects/zfsd/head/share/examples/ses/srcs/setencstat.c
  projects/zfsd/head/share/examples/ses/srcs/setobjstat.c
  projects/zfsd/head/sys/amd64/conf/GENERIC
  projects/zfsd/head/sys/cam/scsi/scsi_ses.h
  projects/zfsd/head/sys/conf/files
  projects/zfsd/head/sys/i386/conf/GENERIC
  projects/zfsd/head/sys/ia64/conf/GENERIC
  projects/zfsd/head/sys/mips/conf/OCTEON1
  projects/zfsd/head/sys/modules/cam/Makefile
  projects/zfsd/head/sys/pc98/conf/GENERIC
  projects/zfsd/head/sys/sparc64/conf/GENERIC

Modified: projects/zfsd/head/share/examples/ses/Makefile.inc
==============================================================================
--- projects/zfsd/head/share/examples/ses/Makefile.inc	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/Makefile.inc	Mon Jul 18 19:26:16 2011	(r224197)
@@ -32,7 +32,6 @@
 # mjacob@feral.com
 #
 
-CFLAGS+= -I/usr/include/cam/scsi -DSESINC="<scsi_ses.h>"
 BINDIR?= /usr/sbin
 
 CLEANFILES+= ${MAN}

Modified: projects/zfsd/head/share/examples/ses/srcs/eltsub.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/eltsub.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/eltsub.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,10 +33,13 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_enc.h>
 
 #include "eltsub.h"
 
@@ -46,80 +49,83 @@ geteltnm(int type)
 	static char rbuf[132];
 
 	switch (type) {
-	case SESTYP_UNSPECIFIED:
+	case ELMTYP_UNSPECIFIED:
 		sprintf(rbuf, "Unspecified");
 		break;
-	case SESTYP_DEVICE:
+	case ELMTYP_DEVICE:
 		sprintf(rbuf, "Device");
 		break;
-	case SESTYP_POWER:
+	case ELMTYP_POWER:
 		sprintf(rbuf, "Power supply");
 		break;
-	case SESTYP_FAN:
+	case ELMTYP_FAN:
 		sprintf(rbuf, "Cooling element");
 		break;
-	case SESTYP_THERM:
+	case ELMTYP_THERM:
 		sprintf(rbuf, "Temperature sensors");
 		break;
-	case SESTYP_DOORLOCK:
+	case ELMTYP_DOORLOCK:
 		sprintf(rbuf, "Door Lock");
 		break;
-	case SESTYP_ALARM:
+	case ELMTYP_ALARM:
 		sprintf(rbuf, "Audible alarm");
 		break;
-	case SESTYP_ESCC:
+	case ELMTYP_ESCC:
 		sprintf(rbuf, "Enclosure services controller electronics");
 		break;
-	case SESTYP_SCC:
+	case ELMTYP_SCC:
 		sprintf(rbuf, "SCC controller electronics");
 		break;
-	case SESTYP_NVRAM:
+	case ELMTYP_NVRAM:
 		sprintf(rbuf, "Nonvolatile cache");
 		break;
-	case SESTYP_UPS:
+	case ELMTYP_INV_OP_REASON:
+		sprintf(rbuf, "Invalid Operation Reason");
+		break;
+	case ELMTYP_UPS:
 		sprintf(rbuf, "Uninterruptible power supply");
 		break;
-	case SESTYP_DISPLAY:
+	case ELMTYP_DISPLAY:
 		sprintf(rbuf, "Display");
 		break;
-	case SESTYP_KEYPAD:
+	case ELMTYP_KEYPAD:
 		sprintf(rbuf, "Key pad entry device");
 		break;
-	case SESTYP_ENCLOSURE:
+	case ELMTYP_ENCLOSURE:
 		sprintf(rbuf, "Enclosure");
 		break;
-	case SESTYP_SCSIXVR:
+	case ELMTYP_SCSIXVR:
 		sprintf(rbuf, "SCSI port/transceiver");
 		break;
-	case SESTYP_LANGUAGE:
+	case ELMTYP_LANGUAGE:
 		sprintf(rbuf, "Language");
 		break;
-	case SESTYP_COMPORT:
+	case ELMTYP_COMPORT:
 		sprintf(rbuf, "Communication Port");
 		break;
-	case SESTYP_VOM:
+	case ELMTYP_VOM:
 		sprintf(rbuf, "Voltage Sensor");
 		break;
-	case SESTYP_AMMETER:
+	case ELMTYP_AMMETER:
 		sprintf(rbuf, "Current Sensor");
 		break;
-	case SESTYP_SCSI_TGT:
+	case ELMTYP_SCSI_TGT:
 		sprintf(rbuf, "SCSI target port");
 		break;
-	case SESTYP_SCSI_INI:
+	case ELMTYP_SCSI_INI:
 		sprintf(rbuf, "SCSI initiator port");
 		break;
-	case SESTYP_SUBENC:
+	case ELMTYP_SUBENC:
 		sprintf(rbuf, "Simple sub-enclosure");
 		break;
-	case SESTYP_ARRAY:
+	case ELMTYP_ARRAY_DEV:
 		sprintf(rbuf, "Array device");
 		break;
-	case SESTYP_SASEXPANDER:
-		sprintf(rbuf, "SAS Expander");
+	case ELMTYP_SAS_EXP:
+		sprintf(rbuf, "SAS expander");
 		break;
-	case SESTYP_SASCONNECTOR:
-		sprintf(rbuf, "SAS Connector");
+	case ELMTYP_SAS_CONN:
+		sprintf(rbuf, "SAS connector");
 		break;
 	default:
 		(void) sprintf(rbuf, "<Type 0x%x>", type);

Modified: projects/zfsd/head/share/examples/ses/srcs/getencstat.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/getencstat.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/getencstat.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,20 +33,25 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_enc.h>
 
 #include "eltsub.h"
 
 int
 main(int a, char **v)
 {
-	ses_object *objp;
-	ses_objstat ob;
+	encioc_element_t *objp;
+	encioc_elm_status_t ob;
+	encioc_elm_desc_t objd;
+	encioc_elm_devnames_t objdn;
 	int fd, nobj, f, i, verbose, quiet, errors;
 	u_char estat;
 
@@ -73,13 +78,13 @@ main(int a, char **v)
 			perror(*v);
 			continue;
 		}
-		if (ioctl(fd, SESIOC_GETNOBJ, (caddr_t) &nobj) < 0) {
-			perror("SESIOC_GETNOBJ");
+		if (ioctl(fd, ENCIOC_GETNELM, (caddr_t) &nobj) < 0) {
+			perror("ENCIOC_GETNELM");
 			(void) close(fd);
 			continue;
 		}
-		if (ioctl(fd, SESIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
-			perror("SESIOC_GETENCSTAT");
+		if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &estat) < 0) {
+			perror("ENCIOC_GETENCSTAT");
 			(void) close(fd);
 			continue;
 		}
@@ -113,38 +118,67 @@ main(int a, char **v)
 			}
 		}
 		fprintf(stdout, ">\n");
-		objp = calloc(nobj, sizeof (ses_object));
+		objp = calloc(nobj, sizeof (encioc_element_t));
 		if (objp == NULL) {
 			perror("calloc");
 			(void) close(fd);
 			continue;
 		}
-                if (ioctl(fd, SESIOC_GETOBJMAP, (caddr_t) objp) < 0) {
-                        perror("SESIOC_GETOBJMAP");
+                if (ioctl(fd, ENCIOC_GETELMMAP, (caddr_t) objp) < 0) {
+                        perror("ENCIOC_GETELMMAP");
                         (void) close(fd);
                         continue;
                 }
 		for (i = 0; i < nobj; i++) {
-			ob.obj_id = objp[i].obj_id;
-			if (ioctl(fd, SESIOC_GETOBJSTAT, (caddr_t) &ob) < 0) {
-				perror("SESIOC_GETOBJSTAT");
+			ob.elm_idx = objp[i].elm_idx;
+			if (ioctl(fd, ENCIOC_GETELMSTAT, (caddr_t) &ob) < 0) {
+				perror("ENCIOC_GETELMSTAT");
 				(void) close(fd);
 				break;
 			}
-			if ((ob.cstat[0] & 0xf) == SES_OBJSTAT_OK) {
-				if (verbose) {
-					fprintf(stdout,
-					    "Element 0x%x: %s OK (%s)\n",
-					    ob.obj_id,
-					    geteltnm(objp[i].object_type),
-					    stat2ascii(objp[i].object_type,
-					    ob.cstat));
-				}
+			bzero(&objd, sizeof(objd));
+			objd.elm_idx = objp[i].elm_idx;
+			objd.elm_desc_len = UINT16_MAX;
+			objd.elm_desc_str = calloc(UINT16_MAX, sizeof(char));
+			if (objd.elm_desc_str == NULL) {
+				perror("calloc");
+				(void) close(fd);
 				continue;
 			}
-			fprintf(stdout, "Element 0x%x: %s, %s\n",
-			    ob.obj_id, geteltnm(objp[i].object_type),
-			    stat2ascii(objp[i].object_type, ob.cstat));
+			if (ioctl(fd, ENCIOC_GETELMDESC, (caddr_t)&objd) < 0) {
+				perror("ENCIOC_GETELMDESC");
+				(void) close(fd);
+				break;
+			}
+			bzero(&objdn, sizeof(objdn));
+			objdn.elm_idx = objp[i].elm_idx;
+			objdn.elm_names_size = 128;
+			objdn.elm_devnames = calloc(128, sizeof(char));
+			if (objdn.elm_devnames == NULL) {
+				perror("calloc");
+				(void) close(fd);
+				break;
+			}
+			/*
+			 * This ioctl isn't critical and has a good chance
+			 * of returning -1.
+			 */
+			(void)ioctl(fd, ENCIOC_GETELMDEVNAMES, (caddr_t)&objdn);
+			fprintf(stdout, "Element 0x%x: %s", ob.elm_idx,
+			    geteltnm(objp[i].elm_type));
+			if ((ob.cstat[0] & 0xf) == SES_OBJSTAT_OK)
+				fprintf(stdout, ", OK (%s)",
+				    stat2ascii(objp[i].elm_type, ob.cstat));
+			else
+				fprintf(stdout, ", %s",
+				    stat2ascii(objp[i].elm_type, ob.cstat));
+			fprintf(stdout, ", descriptor: '%s'",
+			    objd.elm_desc_str);
+			if (objdn.elm_names_len > 0)
+				fprintf(stdout, ", dev: '%s'",
+				    objdn.elm_devnames);
+			fprintf(stdout, "\n");
+			free(objdn.elm_devnames);
 		}
 		free(objp);
 		(void) close(fd);

Modified: projects/zfsd/head/share/examples/ses/srcs/getnobj.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/getnobj.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/getnobj.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,12 +33,15 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_ses.h>
 
 int
 main(int argc, char **argv)

Modified: projects/zfsd/head/share/examples/ses/srcs/getobjmap.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/getobjmap.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/getobjmap.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,11 +33,14 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_ses.h>
 
 #include "eltsub.h"
 

Modified: projects/zfsd/head/share/examples/ses/srcs/getobjstat.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/getobjstat.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/getobjstat.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -32,11 +32,14 @@
  * mjacob@feral.com
  */
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_ses.h>
 
 int
 main(int a, char **v)

Modified: projects/zfsd/head/share/examples/ses/srcs/inienc.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/inienc.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/inienc.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,11 +33,14 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_ses.h>
 
 int
 main(int a, char **v)

Modified: projects/zfsd/head/share/examples/ses/srcs/sesd.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/sesd.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/sesd.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -32,6 +32,8 @@
  * mjacob@feral.com
  */
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
@@ -39,7 +41,8 @@
 #include <string.h>
 #include <syslog.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_enc.h>
 
 #define	ALLSTAT (SES_ENCSTAT_UNRECOV | SES_ENCSTAT_CRITICAL | \
 	SES_ENCSTAT_NONCRITICAL | SES_ENCSTAT_INFO)
@@ -54,7 +57,7 @@ main(int a, char **v)
 	static const char *usage =
 	    "usage: %s [ -d ] [ -t pollinterval ] device [ device ]\n";
 	int fd, polltime, dev, devbase, nodaemon;
-	ses_encstat stat, *carray;
+	encioc_enc_status_t stat, *carray;
 
 	if (a < 2) {
 		fprintf(stderr, usage, *v);
@@ -83,7 +86,7 @@ main(int a, char **v)
 		return (1);
 	}
 	for (dev = devbase; dev < a; dev++)
-		carray[dev] = (ses_encstat) -1;
+		carray[dev] = (encioc_enc_status_t) -1;
 
 	/*
 	 * Check to make sure we can open all devices
@@ -94,8 +97,8 @@ main(int a, char **v)
 			perror(v[dev]);
 			return (1);
 		}
-		if (ioctl(fd, SESIOC_INIT, NULL) < 0) {
-			fprintf(stderr, "%s: SESIOC_INIT fails- %s\n",
+		if (ioctl(fd, ENCIOC_INIT, NULL) < 0) {
+			fprintf(stderr, "%s: ENCIOC_INIT fails- %s\n",
 			    v[dev], strerror(errno));
 			return (1);
 		}
@@ -122,9 +125,9 @@ main(int a, char **v)
 			/*
 			 * Get the actual current enclosure status.
 			 */
-			if (ioctl(fd, SESIOC_GETENCSTAT, (caddr_t) &stat) < 0) {
+			if (ioctl(fd, ENCIOC_GETENCSTAT, (caddr_t) &stat) < 0) {
 				syslog(LOG_ERR,
-				    "%s: SESIOC_GETENCSTAT- %m", v[dev]);
+				    "%s: ENCIOC_GETENCSTAT- %m", v[dev]);
 				(void) close(fd);
 				continue;
 			}

Modified: projects/zfsd/head/share/examples/ses/srcs/setencstat.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/setencstat.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/setencstat.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,18 +33,21 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_enc.h>
 
 int
 main(int a, char **v)
 {
 	int fd;
 	long val;
-	ses_encstat stat;
+	encioc_enc_status_t stat;
 
 	if (a != 3) {
 		fprintf(stderr, "usage: %s device enclosure_status\n", *v);
@@ -57,9 +60,9 @@ main(int a, char **v)
 	}
 	
 	val =  strtol(v[2], NULL, 0);
-	stat = (ses_encstat) val;
-	if (ioctl(fd, SESIOC_SETENCSTAT, (caddr_t) &stat) < 0) {
-		perror("SESIOC_SETENCSTAT");
+	stat = (encioc_enc_status_t)val;
+	if (ioctl(fd, ENCIOC_SETENCSTAT, (caddr_t) &stat) < 0) {
+		perror("ENCIOC_SETENCSTAT");
 	}
 	(void) close(fd);
 	return (0);

Modified: projects/zfsd/head/share/examples/ses/srcs/setobjstat.c
==============================================================================
--- projects/zfsd/head/share/examples/ses/srcs/setobjstat.c	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/share/examples/ses/srcs/setobjstat.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -33,18 +33,21 @@
  */
 
 #include <unistd.h>
+#include <stddef.h>
+#include <stdint.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
-#include SESINC
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_enc.h>
 
 int
 main(int a, char **v)
 {
 	int fd;
 	int i;
-	ses_objstat obj;
+	encioc_elm_status_t obj;
 	long cvt;
 	char *x;
 
@@ -64,7 +67,7 @@ usage:
 	if (x == v[2]) {
 		goto usage;
 	}
-	obj.obj_id = cvt;
+	obj.elm_idx = cvt;
 	for (i = 0; i < 4; i++) {
 		x = v[3 + i];
 		cvt = strtol(v[3 + i],  &x, 0);
@@ -73,8 +76,8 @@ usage:
 		}
 		obj.cstat[i] = cvt;
 	}
-	if (ioctl(fd, SESIOC_SETOBJSTAT, (caddr_t) &obj) < 0) {
-		perror("SESIOC_SETOBJSTAT");
+	if (ioctl(fd, ENCIOC_SETELMSTAT, (caddr_t) &obj) < 0) {
+		perror("ENCIOC_SETELMSTAT");
 	}
 	(void) close(fd);
 	return (0);

Modified: projects/zfsd/head/sys/amd64/conf/GENERIC
==============================================================================
--- projects/zfsd/head/sys/amd64/conf/GENERIC	Mon Jul 18 19:23:50 2011	(r224196)
+++ projects/zfsd/head/sys/amd64/conf/GENERIC	Mon Jul 18 19:26:16 2011	(r224197)
@@ -126,7 +126,7 @@ device		da		# Direct Access (disks)
 device		sa		# Sequential Access (tape etc)
 device		cd		# CD
 device		pass		# Passthrough device (direct ATA/SCSI access)
-device		ses		# SCSI Environmental Services (and SAF-TE)
+device		enc		# Enclosure Services (SES and SAF-TE)
 
 # RAID controllers interfaced to the SCSI subsystem
 device		amr		# AMI MegaRAID

Added: projects/zfsd/head/sys/cam/scsi/scsi_enc.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc.c	Mon Jul 18 19:26:16 2011	(r224197)
@@ -0,0 +1,975 @@
+/*-
+ * Copyright (c) 2000 Matthew Jacob
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification, immediately at the beginning of the file.
+ * 2. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <sys/conf.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mutex.h>
+#include <sys/queue.h>
+#include <sys/sx.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+
+#include <machine/stdarg.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_debug.h>
+#include <cam/cam_periph.h>
+#include <cam/cam_xpt_periph.h>
+
+#include <cam/scsi/scsi_all.h>
+#include <cam/scsi/scsi_message.h>
+#include <cam/scsi/scsi_enc.h>
+#include <cam/scsi/scsi_enc_internal.h>
+
+#include <opt_enc.h>
+
+MALLOC_DEFINE(M_SCSIENC, "SCSI ENC", "SCSI ENC buffers");
+
+/* Enclosure type independent driver */
+
+#define	SEN_ID		"UNISYS           SUN_SEN"
+#define	SEN_ID_LEN	24
+
+static	d_open_t	enc_open;
+static	d_close_t	enc_close;
+static	d_ioctl_t	enc_ioctl;
+static	periph_init_t	enc_init;
+static  periph_ctor_t	enc_ctor;
+static	periph_oninv_t	enc_oninvalidate;
+static  periph_dtor_t   enc_dtor;
+static  periph_start_t  enc_start;
+
+static void enc_async(void *, uint32_t, struct cam_path *, void *);
+static enctyp enc_type(void *, int);
+
+static struct periph_driver encdriver = {
+	enc_init, "enc",
+	TAILQ_HEAD_INITIALIZER(encdriver.units), /* generation */ 0
+};
+
+PERIPHDRIVER_DECLARE(enc, encdriver);
+
+static struct cdevsw enc_cdevsw = {
+	.d_version =	D_VERSION,
+	.d_open =	enc_open,
+	.d_close =	enc_close,
+	.d_ioctl =	enc_ioctl,
+	.d_name =	"enc",
+	.d_flags =	0,
+};
+
+static void
+enc_init(void)
+{
+	cam_status status;
+
+	/*
+	 * Install a global async callback.  This callback will
+	 * receive async callbacks like "new device found".
+	 */
+	status = xpt_register_async(AC_FOUND_DEVICE, enc_async, NULL, NULL);
+
+	if (status != CAM_REQ_CMP) {
+		printf("enc: Failed to attach master async callback "
+		       "due to status 0x%x!\n", status);
+	}
+}
+
+static void
+enc_oninvalidate(struct cam_periph *periph)
+{
+	struct enc_softc *enc;
+
+	enc = periph->softc;
+
+	/* If the sub-driver has an invalidate routine, call it */
+	if (enc->enc_vec.softc_invalidate != NULL)
+		enc->enc_vec.softc_invalidate(periph);
+
+	/*
+	 * Unregister any async callbacks.
+	 */
+	xpt_register_async(0, enc_async, periph, periph->path);
+
+	/*
+	 * Shutdown our daemon.
+	 */
+	enc->enc_flags |= ENC_FLAG_SHUTDOWN;
+	if (enc->enc_daemon != NULL) {
+		/* Signal and wait for the ses daemon to terminate. */
+		wakeup(enc->enc_daemon);
+		/*
+		 * We're called with the SIM mutex held, but we're dropping
+		 * the update mutex here on sleep.  So we have to manually
+		 * drop the SIM mutex.
+		 */
+		cam_periph_sleep(enc->periph, enc->enc_daemon,
+				 PUSER, "thtrm", 0);
+	}
+	callout_drain(&enc->status_updater);
+
+	enc->enc_flags |= ENC_FLAG_INVALID;
+
+	xpt_print(periph->path, "lost device\n");
+}
+
+static void
+enc_dtor(struct cam_periph *periph)
+{
+	struct enc_softc *enc;
+
+	enc = periph->softc;
+
+	xpt_print(periph->path, "removing device entry\n");
+	cam_periph_unlock(periph);
+	destroy_dev(enc->enc_dev);
+	cam_periph_lock(periph);
+
+	/* If the sub-driver has a cleanup routine, call it */
+	if (enc->enc_vec.softc_cleanup != NULL)
+		enc->enc_vec.softc_cleanup(periph);
+
+	if (enc->enc_boot_hold_ch.ich_func != NULL) {
+		config_intrhook_disestablish(&enc->enc_boot_hold_ch);
+		enc->enc_boot_hold_ch.ich_func = NULL;
+	}
+
+	ENC_FREE(enc);
+}
+
+static void
+enc_async(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
+{
+	struct cam_periph *periph;
+
+	periph = (struct cam_periph *)callback_arg;
+
+	switch(code) {
+	case AC_FOUND_DEVICE:
+	{
+		struct ccb_getdev *cgd;
+		cam_status status;
+		int inq_len;
+		path_id_t path_id;
+
+		cgd = (struct ccb_getdev *)arg;
+		if (arg == NULL) {
+			break;
+		}
+
+		if (cgd->protocol != PROTO_SCSI)
+			break;
+
+		inq_len = cgd->inq_data.additional_length + 4;
+
+		/*
+		 * PROBLEM: WE NEED TO LOOK AT BYTES 48-53 TO SEE IF THIS
+		 * PROBLEM: IS A SAF-TE DEVICE.
+		 */
+		switch (enc_type(&cgd->inq_data, inq_len)) {
+		case ENC_SES:
+		case ENC_SES_SCSI2:
+		case ENC_SES_PASSTHROUGH:
+		case ENC_SEN:
+		case ENC_SAFT:
+			break;
+		default:
+			/*
+			 * Schedule announcement of the ENC bindings for
+			 * this device if it is managed by a SEP.
+			 */
+			path_id = xpt_path_path_id(path);
+			xpt_lock_buses();
+			TAILQ_FOREACH(periph, &encdriver.units, unit_links) {
+				struct enc_softc *softc;
+
+				softc = (struct enc_softc *)periph->softc;
+				if (xpt_path_path_id(periph->path) != path_id
+				 || softc == NULL
+				 || (softc->enc_flags & ENC_FLAG_INITIALIZED)
+				  == 0
+				 || softc->enc_vec.device_found == NULL)
+					continue;
+
+				softc->enc_vec.device_found(softc);
+			}
+			xpt_unlock_buses();
+			return;
+		}
+
+		status = cam_periph_alloc(enc_ctor, enc_oninvalidate,
+		    enc_dtor, enc_start, "enc", CAM_PERIPH_BIO,
+		    cgd->ccb_h.path, enc_async, AC_FOUND_DEVICE, cgd);
+
+		if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) {
+			printf("enc_async: Unable to probe new device due to "
+			    "status 0x%x\n", status);
+		}
+		break;
+	}
+	default:
+		cam_periph_async(periph, code, path, arg);
+		break;
+	}
+}
+
+static int
+enc_open(struct cdev *dev, int flags, int fmt, struct thread *td)
+{
+	struct cam_periph *periph;
+	struct enc_softc *softc;
+	int error = 0;
+
+	periph = (struct cam_periph *)dev->si_drv1;
+	if (periph == NULL) {
+		return (ENXIO);
+	}
+
+	if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
+		cam_periph_unlock(periph);
+		return (ENXIO);
+	}
+
+	cam_periph_lock(periph);
+
+	softc = (struct enc_softc *)periph->softc;
+
+	if ((softc->enc_flags & ENC_FLAG_INITIALIZED) == 0) {
+		error = ENXIO;
+		goto out;
+	}
+	if (softc->enc_flags & ENC_FLAG_INVALID) {
+		error = ENXIO;
+		goto out;
+	}
+
+out:
+	cam_periph_unlock(periph);
+	if (error) {
+		cam_periph_release(periph);
+	}
+	return (error);
+}
+
+static int
+enc_close(struct cdev *dev, int flag, int fmt, struct thread *td)
+{
+	struct cam_periph *periph;
+	struct enc_softc *softc;
+	int error;
+
+	error = 0;
+
+	periph = (struct cam_periph *)dev->si_drv1;
+	if (periph == NULL)
+		return (ENXIO);
+
+	cam_periph_lock(periph);
+
+	softc = (struct enc_softc *)periph->softc;
+
+	cam_periph_unlock(periph);
+	cam_periph_release(periph);
+
+	return (0);
+}
+
+static void
+enc_start(struct cam_periph *p, union ccb *sccb)
+{
+	struct enc_softc *enc;
+
+	enc = p->softc;
+	ENC_DLOG(enc, "%s enter imm=%d prio=%d\n",
+	    __func__, p->immediate_priority, p->pinfo.priority);
+	if (p->immediate_priority <= p->pinfo.priority) {
+		SLIST_INSERT_HEAD(&p->ccb_list, &sccb->ccb_h, periph_links.sle);
+		p->immediate_priority = CAM_PRIORITY_NONE;
+		wakeup(&p->ccb_list);
+	} else
+		xpt_release_ccb(sccb);
+	ENC_DLOG(enc, "%s exit\n", __func__);
+}
+
+void
+enc_done(struct cam_periph *periph, union ccb *dccb)
+{
+	wakeup(&dccb->ccb_h.cbfcnp);
+}
+
+int
+enc_error(union ccb *ccb, uint32_t cflags, uint32_t sflags)
+{
+	struct enc_softc *softc;
+	struct cam_periph *periph;
+
+	periph = xpt_path_periph(ccb->ccb_h.path);
+	softc = (struct enc_softc *)periph->softc;
+
+	return (cam_periph_error(ccb, cflags, sflags, &softc->saved_ccb));
+}
+
+static int
+enc_ioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag,
+	 struct thread *td)
+{
+	struct cam_periph *periph;
+	encioc_enc_status_t tmp;
+	encioc_string_t sstr;
+	encioc_elm_status_t elms;
+	encioc_elm_desc_t elmd;
+	encioc_elm_devnames_t elmdn;
+	encioc_element_t *uelm;
+	enc_softc_t *enc;
+	enc_cache_t *cache;
+	void *addr;
+	int error, i;
+
+
+	if (arg_addr)
+		addr = *((caddr_t *) arg_addr);
+	else
+		addr = NULL;
+
+	periph = (struct cam_periph *)dev->si_drv1;
+	if (periph == NULL)
+		return (ENXIO);
+
+	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering encioctl\n"));
+
+	cam_periph_lock(periph);
+	enc = (struct enc_softc *)periph->softc;
+	cache = &enc->enc_cache;
+
+	/*
+	 * Now check to see whether we're initialized or not.
+	 * This actually should never fail as we're not supposed
+	 * to get past enc_open w/o successfully initializing
+	 * things.
+	 */
+	if ((enc->enc_flags & ENC_FLAG_INITIALIZED) == 0) {
+		cam_periph_unlock(periph);
+		return (ENXIO);
+	}
+	cam_periph_unlock(periph);
+
+	error = 0;
+
+	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
+	    ("trying to do ioctl %#lx\n", cmd));
+
+	/*
+	 * If this command can change the device's state,
+	 * we must have the device open for writing.
+	 *
+	 * For commands that get information about the
+	 * device- we don't need to lock the peripheral
+	 * if we aren't running a command.  The periph
+	 * also can't go away while a user process has
+	 * it open.
+	 */
+	switch (cmd) {
+	case ENCIOC_GETNELM:
+	case ENCIOC_GETELMMAP:
+	case ENCIOC_GETENCSTAT:
+	case ENCIOC_GETELMSTAT:
+	case ENCIOC_GETELMDESC:
+	case ENCIOC_GETELMDEVNAMES:
+		break;
+	default:
+		if ((flag & FWRITE) == 0) {
+			return (EBADF);
+		}
+	}
+ 
+	/*
+	 * XXX The values read here are only valid for the current
+	 *     configuration generation.  We need these ioctls
+	 *     to also pass in/out a generation number.
+	 */
+	sx_slock(&enc->enc_cache_lock);
+	switch (cmd) {
+	case ENCIOC_GETNELM:
+		error = copyout(&cache->nelms, addr, sizeof (cache->nelms));
+		break;
+		
+	case ENCIOC_GETELMMAP:
+		for (uelm = addr, i = 0; i != cache->nelms; i++) {
+			encioc_element_t kelm;
+			kelm.elm_idx = i;
+			kelm.elm_subenc_id = cache->elm_map[i].subenclosure;
+			kelm.elm_type = cache->elm_map[i].enctype;
+			error = copyout(&kelm, &uelm[i], sizeof(kelm));
+			if (error)
+				break;
+		}
+		break;
+
+	case ENCIOC_GETENCSTAT:
+		cam_periph_lock(periph);
+		error = enc->enc_vec.get_enc_status(enc, 1);
+		if (error) {
+			cam_periph_unlock(periph);
+			break;
+		}
+		tmp = cache->enc_status & ~ENCI_SVALID;
+		cam_periph_unlock(periph);
+		error = copyout(&tmp, addr, sizeof(tmp));
+		cache->enc_status = tmp;
+		break;
+
+	case ENCIOC_SETENCSTAT:
+		error = copyin(addr, &tmp, sizeof(tmp));
+		if (error)
+			break;
+		cam_periph_lock(periph);
+		error = enc->enc_vec.set_enc_status(enc, tmp, 1);
+		cam_periph_unlock(periph);
+		break;
+
+	case ENCIOC_GETSTRING:
+	case ENCIOC_SETSTRING:
+		if (enc->enc_vec.handle_string == NULL) {
+			error = EINVAL;
+			break;
+		}
+		error = copyin(addr, &sstr, sizeof(sstr));
+		if (error)
+			break;
+		cam_periph_lock(periph);
+		error = enc->enc_vec.handle_string(enc, &sstr, cmd);
+		cam_periph_unlock(periph);
+		break;
+
+	case ENCIOC_GETELMSTAT:
+		error = copyin(addr, &elms, sizeof(elms));
+		if (error)
+			break;
+		if (elms.elm_idx >= cache->nelms) {
+			error = EINVAL;
+			break;
+		}
+		cam_periph_lock(periph);
+		error = enc->enc_vec.get_elm_status(enc, &elms, 1);
+		cam_periph_unlock(periph);
+		if (error)
+			break;
+		error = copyout(&elms, addr, sizeof(elms));
+		break;
+

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



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