svn commit: r310174 - in stable/11: sbin/camcontrol sys/cam/scsi

Kenneth D. Merry ken at FreeBSD.org
Fri Dec 16 20:24:49 UTC 2016


Author: ken
Date: Fri Dec 16 20:24:47 2016
New Revision: 310174
URL: https://svnweb.freebsd.org/changeset/base/310174

Log:
  MFC r309374, r309513, r309839, r309840:
  
    ------------------------------------------------------------------------
    r309374 | ken | 2016-12-01 15:20:27 -0700 (Thu, 01 Dec 2016) | 41 lines
  
    Add SCSI REPORT TIMESTAMP and SET TIMESTAMP support.
  
    This adds support to camcontrol(8) and libcam(3) for getting and setting
    the time on SCSI protocol drives.  This is more commonly found on tape
    drives, but is a SPC (SCSI Primary Commands) command, and may be found
    on any device that speaks SCSI.
  
    The new camcontrol timestamp subcommand allows getting the current device
    time or setting the time to the current system time or any arbitrary time.
  
    sbin/camcontrol/Makefile:
    	Add timestamp.c.
  
    sbin/camcontrol/camcontrol.8:
    	Document the new timestamp subcommand.
  
    sbin/camcontrol/camcontrol.c:
    	Add the timestamp subcommand to camcontrol.
  
    sbin/camcontrol/camcontrol.h:
    	Add the timestamp() function prototype.
  
    sbin/camcontrol/timestamp.c:
    	Timestamp setting and reporting functionality.
  
    sys/cam/scsi/scsi_all.c:
    	Add two new CCB building functions, scsi_set_timestamp() and
    	scsi_report_timestamp().  Also, add a new helper function,
    	scsi_create_timestamp().
  
    sys/cam/scsi/scsi_all.h:
    	Add CDB and parameter data for the the set and report timestamp
    	commands.
  
    	Add function declarations for the new CCB building and helper
    	functions.
  
    Submitted by:	Sam Klopsch
    Sponsored by:	Spectra Logic
  
    ------------------------------------------------------------------------
    r309513 | adrian | 2016-12-03 13:35:39 -0700 (Sat, 03 Dec 2016) | 7 lines
  
    [camcontrol] init ts=0 to quieten gcc.
  
    It "looks" like ts is set to something on success, and not modified on
    error.
  
    Checked on IRC with: cem
  
    ------------------------------------------------------------------------
    r309839 | ngie | 2016-12-10 16:26:34 -0700 (Sat, 10 Dec 2016) | 6 lines
  
    free/NULL out variables prior to calling strdup to avoid leaking memory
    if arguments are specified more than once with "camcontrol timestamp".
  
    CID:		1366829, 1366831
  
    ------------------------------------------------------------------------
    r309840 | ngie | 2016-12-10 16:58:14 -0700 (Sat, 10 Dec 2016) | 8 lines
  
    Cut to the chase and just call free instead of free(x) + x = NULL
  
    NULLing out x wasn't required as the memory was immediately scribbled
    over with strdup in the following call.
  
    Submitted by:	imp
  
    ------------------------------------------------------------------------

Added:
  stable/11/sbin/camcontrol/timestamp.c
     - copied, changed from r309374, head/sbin/camcontrol/timestamp.c
Modified:
  stable/11/sbin/camcontrol/Makefile
  stable/11/sbin/camcontrol/camcontrol.8
  stable/11/sbin/camcontrol/camcontrol.c
  stable/11/sbin/camcontrol/camcontrol.h
  stable/11/sys/cam/scsi/scsi_all.c
  stable/11/sys/cam/scsi/scsi_all.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sbin/camcontrol/Makefile
==============================================================================
--- stable/11/sbin/camcontrol/Makefile	Fri Dec 16 20:10:55 2016	(r310173)
+++ stable/11/sbin/camcontrol/Makefile	Fri Dec 16 20:24:47 2016	(r310174)
@@ -4,7 +4,7 @@ PACKAGE=runtime
 PROG=	camcontrol
 SRCS=	camcontrol.c util.c
 .if !defined(RELEASE_CRUNCH)
