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) */