Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 May 2012 14:07:44 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r235911 - in head: share/examples/ses share/examples/ses/srcs sys/cam/scsi sys/conf sys/fs/devfs sys/modules/cam usr.bin/kdump
Message-ID:  <201205241407.q4OE7i47042313@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Thu May 24 14:07:44 2012
New Revision: 235911
URL: http://svn.freebsd.org/changeset/base/235911

Log:
  MFprojects/zfsd:
  Revamp the CAM enclosure services driver.
  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.
  
  Sponsored by:   Spectra Logic Corporation
  Sponsored by:   iXsystems, Inc.
  Submitted by:   gibbs, will, mav

Added:
  head/sys/cam/scsi/scsi_enc.c   (contents, props changed)
  head/sys/cam/scsi/scsi_enc.h   (contents, props changed)
  head/sys/cam/scsi/scsi_enc_internal.h   (contents, props changed)
  head/sys/cam/scsi/scsi_enc_safte.c   (contents, props changed)
  head/sys/cam/scsi/scsi_enc_ses.c   (contents, props changed)
Deleted:
  head/sys/cam/scsi/scsi_ses.c
Modified:
  head/share/examples/ses/Makefile.inc
  head/share/examples/ses/srcs/eltsub.c
  head/share/examples/ses/srcs/getencstat.c
  head/share/examples/ses/srcs/getnobj.c
  head/share/examples/ses/srcs/getobjmap.c
  head/share/examples/ses/srcs/getobjstat.c
  head/share/examples/ses/srcs/inienc.c
  head/share/examples/ses/srcs/sesd.c
  head/share/examples/ses/srcs/setencstat.c
  head/share/examples/ses/srcs/setobjstat.c
  head/sys/cam/scsi/scsi_ses.h
  head/sys/conf/files
  head/sys/fs/devfs/devfs_vnops.c
  head/sys/modules/cam/Makefile
  head/usr.bin/kdump/mkioctls

Modified: head/share/examples/ses/Makefile.inc
==============================================================================
--- head/share/examples/ses/Makefile.inc	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/Makefile.inc	Thu May 24 14:07:44 2012	(r235911)
@@ -32,7 +32,6 @@
 # mjacob@feral.com
 #
 
-CFLAGS+= -I/usr/include/cam/scsi -DSESINC="<scsi_ses.h>"
 BINDIR?= /usr/sbin
 
 CLEANFILES+= ${MAN}