-SRCS+=	attrib.c epc.c fwdownload.c modeedit.c persist.c progress.c zone.c
+SRCS+=	attrib.c epc.c fwdownload.c modeedit.c persist.c progress.c timestamp.c zone.c
 .else
 CFLAGS+= -DMINIMALISTIC
 .endif

Modified: stable/11/sbin/camcontrol/camcontrol.8
==============================================================================
--- stable/11/sbin/camcontrol/camcontrol.8	Fri Dec 16 20:10:55 2016	(r310173)
+++ stable/11/sbin/camcontrol/camcontrol.8	Fri Dec 16 20:24:47 2016	(r310174)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 16, 2016
+.Dd November 30, 2016
 .Dt CAMCONTROL 8
 .Os
 .Sh NAME
@@ -343,6 +343,11 @@
 .Op Fl S Ar power_src
 .Op Fl T Ar timer
 .Nm
+.Ic timestamp
+.Op device id
+.Op generic args
+.Ao Fl r Oo Ns Fl f Ar format | Fl m | Fl U Oc | Fl s Ao Fl f Ar format Fl T Ar time | Fl U Ac Ac
+.Nm
 .Ic help
 .Sh DESCRIPTION
 The
@@ -2417,6 +2422,54 @@ supports, and a number of parameters abo
 whether it is enabled and what the timer value is.
 .El
 .El
+.It Ic timestamp
+Issue REPORT TIMESTAMP or SET TIMESTAMP
+.Tn SCSI
+commands. Either the
+.Fl r
+option or the
+.Fl s
+option must be specified.
+.Bl -tag -width 6n
+.It Fl r
+Report the device's timestamp.
+If no more arguments are specified, the timestamp will be reported using
+the national representation of the date and time, followed by the time
+zone.
+.Bl -tag -width 9n
+.It Fl f Ar format
+Specify the strftime format string, as documented in strftime(3), to be used
+to format the reported timestamp.
+.It Fl m
+Report the timestamp as milliseconds since the epoch.
+.It Fl U
+Report the timestamp using the national representation of the date and
+time, but override the system time zone and use UTC instead.
+.El
+.El
+.Bl -tag -width 6n
+.It Fl s
+Set the device's timestamp. Either the
+.Fl f
+and 
+.Fl T
+options or the
+.Fl U
+option must be specified.
+.Bl -tag -width 9n
+.It Fl f Ar format
+Specify the strptime format string, as documented in strptime(3).
+The time must also be specified with the
+.Fl T 
+option.
+.It Fl T
+Provide the time in the format specified with the
+.Fl f
+option.
+.It Fl U
+Set the timestamp to the host system's time in UTC.
+.El
+.El
 .It Ic help
 Print out verbose usage information.
 .El
@@ -2730,6 +2783,18 @@ camcontrol epc ada0 -c list
 Display the ATA Power Conditions log (Log Address 0x08) for
 drive
 .Pa ada0 .
+.Pp
+.Bd -literal -offset indent
+camcontrol timestamp sa0 -s -f "%A %c" \e
+	-T "Wednesday Wed Oct 26 21:43:57 2016"
+.Ed
+.Pp
+Set the timestamp of drive
+.Pa sa0
+using a
+.Xr strptime 3 
+format string followed by a time string
+that was created using this format string.
 .Sh SEE ALSO
 .Xr cam 3 ,
 .Xr cam_cdbparse 3 ,

