Module Name:    src
Committed By:   flxd
Date:           Sat Nov 19 08:43:40 UTC 2016

Modified Files:
        src/sbin/scsictl: scsictl.8 scsictl.c
        src/sys/dev/scsipi: scsi_disk.h

Log Message:
Add "getrealloc" and "setrealloc" commands to get/set automatic reallocation
parameters/enables for error recovery, similar to {get,set}cache.
Many old SCSI disks shipped with reallocation disabled, albeit supporting it.
Minor (cosmetic) fixup of scsi_disk_pages while there.
Based upon code in PR bin/29165 by Greg A. Woods.
OK christos@


To generate a diff of this commit:
cvs rdiff -u -r1.26 -r1.27 src/sbin/scsictl/scsictl.8
cvs rdiff -u -r1.38 -r1.39 src/sbin/scsictl/scsictl.c
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/scsipi/scsi_disk.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/scsictl/scsictl.8
diff -u src/sbin/scsictl/scsictl.8:1.26 src/sbin/scsictl/scsictl.8:1.27
--- src/sbin/scsictl/scsictl.8:1.26	Fri Mar 29 21:46:32 2013
+++ src/sbin/scsictl/scsictl.8	Sat Nov 19 08:43:40 2016
@@ -1,4 +1,4 @@
-.\"	$NetBSD: scsictl.8,v 1.26 2013/03/29 21:46:32 christos Exp $
+.\"	$NetBSD: scsictl.8,v 1.27 2016/11/19 08:43:40 flxd Exp $
 .\"
 .\" Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -224,6 +224,28 @@ Set the highest speed that the optical d
 data.
 The units are multiples of a single speed CDROM (150 KB/s).
 Specify 0 to use the drive's fastest speed.
+.Pp
+.Nm getrealloc
+.Pp
+Returns automatic reallocation parameters for the device.
+.Pp
+.Nm setrealloc
+.Ar none|r|w|rw
+.Op Ar save
+.Pp
+Set automatic reallocation parameters for the device.
+Automatic reallocation may be disabled
+.Pq none ,
+the automatic read reallocation enabled
+.Pq r ,
+the automatic write reallocation enabled
+.Pq w ,
+or both automatic read and write reallocation enabled
+.Pq rw .
+If the drive's automatic reallocation parameters are savable, specifying
+.Ar save
+after the automatic reallocation enable state will cause the parameters to be
+saved in non-volatile storage.
 .Sh BUS COMMANDS
 The following commands are supported for SCSI busses:
 .Pp