Modified: head/share/examples/ses/srcs/eltsub.c
==============================================================================
--- head/share/examples/ses/srcs/eltsub.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/eltsub.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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,79 +49,82 @@ geteltnm(int type)
 	static char rbuf[132];
 
 	switch (type) {
-	case SESTYP_UNSPECIFIED:
+	case ELMTYP_UNSPECIFIED:
 		sprintf(rbuf, "Unspecified");
 		break;
-	case SESTYP_DEVICE:
-		sprintf(rbuf, "Device");
+	case ELMTYP_DEVICE:
+		sprintf(rbuf, "Device Slot");
 		break;
-	case SESTYP_POWER:
-		sprintf(rbuf, "Power supply");
+	case ELMTYP_POWER:
+		sprintf(rbuf, "Power Supply");
 		break;
-	case SESTYP_FAN:
-		sprintf(rbuf, "Cooling element");
+	case ELMTYP_FAN:
+		sprintf(rbuf, "Cooling");
 		break;
-	case SESTYP_THERM:
-		sprintf(rbuf, "Temperature sensors");
+	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:
-		sprintf(rbuf, "Enclosure services controller electronics");
+	case ELMTYP_ESCC:
+		sprintf(rbuf, "Enclosure Eervices Controller Electronics");
 		break;
-	case SESTYP_SCC:
-		sprintf(rbuf, "SCC controller electronics");
+	case ELMTYP_SCC:
+		sprintf(rbuf, "SCC Controller Electronics");
 		break;
-	case SESTYP_NVRAM:
-		sprintf(rbuf, "Nonvolatile cache");
+	case ELMTYP_NVRAM:
+		sprintf(rbuf, "Nonvolatile Cache");
 		break;
-	case SESTYP_UPS:
-		sprintf(rbuf, "Uninterruptible power supply");
+	case ELMTYP_INV_OP_REASON:
+		sprintf(rbuf, "Invalid Operation Reason");
 		break;
-	case SESTYP_DISPLAY:
+	case ELMTYP_UPS:
+		sprintf(rbuf, "Uninterruptible Power Supply");
+		break;
+	case ELMTYP_DISPLAY:
 		sprintf(rbuf, "Display");
 		break;
-	case SESTYP_KEYPAD:
-		sprintf(rbuf, "Key pad entry device");
+	case ELMTYP_KEYPAD:
+		sprintf(rbuf, "Key Pad Entry");
 		break;
-	case SESTYP_ENCLOSURE:
+	case ELMTYP_ENCLOSURE:
 		sprintf(rbuf, "Enclosure");
 		break;
-	case SESTYP_SCSIXVR:
-		sprintf(rbuf, "SCSI port/transceiver");
+	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:
-		sprintf(rbuf, "SCSI target port");
+	case ELMTYP_SCSI_TGT:
+		sprintf(rbuf, "SCSI Target Port");
 		break;
-	case SESTYP_SCSI_INI:
-		sprintf(rbuf, "SCSI initiator port");
+	case ELMTYP_SCSI_INI:
+		sprintf(rbuf, "SCSI Initiator Port");
 		break;
-	case SESTYP_SUBENC:
-		sprintf(rbuf, "Simple sub-enclosure");
+	case ELMTYP_SUBENC:
+		sprintf(rbuf, "Simple Subenclosure");
 		break;
-	case SESTYP_ARRAY:
-		sprintf(rbuf, "Array device");
+	case ELMTYP_ARRAY_DEV:
+		sprintf(rbuf, "Array Device Slot");
 		break;
-	case SESTYP_SASEXPANDER:
+	case ELMTYP_SAS_EXP:
 		sprintf(rbuf, "SAS Expander");
 		break;
-	case SESTYP_SASCONNECTOR:
+	case ELMTYP_SAS_CONN:
 		sprintf(rbuf, "SAS Connector");
 		break;
 	default:
@@ -134,31 +140,34 @@ scode2ascii(u_char code)
 	static char rbuf[32];
 	switch (code & 0xf) {
 	case SES_OBJSTAT_UNSUPPORTED:
-		sprintf(rbuf, "status not supported");
+		sprintf(rbuf, "Unsupported");
 		break;
 	case SES_OBJSTAT_OK:
-		sprintf(rbuf, "ok");
+		sprintf(rbuf, "OK");
 		break;
 	case SES_OBJSTAT_CRIT:
-		sprintf(rbuf, "critical");
+		sprintf(rbuf, "Critical");
 		break;
 	case SES_OBJSTAT_NONCRIT:
-		sprintf(rbuf, "non-critical");
+		sprintf(rbuf, "Noncritical");
 		break;
 	case SES_OBJSTAT_UNRECOV:
-		sprintf(rbuf, "unrecoverable");
+		sprintf(rbuf, "Unrecoverable");
 		break;
 	case SES_OBJSTAT_NOTINSTALLED:
-		sprintf(rbuf, "not installed");
+		sprintf(rbuf, "Not Installed");
 		break;
 	case SES_OBJSTAT_UNKNOWN:
-		sprintf(rbuf, "unknown status");
+		sprintf(rbuf, "Unknown");
 		break;
 	case SES_OBJSTAT_NOTAVAIL:
-		sprintf(rbuf, "status not available");
+		sprintf(rbuf, "Not Available");
+		break;
+	case SES_OBJSTAT_NOACCESS:
+		sprintf(rbuf, "No Access Allowed");
 		break;
 	default:
-		sprintf(rbuf, "unknown status code %x", code & 0xf);
+		sprintf(rbuf, "<Status 0x%x>", code & 0xf);
 		break;
 	}
 	return (rbuf);
@@ -171,7 +180,7 @@ stat2ascii(int eletype __unused, u_char 
 	static char ebuf[256], *scode;
 
 	scode = scode2ascii(cstat[0]);
-	sprintf(ebuf, "Status=%s (bytes=0x%02x 0x%02x 0x%02x 0x%02x)",
+	sprintf(ebuf, "status: %s (0x%02x 0x%02x 0x%02x 0x%02x)",
 	    scode, cstat[0], cstat[1], cstat[2], cstat[3]);
 	return (ebuf);
 }

Modified: head/share/examples/ses/srcs/getencstat.c
==============================================================================
--- head/share/examples/ses/srcs/getencstat.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/getencstat.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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,64 @@ 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));
+			fprintf(stdout, ", %s",
+			    stat2ascii(objp[i].elm_type, ob.cstat));
+			if (objd.elm_desc_len > 0)
+				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: head/share/examples/ses/srcs/getnobj.c
==============================================================================
--- head/share/examples/ses/srcs/getnobj.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/getnobj.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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: head/share/examples/ses/srcs/getobjmap.c
==============================================================================
--- head/share/examples/ses/srcs/getobjmap.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/getobjmap.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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: head/share/examples/ses/srcs/getobjstat.c
==============================================================================
--- head/share/examples/ses/srcs/getobjstat.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/getobjstat.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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: head/share/examples/ses/srcs/inienc.c
==============================================================================
--- head/share/examples/ses/srcs/inienc.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/inienc.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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: head/share/examples/ses/srcs/sesd.c
==============================================================================
--- head/share/examples/ses/srcs/sesd.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/sesd.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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: head/share/examples/ses/srcs/setencstat.c
==============================================================================
--- head/share/examples/ses/srcs/setencstat.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/setencstat.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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: head/share/examples/ses/srcs/setobjstat.c
==============================================================================
--- head/share/examples/ses/srcs/setobjstat.c	Thu May 24 13:15:15 2012	(r235910)
+++ head/share/examples/ses/srcs/setobjstat.c	Thu May 24 14:07:44 2012	(r235911)
@@ -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);

Added: head/sys/cam/scsi/scsi_enc.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/cam/scsi/scsi_enc.c	Thu May 24 14:07:44 2012	(r235911)
@@ -0,0 +1,1011 @@
+/*-
+ * 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/sysctl.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(struct ccb_getdev *);
+
+SYSCTL_NODE(_kern_cam, OID_AUTO, enc, CTLFLAG_RD, 0,
+            "CAM Enclosure Services driver");
+
+static struct periph_driver encdriver = {
+	enc_init, "ses",
+	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 =	"ses",
+	.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;
+
+	enc->enc_flags |= ENC_FLAG_INVALID;
+
+	/* If the sub-driver has an invalidate routine, call it */
+	if (enc->enc_vec.softc_invalidate != NULL)
+		enc->enc_vec.softc_invalidate(enc);
+
+	/*
+	 * 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);
+
+	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(enc);
+
+	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;
+		path_id_t path_id;
+
+		cgd = (struct ccb_getdev *)arg;
+		if (arg == NULL) {
+			break;
+		}
+
+		if (enc_type(cgd) == ENC_NONE) {
+			/*
+			 * 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, "ses", 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)
+		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;
+
+	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;
+		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);

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



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