Modified: stable/11/sbin/camcontrol/camcontrol.c
==============================================================================
--- stable/11/sbin/camcontrol/camcontrol.c	Fri Dec 16 20:10:55 2016	(r310173)
+++ stable/11/sbin/camcontrol/camcontrol.c	Fri Dec 16 20:24:47 2016	(r310174)
@@ -103,7 +103,8 @@ typedef enum {
 	CAM_CMD_OPCODES		= 0x00000024,
 	CAM_CMD_REPROBE		= 0x00000025,
 	CAM_CMD_ZONE		= 0x00000026,
-	CAM_CMD_EPC		= 0x00000027
+	CAM_CMD_EPC		= 0x00000027,
+	CAM_CMD_TIMESTAMP	= 0x00000028
 } cam_cmdmask;
 
 typedef enum {
@@ -234,6 +235,7 @@ static struct camcontrol_opts option_tab
 	{"opcodes", CAM_CMD_OPCODES, CAM_ARG_NONE, "No:s:T"},
 	{"zone", CAM_CMD_ZONE, CAM_ARG_NONE, "ac:l:No:P:"},
 	{"epc", CAM_CMD_EPC, CAM_ARG_NONE, "c:dDeHp:Pr:sS:T:"},
+	{"timestamp", CAM_CMD_TIMESTAMP, CAM_ARG_NONE, "f:mrsUT:"},
 #endif /* MINIMALISTIC */
 	{"help", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
 	{"-?", CAM_CMD_USAGE, CAM_ARG_NONE, NULL},
@@ -8922,6 +8924,9 @@ usage(int printlong)
 "        camcontrol epc        [dev_id][generic_args]<-c cmd> [-d] [-D] [-e]\n"
 "                              [-H] [-p power_cond] [-P] [-r rst_src] [-s]\n"
 "                              [-S power_src] [-T timer]\n"
+"        camcontrol timestamp  [dev_id][generic_args] <-r [-f format|-m|-U]>|\n"
+"                              <-s <-f format -T time | -U >>\n"
+"                              \n"
 #endif /* MINIMALISTIC */
 "        camcontrol help\n");
 	if (!printlong)
@@ -8966,6 +8971,7 @@ usage(int printlong)
 "opcodes     send the SCSI REPORT SUPPORTED OPCODES command\n"
 "zone        manage Zoned Block (Shingled) devices\n"
 "epc         send ATA Extended Power Conditions commands\n"
+"timestamp   report or set the device's timestamp\n"
 "help        this message\n"
 "Device Identifiers:\n"
 "bus:target        specify the bus and target, lun defaults to 0\n"
@@ -9157,6 +9163,17 @@ usage(int printlong)
 "-s                save mode (timer, state, restore)\n"
 "-S power_src      set power source: battery, nonbattery (source)\n"
 "-T timer          set timer, seconds, .1 sec resolution (timer)\n"
+"timestamp arguments:\n"
+"-r                report the timestamp of the device\n"
+"-f format         report the timestamp of the device with the given\n"
+"                  strftime(3) format string\n"
+"-m                report the timestamp of the device as milliseconds since\n"
+"                  January 1st, 1970\n"
+"-U                report the time with UTC instead of the local time zone\n"
+"-s                set the timestamp of the device\n"
+"-f format         the format of the time string passed into strptime(3)\n"
+"-T time           the time value passed into strptime(3)\n"
+"-U                set the timestamp of the device to UTC time\n"
 );
 #endif /* MINIMALISTIC */
 }
@@ -9520,6 +9537,10 @@ main(int argc, char **argv)
 			error = epc(cam_dev, argc, argv, combinedopt,
 			    retry_count, timeout, arglist & CAM_ARG_VERBOSE);
 			break;
+		case CAM_CMD_TIMESTAMP:
+			error = timestamp(cam_dev, argc, argv, combinedopt,
+			    retry_count, timeout, arglist & CAM_ARG_VERBOSE);
+			break;
 #endif /* MINIMALISTIC */
 		case CAM_CMD_USAGE:
 			usage(1);

Modified: stable/11/sbin/camcontrol/camcontrol.h
==============================================================================
--- stable/11/sbin/camcontrol/camcontrol.h	Fri Dec 16 20:10:55 2016	(r310173)
+++ stable/11/sbin/camcontrol/camcontrol.h	Fri Dec 16 20:24:47 2016	(r310174)
@@ -81,6 +81,9 @@ int zone(struct cam_device *device, int 
 	 int retry_count, int timeout, int verbosemode);
 int epc(struct cam_device *device, int argc, char **argv, char *combinedopt,
 	int retry_count, int timeout, int verbosemode);