Index: src/sbin/scsictl/scsictl.c
diff -u src/sbin/scsictl/scsictl.c:1.38 src/sbin/scsictl/scsictl.c:1.39
--- src/sbin/scsictl/scsictl.c:1.38	Sat Oct 18 08:33:24 2014
+++ src/sbin/scsictl/scsictl.c	Sat Nov 19 08:43:40 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsictl.c,v 1.38 2014/10/18 08:33:24 snj Exp $	*/
+/*	$NetBSD: scsictl.c,v 1.39 2016/11/19 08:43:40 flxd Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: scsictl.c,v 1.38 2014/10/18 08:33:24 snj Exp $");
+__RCSID("$NetBSD: scsictl.c,v 1.39 2016/11/19 08:43:40 flxd Exp $");
 #endif
 
 
@@ -91,6 +91,8 @@ static void	device_getcache(int, char *[
 static void	device_setcache(int, char *[]);
 static void	device_flushcache(int, char *[]);
 static void	device_setspeed(int, char *[]);
+static void	device_getrealloc(int, char *[]);
+static void	device_setrealloc(int, char *[]);
 
 static struct command device_commands[] = {
 	{ "defects",	"[primary] [grown] [block|byte|physical]",
@@ -111,6 +113,8 @@ static struct command device_commands[] 
 	{ "setcache",	"none|r|w|rw [save]",	device_setcache },
 	{ "flushcache",	"",			device_flushcache },
 	{ "setspeed",	"[speed]",		device_setspeed },
+	{ "getrealloc",	"",			device_getrealloc },
+	{ "setrealloc",	"none|r|w|rw [save]",	device_setrealloc },
 	{ NULL,		NULL,			NULL },
 };
 
@@ -981,6 +985,93 @@ device_setspeed(int argc, char *argv[])
 }
 
 /*
+ * device_getrealloc:
+ *
+ *	Get the automatic reallocation parameters for a SCSI disk.
+ */
+static void
+device_getrealloc(int argc, char *argv[])
+{
+	struct {
+		struct scsi_mode_parameter_header_6 header;
+		struct scsi_general_block_descriptor blk_desc;
+		struct page_err_recov err_recov_params;
+	} data;
+	u_int8_t flags;
+
+	/* No arguments. */
+	if (argc != 0)
+		usage();
+
+	scsi_mode_sense(fd, 0x01, 0x00, &data, sizeof(data));
+
+	flags = data.err_recov_params.flags;
+	if ((flags & (ERR_RECOV_ARRE | ERR_RECOV_AWRE)) == 0)
+		printf("%s: no automatic reallocation enabled\n", dvname);
+	else {
+		printf("%s: automatic read reallocation %senabled\n", dvname,
+		    (flags & ERR_RECOV_ARRE) ? "" : "not ");
+		printf("%s: automatic write reallocation %senabled\n", dvname,
+		    (flags & ERR_RECOV_AWRE) ? "" : "not ");
+	}
+	printf("%s: error recovery parameters are %ssavable\n", dvname,
+	    (data.err_recov_params.pg_code & PGCODE_PS) ? "" : "not ");
+}
+
+/*
+ * device_setrealloc:
+ *
+ *	Set the automatic reallocation parameters for a SCSI disk.
+ */
+static void
+device_setrealloc(int argc, char *argv[])
+{
+	struct {
+		struct scsi_mode_parameter_header_6 header;
+		struct scsi_general_block_descriptor blk_desc;
+		struct page_err_recov err_recov_params;
+	} data;
+	int dlen;
+	u_int8_t flags, byte2;
+
+	if (argc > 2 || argc == 0)
+		usage();
+
+	flags = 0;
+	byte2 = 0;
+	if (strcmp(argv[0], "none") == 0)
+		flags = 0;
+	else if (strcmp(argv[0], "r") == 0)
+		flags = ERR_RECOV_ARRE;
+	else if (strcmp(argv[0], "w") == 0)
+		flags = ERR_RECOV_AWRE;
+	else if (strcmp(argv[0], "rw") == 0)
+		flags = ERR_RECOV_ARRE | ERR_RECOV_AWRE;
+	else
+		usage();
+
+	if (argc == 2) {
+		if (strcmp(argv[1], "save") == 0)
+			byte2 = SMS_SP;
+		else
+			usage();
+	}
+
+	scsi_mode_sense(fd, 0x01, 0x00, &data, sizeof(data));
+
+	data.err_recov_params.pg_code &= PGCODE_MASK;
+	data.err_recov_params.flags &= ~(ERR_RECOV_ARRE | ERR_RECOV_AWRE);
+	data.err_recov_params.flags |= flags;
+
+	data.header.data_length = 0;
+
+	dlen = sizeof(data.header) + sizeof(data.blk_desc) + 2 +
+	    data.err_recov_params.pg_length;
+
+	scsi_mode_select(fd, byte2, &data, dlen);
+}
+
+/*
  * device_prevent:
  *
  *      Issue a prevent to a SCSI device.

Index: src/sys/dev/scsipi/scsi_disk.h
diff -u src/sys/dev/scsipi/scsi_disk.h:1.31 src/sys/dev/scsipi/scsi_disk.h:1.32
--- src/sys/dev/scsipi/scsi_disk.h:1.31	Sun Dec 11 12:23:50 2005
+++ src/sys/dev/scsipi/scsi_disk.h	Sat Nov 19 08:43:40 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsi_disk.h,v 1.31 2005/12/11 12:23:50 christos Exp $	*/
+/*	$NetBSD: scsi_disk.h,v 1.32 2016/11/19 08:43:40 flxd Exp $	*/
 
 /*
  * SCSI-specific interface description
@@ -236,6 +236,27 @@ struct scsi_read_defect_data_data {
 
 union scsi_disk_pages {
 #define	DISK_PGCODE	0x3F	/* only 6 bits valid */
+	struct page_err_recov {
+		u_int8_t pg_code;	/* page code (should be 1) */
+		u_int8_t pg_length;	/* page length (should be 0x0a) */
+		u_int8_t flags;		/* error recovery flags */
+#define	ERR_RECOV_DCR	0x01		/* disable correction */
+#define	ERR_RECOV_DTE	0x02		/* disable transfer on error */
+#define	ERR_RECOV_PER	0x04		/* post error */
+#define	ERR_RECOV_EER	0x08		/* enable early recovery */
+#define	ERR_RECOV_RC	0x10		/* read continuous */
+#define	ERR_RECOV_TB	0x20		/* transfer block */
+#define	ERR_RECOV_ARRE	0x40		/* autom. read reallocation enable */
+#define	ERR_RECOV_AWRE	0x80		/* autom. write reallocation enable */
+		u_int8_t rd_retry_ct;	/* read retry count */
+		u_int8_t corr_span;	/* correction span */
+		u_int8_t hd_off_ct;	/* head offset count */
+		u_int8_t dat_strb_off_ct; /* data strobe offset count */
+		u_int8_t reserved1;
+		u_int8_t wr_retry_ct;	/* write retry count */
+		u_int8_t reserved2;
+		u_int8_t recov_tm_lim[2]; /* recovery time limit */
+	} err_recov_params;
 	struct page_disk_format {
 		u_int8_t pg_code;	/* page code (should be 3) */
 		u_int8_t pg_length;	/* page length (should be 0x16) */
@@ -253,6 +274,7 @@ union scsi_disk_pages {
 #define	DISK_FMT_RMB	0x20
 #define	DISK_FMT_HSEC	0x40
 #define	DISK_FMT_SSEC	0x80
+		u_int8_t reserved1;
 		u_int8_t reserved2;
 		u_int8_t reserved3;
 	} disk_format;
@@ -303,8 +325,8 @@ union scsi_disk_pages {
 		u_int8_t pin_34_2;	/* pin 34 (6) pin 2 (7/11) definition */
 		u_int8_t pin_4_1;	/* pin 4 (8/9) pin 1 (13) definition */
 		u_int8_t rpm[2];	/* rotational rate */
-		u_int8_t reserved3;
-		u_int8_t reserved4;
+		u_int8_t reserved1;
+		u_int8_t reserved2;
 	} flex_geometry;
 	struct page_caching {
 		u_int8_t pg_code;	/* page code (should be 8) */

Reply via email to