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@
This commit is contained in:
parent
56b555c863
commit
b0be1b67cd
@ -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.
|
.\" Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
@ -224,6 +224,28 @@ Set the highest speed that the optical drive should use for reading
|
|||||||
data.
|
data.
|
||||||
The units are multiples of a single speed CDROM (150 KB/s).
|
The units are multiples of a single speed CDROM (150 KB/s).
|
||||||
Specify 0 to use the drive's fastest speed.
|
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
|
.Sh BUS COMMANDS
|
||||||
The following commands are supported for SCSI busses:
|
The following commands are supported for SCSI busses:
|
||||||
.Pp
|
.Pp
|
||||||
|
@ -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.
|
* Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
|
||||||
@ -36,7 +36,7 @@
|
|||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -91,6 +91,8 @@ static void device_getcache(int, char *[]);
|
|||||||
static void device_setcache(int, char *[]);
|
static void device_setcache(int, char *[]);
|
||||||
static void device_flushcache(int, char *[]);
|
static void device_flushcache(int, char *[]);
|
||||||
static void device_setspeed(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[] = {
|
static struct command device_commands[] = {
|
||||||
{ "defects", "[primary] [grown] [block|byte|physical]",
|
{ "defects", "[primary] [grown] [block|byte|physical]",
|
||||||
@ -111,6 +113,8 @@ static struct command device_commands[] = {
|
|||||||
{ "setcache", "none|r|w|rw [save]", device_setcache },
|
{ "setcache", "none|r|w|rw [save]", device_setcache },
|
||||||
{ "flushcache", "", device_flushcache },
|
{ "flushcache", "", device_flushcache },
|
||||||
{ "setspeed", "[speed]", device_setspeed },
|
{ "setspeed", "[speed]", device_setspeed },
|
||||||
|
{ "getrealloc", "", device_getrealloc },
|
||||||
|
{ "setrealloc", "none|r|w|rw [save]", device_setrealloc },
|
||||||
{ NULL, NULL, NULL },
|
{ NULL, NULL, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -980,6 +984,93 @@ device_setspeed(int argc, char *argv[])
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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:
|
* device_prevent:
|
||||||
*
|
*
|
||||||
|
@ -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
|
* SCSI-specific interface description
|
||||||
@ -236,6 +236,27 @@ struct scsi_read_defect_data_data {
|
|||||||
|
|
||||||
union scsi_disk_pages {
|
union scsi_disk_pages {
|
||||||
#define DISK_PGCODE 0x3F /* only 6 bits valid */
|
#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 {
|
struct page_disk_format {
|
||||||
u_int8_t pg_code; /* page code (should be 3) */
|
u_int8_t pg_code; /* page code (should be 3) */
|
||||||
u_int8_t pg_length; /* page length (should be 0x16) */
|
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_RMB 0x20
|
||||||
#define DISK_FMT_HSEC 0x40
|
#define DISK_FMT_HSEC 0x40
|
||||||
#define DISK_FMT_SSEC 0x80
|
#define DISK_FMT_SSEC 0x80
|
||||||
|
u_int8_t reserved1;
|
||||||
u_int8_t reserved2;
|
u_int8_t reserved2;
|
||||||
u_int8_t reserved3;
|
u_int8_t reserved3;
|
||||||
} disk_format;
|
} 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_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 pin_4_1; /* pin 4 (8/9) pin 1 (13) definition */
|
||||||
u_int8_t rpm[2]; /* rotational rate */
|
u_int8_t rpm[2]; /* rotational rate */
|
||||||
u_int8_t reserved3;
|
u_int8_t reserved1;
|
||||||
u_int8_t reserved4;
|
u_int8_t reserved2;
|
||||||
} flex_geometry;
|
} flex_geometry;
|
||||||
struct page_caching {
|
struct page_caching {
|
||||||
u_int8_t pg_code; /* page code (should be 8) */
|
u_int8_t pg_code; /* page code (should be 8) */
|
||||||
|
Loading…
Reference in New Issue
Block a user