+int timestamp(struct cam_device *device, int argc, char **argv,
+	      char *combinedopt, int retry_count, int timeout,
+	      int verbosemode);
 void mode_sense(struct cam_device *device, int mode_page, int page_control,
 		int dbd, int retry_count, int timeout, u_int8_t *data,
 		int datalen);

Copied and modified: stable/11/sbin/camcontrol/timestamp.c (from r309374, head/sbin/camcontrol/timestamp.c)
==============================================================================
--- head/sbin/camcontrol/timestamp.c	Thu Dec  1 22:20:27 2016	(r309374, copy source)
+++ stable/11/sbin/camcontrol/timestamp.c	Fri Dec 16 20:24:47 2016	(r310174)
@@ -328,7 +328,7 @@ timestamp(struct cam_device *device, int
 	  int retry_count, int timeout, int verbosemode __unused)
 {
 	int c;
-	uint64_t ts;
+	uint64_t ts = 0;
 	char *format_string = NULL;
 	char *timestamp_string = NULL;
 	int action = -1;
@@ -358,6 +358,7 @@ timestamp(struct cam_device *device, int
 		}
 		case 'f': {
 			single_arg++;
+			free(format_string);
 			format_string = strdup(optarg);
 			if (format_string == NULL) {
 				warn("Error allocating memory for format "
@@ -369,6 +370,7 @@ timestamp(struct cam_device *device, int
 		}
 		case 'm': {
 			single_arg++;
+			free(format_string);
 			format_string = strdup(MIL);
 			if (format_string == NULL) {
 				warn("Error allocating memory");
@@ -382,6 +384,7 @@ timestamp(struct cam_device *device, int
 			break;
 		}
 		case 'T':
+			free(timestamp_string);
 			timestamp_string = strdup(optarg);
 			if (timestamp_string == NULL) {
 				warn("Error allocating memory for format "

Modified: stable/11/sys/cam/scsi/scsi_all.c
==============================================================================
--- stable/11/sys/cam/scsi/scsi_all.c	Fri Dec 16 20:10:55 2016	(r310173)
+++ stable/11/sys/cam/scsi/scsi_all.c	Fri Dec 16 20:24:47 2016	(r310174)
@@ -7947,6 +7947,32 @@ scsi_report_target_group(struct ccb_scsi
 }
 
 void
+scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+		 void (*cbfcnp)(struct cam_periph *, union ccb *),
+		 u_int8_t tag_action, u_int8_t pdf,
+		 void *buf, u_int32_t alloc_len,
+		 u_int8_t sense_len, u_int32_t timeout)
+{
+	struct scsi_timestamp *scsi_cmd;
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_IN,
+		      tag_action,
+		      /*data_ptr*/(u_int8_t *)buf,
+		      /*dxfer_len*/alloc_len,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+	scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
+	bzero(scsi_cmd, sizeof(*scsi_cmd));
+	scsi_cmd->opcode = MAINTENANCE_IN;
+	scsi_cmd->service_action = REPORT_TIMESTAMP | pdf;
+	scsi_ulto4b(alloc_len, scsi_cmd->length);
+}
+
+void
 scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 		 void (*cbfcnp)(struct cam_periph *, union ccb *),
 		 u_int8_t tag_action, void *buf, u_int32_t alloc_len,
@@ -7971,6 +7997,45 @@ scsi_set_target_group(struct ccb_scsiio 
 	scsi_ulto4b(alloc_len, scsi_cmd->length);
 }
 
+void
+scsi_create_timestamp(uint8_t *timestamp_6b_buf,
+		      uint64_t timestamp)
+{
+	uint8_t buf[8];
+	scsi_u64to8b(timestamp, buf);
+	/*
+	 * Using memcopy starting at buf[2] because the set timestamp parameters
+	 * only has six bytes for the timestamp to fit into, and we don't have a
+	 * scsi_u64to6b function.
+	 */
+	memcpy(timestamp_6b_buf, &buf[2], 6);
+}
+
+void
+scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+		   void (*cbfcnp)(struct cam_periph *, union ccb *),
+		   u_int8_t tag_action, void *buf, u_int32_t alloc_len,
+		   u_int8_t sense_len, u_int32_t timeout)
+{
+	struct scsi_timestamp *scsi_cmd;
+
+	cam_fill_csio(csio,
+		      retries,
+		      cbfcnp,
+		      /*flags*/CAM_DIR_OUT,
+		      tag_action,
+		      /*data_ptr*/(u_int8_t *) buf,
+		      /*dxfer_len*/alloc_len,
+		      sense_len,
+		      sizeof(*scsi_cmd),
+		      timeout);
+	scsi_cmd = (struct scsi_timestamp *)&csio->cdb_io.cdb_bytes;
+	bzero(scsi_cmd, sizeof(*scsi_cmd));
+	scsi_cmd->opcode = MAINTENANCE_OUT;
+	scsi_cmd->service_action = SET_TIMESTAMP;
+	scsi_ulto4b(alloc_len, scsi_cmd->length);
+}
+
 /*
  * Syncronize the media to the contents of the cache for
  * the given lba/count pair.  Specifying 0/0 means sync

Modified: stable/11/sys/cam/scsi/scsi_all.h
==============================================================================
--- stable/11/sys/cam/scsi/scsi_all.h	Fri Dec 16 20:10:55 2016	(r310173)
+++ stable/11/sys/cam/scsi/scsi_all.h	Fri Dec 16 20:24:47 2016	(r310174)
@@ -702,7 +702,9 @@ struct scsi_control_page {
 
 struct scsi_control_ext_page {
 	uint8_t page_code;
+#define SCEP_PAGE_CODE			0x0a
 	uint8_t subpage_code;
+#define SCEP_SUBPAGE_CODE		0x01
 	uint8_t page_length[2];
 	uint8_t flags;
 #define	SCEP_TCMOS			0x04	/* Timestamp Changeable by */
@@ -2971,6 +2973,31 @@ struct scsi_target_group
 	uint8_t control;
 };
 
+struct scsi_timestamp
+{
+	uint8_t opcode;
+	uint8_t service_action;
+	uint8_t reserved1[4];
+	uint8_t length[4];
+	uint8_t reserved2;
+	uint8_t control;
+};
+
+struct scsi_set_timestamp_parameters
+{
+	uint8_t reserved1[4];
+	uint8_t timestamp[6];
+	uint8_t reserved2[4];
+};
+
+struct scsi_report_timestamp_parameter_data
+{
+	uint8_t length[2];
+	uint8_t reserved1[2];
+	uint8_t timestamp[6];
+	uint8_t reserved2[2];
+};
+
 struct scsi_target_port_descriptor {
 	uint8_t	reserved[2];
 	uint8_t	relative_target_port_identifier[2];
@@ -3966,12 +3993,29 @@ void		scsi_report_target_group(struct cc
 				 u_int32_t alloc_len, u_int8_t sense_len,
 				 u_int32_t timeout);
 
+void		scsi_report_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+				 void (*cbfcnp)(struct cam_periph *, 
+				 union ccb *), u_int8_t tag_action, 
+				 u_int8_t pdf,
+				 void *buf,
+				 u_int32_t alloc_len, u_int8_t sense_len,
+				 u_int32_t timeout);
+
 void		scsi_set_target_group(struct ccb_scsiio *csio, u_int32_t retries,
 				 void (*cbfcnp)(struct cam_periph *, 
 				 union ccb *), u_int8_t tag_action, void *buf,
 				 u_int32_t alloc_len, u_int8_t sense_len,
 				 u_int32_t timeout);
 
+void		scsi_create_timestamp(uint8_t *timestamp_6b_buf,
+				      uint64_t timestamp);
+
+void		scsi_set_timestamp(struct ccb_scsiio *csio, u_int32_t retries,
+				   void (*cbfcnp)(struct cam_periph *, 
+				   union ccb *), u_int8_t tag_action,
+				   void *buf, u_int32_t alloc_len,
+				   u_int8_t sense_len, u_int32_t timeout);
+
 void		scsi_synchronize_cache(struct ccb_scsiio *csio, 
 				       u_int32_t retries,
 				       void (*cbfcnp)(struct cam_periph *, 


More information about the svn-src-stable-11 mailing list