|
|
|
@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
|
|
|
|
|
|
|
|
|
|
#include <sys/queue.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/sbuf.h>
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include <ctype.h>
|
|
|
|
@ -96,6 +97,8 @@ static void editentry_create(void *hook, int letter, void *arg,
|
|
|
|
|
int count, char *name);
|
|
|
|
|
static void editentry_update(void *hook, int letter, void *arg,
|
|
|
|
|
int count, char *name);
|
|
|
|
|
static void editentry_create_desc(void *hook, int letter, void *arg,
|
|
|
|
|
int count, char *name);
|
|
|
|
|
static int editentry_save(void *hook, char *name);
|
|
|
|
|
static struct editentry *editentry_lookup(char *name);
|
|
|
|
|
static int editentry_set(char *name, char *newvalue,
|
|
|
|
@ -103,9 +106,16 @@ static int editentry_set(char *name, char *newvalue,
|
|
|
|
|
static void editlist_populate(struct cam_device *device,
|
|
|
|
|
int cdb_len, int dbd, int pc, int page, int subpage,
|
|
|
|
|
int task_attr, int retries, int timeout);
|
|
|
|
|
static void editlist_populate_desc(struct cam_device *device,
|
|
|
|
|
int cdb_len, int llbaa, int pc, int page,
|
|
|
|
|
int subpage, int task_attr, int retries,
|
|
|
|
|
int timeout);
|
|
|
|
|
static void editlist_save(struct cam_device *device, int cdb_len,
|
|
|
|
|
int dbd, int pc, int page, int subpage,
|
|
|
|
|
int task_attr, int retries, int timeout);
|
|
|
|
|
static void editlist_save_desc(struct cam_device *device, int cdb_len,
|
|
|
|
|
int llbaa, int pc, int page, int subpage,
|
|
|
|
|
int task_attr, int retries, int timeout);
|
|
|
|
|
static void nameentry_create(int page, int subpage, char *name);
|
|
|
|
|
static struct pagename *nameentry_lookup(int page, int subpage);
|
|
|
|
|
static int load_format(const char *pagedb_path, int lpage,
|
|
|
|
@ -116,6 +126,10 @@ static void modepage_edit(void);
|
|
|
|
|
static void modepage_dump(struct cam_device *device, int cdb_len,
|
|
|
|
|
int dbd, int pc, int page, int subpage,
|
|
|
|
|
int task_attr, int retries, int timeout);
|
|
|
|
|
static void modepage_dump_desc(struct cam_device *device,
|
|
|
|
|
int cdb_len, int llbaa, int pc, int page,
|
|
|
|
|
int subpage, int task_attr, int retries,
|
|
|
|
|
int timeout);
|
|
|
|
|
static void cleanup_editfile(void);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -182,6 +196,43 @@ editentry_update(void *hook __unused, int letter, void *arg, int count,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
editentry_create_desc(void *hook __unused, int letter, void *arg, int count,
|
|
|
|
|
char *name)
|
|
|
|
|
{
|
|
|
|
|
struct editentry *newentry; /* Buffer to hold new entry. */
|
|
|
|
|
|
|
|
|
|
/* Allocate memory for the new entry and a copy of the entry name. */
|
|
|
|
|
if ((newentry = malloc(sizeof(struct editentry))) == NULL ||
|
|
|
|
|
(newentry->name = strdup(name)) == NULL)
|
|
|
|
|
err(EX_OSERR, NULL);
|
|
|
|
|
|
|
|
|
|
/* Trim any trailing whitespace for the entry name. */
|
|
|
|
|
RTRIM(newentry->name);
|
|
|
|
|
|
|
|
|
|
newentry->editable = 1;
|
|
|
|
|
newentry->type = letter;
|
|
|
|
|
newentry->size = count;
|
|
|
|
|
newentry->value.svalue = NULL;
|
|
|
|
|
|
|
|
|
|
STAILQ_INSERT_TAIL(&editlist, newentry, link);
|
|
|
|
|
|
|
|
|
|
switch (letter) {
|
|
|
|
|
case 'i': /* Byte-sized integral type. */
|
|
|
|
|
case 'b': /* Bit-sized integral types. */
|
|
|
|
|
case 't':
|
|
|
|
|
newentry->value.ivalue = (intptr_t)arg;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 'c': /* Character array. */
|
|
|
|
|
case 'z': /* Null-padded string. */
|
|
|
|
|
editentry_set(name, (char *)arg, 0);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
; /* NOTREACHED */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
editentry_save(void *hook __unused, char *name)
|
|
|
|
|
{
|
|
|
|
@ -238,7 +289,7 @@ editentry_set(char *name, char *newvalue, int editonly)
|
|
|
|
|
struct editentry *dest; /* Modepage entry to update. */
|
|
|
|
|
char *cval; /* Pointer to new string value. */
|
|
|
|
|
char *convertend; /* End-of-conversion pointer. */
|
|
|
|
|
int ival; /* New integral value. */
|
|
|
|
|
long long ival, newival; /* New integral value. */
|
|
|
|
|
int resolution; /* Resolution in bits for integer conversion. */
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
@ -248,7 +299,7 @@ editentry_set(char *name, char *newvalue, int editonly)
|
|
|
|
|
* currently workaround it (even for int64's), so we have to kludge it.
|
|
|
|
|
*/
|
|
|
|
|
#define RESOLUTION_MAX(size) ((resolution * (size) == 32)? \
|
|
|
|
|
INT_MAX: (1 << (resolution * (size))) - 1)
|
|
|
|
|
UINT_MAX: (1 << (resolution * (size))) - 1)
|
|
|
|
|
|
|
|
|
|
assert(newvalue != NULL);
|
|
|
|
|
if (*newvalue == '\0')
|
|
|
|
@ -265,13 +316,13 @@ editentry_set(char *name, char *newvalue, int editonly)
|
|
|
|
|
case 't':
|
|
|
|
|
/* Convert the value string to an integer. */
|
|
|
|
|
resolution = (dest->type == 'i')? 8: 1;
|
|
|
|
|
ival = (int)strtol(newvalue, &convertend, 0);
|
|
|
|
|
ival = strtoll(newvalue, &convertend, 0);
|
|
|
|
|
if (*convertend != '\0')
|
|
|
|
|
returnerr(EINVAL);
|
|
|
|
|
if (ival > RESOLUTION_MAX(dest->size) || ival < 0) {
|
|
|
|
|
int newival = (ival < 0)? 0: RESOLUTION_MAX(dest->size);
|
|
|
|
|
warnx("value %d is out of range for entry %s; clipping "
|
|
|
|
|
"to %d", ival, name, newival);
|
|
|
|
|
newival = (ival < 0) ? 0 : RESOLUTION_MAX(dest->size);
|
|
|
|
|
warnx("value %lld is out of range for entry %s; "
|
|
|
|
|
"clipping to %lld", ival, name, newival);
|
|
|
|
|
ival = newival;
|
|
|
|
|
}
|
|
|
|
|
if (dest->value.ivalue != ival)
|
|
|
|
@ -548,7 +599,7 @@ static void
|
|
|
|
|
editlist_populate(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
int page, int subpage, int task_attr, int retries, int timeout)
|
|
|
|
|
{
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE];/* Buffer to hold sense data. */
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
u_int8_t *mode_pars; /* Pointer to modepage params. */
|
|
|
|
|
struct scsi_mode_page_header *mph;
|
|
|
|
|
struct scsi_mode_page_header_sp *mphsp;
|
|
|
|
@ -557,8 +608,8 @@ editlist_populate(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
STAILQ_INIT(&editlist);
|
|
|
|
|
|
|
|
|
|
/* Fetch changeable values; use to build initial editlist. */
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, 1, page, subpage, task_attr, retries,
|
|
|
|
|
timeout, data, sizeof(data));
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, 0, 1, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|
if (cdb_len == 6) {
|
|
|
|
|
struct scsi_mode_header_6 *mh =
|
|
|
|
@ -583,16 +634,77 @@ editlist_populate(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
buff_decode_visit(mode_pars, len, format, editentry_create, 0);
|
|
|
|
|
|
|
|
|
|
/* Fetch the current/saved values; use to set editentry values. */
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, pc, page, subpage, task_attr,
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, 0, pc, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
buff_decode_visit(mode_pars, len, format, editentry_update, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
editlist_populate_desc(struct cam_device *device, int cdb_len, int llbaa, int pc,
|
|
|
|
|
int page, int subpage, int task_attr, int retries, int timeout)
|
|
|
|
|
{
|
|
|
|
|
uint8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
uint8_t *desc; /* Pointer to block descriptor. */
|
|
|
|
|
char num[8];
|
|
|
|
|
struct sbuf sb;
|
|
|
|
|
size_t len;
|
|
|
|
|
u_int longlba, dlen, i;
|
|
|
|
|
|
|
|
|
|
STAILQ_INIT(&editlist);
|
|
|
|
|
|
|
|
|
|
/* Fetch the current/saved values. */
|
|
|
|
|
mode_sense(device, &cdb_len, 0, llbaa, pc, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|
if (cdb_len == 6) {
|
|
|
|
|
struct scsi_mode_header_6 *mh =
|
|
|
|
|
(struct scsi_mode_header_6 *)data;
|
|
|
|
|
desc = (uint8_t *)(mh + 1);
|
|
|
|
|
len = mh->blk_desc_len;
|
|
|
|
|
longlba = 0;
|
|
|
|
|
} else {
|
|
|
|
|
struct scsi_mode_header_10 *mh =
|
|
|
|
|
(struct scsi_mode_header_10 *)data;
|
|
|
|
|
desc = (uint8_t *)(mh + 1);
|
|
|
|
|
len = scsi_2btoul(mh->blk_desc_len);
|
|
|
|
|
longlba = (mh->flags & SMH_LONGLBA) != 0;
|
|
|
|
|
}
|
|
|
|
|
dlen = longlba ? 16 : 8;
|
|
|
|
|
len = MIN(len, sizeof(data) - (desc - data));
|
|
|
|
|
|
|
|
|
|
sbuf_new(&sb, format, sizeof(format), SBUF_FIXEDLEN);
|
|
|
|
|
num[0] = 0;
|
|
|
|
|
for (i = 0; i * dlen < len; i++) {
|
|
|
|
|
if (i > 0)
|
|
|
|
|
snprintf(num, sizeof(num), " %d", i + 1);
|
|
|
|
|
if (longlba) {
|
|
|
|
|
sbuf_printf(&sb, "{Number of Logical Blocks%s High} i4\n", num);
|
|
|
|
|
sbuf_printf(&sb, "{Number of Logical Blocks%s} i4\n", num);
|
|
|
|
|
sbuf_cat(&sb, "{Reserved} *i4\n");
|
|
|
|
|
sbuf_printf(&sb, "{Logical Block Length%s} i4\n", num);
|
|
|
|
|
} else if (device->pd_type == T_DIRECT) {
|
|
|
|
|
sbuf_printf(&sb, "{Number of Logical Blocks%s} i4\n", num);
|
|
|
|
|
sbuf_cat(&sb, "{Reserved} *i1\n");
|
|
|
|
|
sbuf_printf(&sb, "{Logical Block Length%s} i3\n", num);
|
|
|
|
|
} else {
|
|
|
|
|
sbuf_printf(&sb, "{Density Code%s} i1\n", num);
|
|
|
|
|
sbuf_printf(&sb, "{Number of Logical Blocks%s} i3\n", num);
|
|
|
|
|
sbuf_cat(&sb, "{Reserved} *i1\n");
|
|
|
|
|
sbuf_printf(&sb, "{Logical Block Length%s} i3\n", num);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
sbuf_finish(&sb);
|
|
|
|
|
sbuf_delete(&sb);
|
|
|
|
|
|
|
|
|
|
/* Decode the value data, creating edit_entries for each value. */
|
|
|
|
|
buff_decode_visit(desc, len, format, editentry_create_desc, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
editlist_save(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
int page, int subpage, int task_attr, int retries, int timeout)
|
|
|
|
|
{
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE];/* Buffer to hold sense data. */
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
u_int8_t *mode_pars; /* Pointer to modepage params. */
|
|
|
|
|
struct scsi_mode_page_header *mph;
|
|
|
|
|
struct scsi_mode_page_header_sp *mphsp;
|
|
|
|
@ -603,7 +715,7 @@ editlist_save(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Preload the CDB buffer with the current mode page data. */
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, pc, page, subpage, task_attr,
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, 0, pc, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|
/* Initial headers & offsets. */
|
|
|
|
@ -676,6 +788,56 @@ editlist_save(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
task_attr, retries, timeout, data, hlen + mphlen + len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
editlist_save_desc(struct cam_device *device, int cdb_len, int llbaa, int pc,
|
|
|
|
|
int page, int subpage, int task_attr, int retries, int timeout)
|
|
|
|
|
{
|
|
|
|
|
uint8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
uint8_t *desc; /* Pointer to block descriptor. */
|
|
|
|
|
size_t len, hlen;
|
|
|
|
|
|
|
|
|
|
/* Make sure that something changed before continuing. */
|
|
|
|
|
if (! editlist_changed)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Preload the CDB buffer with the current mode page data. */
|
|
|
|
|
mode_sense(device, &cdb_len, 0, llbaa, pc, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|
/* Initial headers & offsets. */
|
|
|
|
|
if (cdb_len == 6) {
|
|
|
|
|
struct scsi_mode_header_6 *mh =
|
|
|
|
|
(struct scsi_mode_header_6 *)data;
|
|
|
|
|
hlen = sizeof(*mh);
|
|
|
|
|
desc = (uint8_t *)(mh + 1);
|
|
|
|
|
len = mh->blk_desc_len;
|
|
|
|
|
mh->data_length = 0; /* Reserved for MODE SELECT command. */
|
|
|
|
|
if (device->pd_type != T_SEQUENTIAL)
|
|
|
|
|
mh->dev_spec = 0; /* See comment above */
|
|
|
|
|
} else {
|
|
|
|
|
struct scsi_mode_header_10 *mh =
|
|
|
|
|
(struct scsi_mode_header_10 *)data;
|
|
|
|
|
hlen = sizeof(*mh);
|
|
|
|
|
desc = (uint8_t *)(mh + 1);
|
|
|
|
|
len = scsi_2btoul(mh->blk_desc_len);
|
|
|
|
|
scsi_ulto2b(0, mh->data_length); /* Reserved for MODE SELECT. */
|
|
|
|
|
if (device->pd_type != T_SEQUENTIAL)
|
|
|
|
|
mh->dev_spec = 0; /* See comment above */
|
|
|
|
|
}
|
|
|
|
|
len = MIN(len, sizeof(data) - (desc - data));
|
|
|
|
|
|
|
|
|
|
/* Encode the value data to be passed back to the device. */
|
|
|
|
|
buff_encode_visit(desc, len, format, editentry_save, 0);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Write the changes back to the device. If the user editted control
|
|
|
|
|
* page 3 (saved values) then request the changes be permanently
|
|
|
|
|
* recorded.
|
|
|
|
|
*/
|
|
|
|
|
mode_select(device, cdb_len, (pc << PAGE_CTRL_SHIFT == SMS_PAGE_CTRL_SAVED),
|
|
|
|
|
task_attr, retries, timeout, data, hlen + len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
modepage_write(FILE *file, int editonly)
|
|
|
|
|
{
|
|
|
|
@ -689,7 +851,7 @@ modepage_write(FILE *file, int editonly)
|
|
|
|
|
fprintf(file, "%s: %s\n", scan->name,
|
|
|
|
|
scan->value.svalue);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(file, "%s: %d\n", scan->name,
|
|
|
|
|
fprintf(file, "%s: %u\n", scan->name,
|
|
|
|
|
scan->value.ivalue);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -845,13 +1007,13 @@ static void
|
|
|
|
|
modepage_dump(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
int page, int subpage, int task_attr, int retries, int timeout)
|
|
|
|
|
{
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE];/* Buffer to hold sense data. */
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
u_int8_t *mode_pars; /* Pointer to modepage params. */
|
|
|
|
|
struct scsi_mode_page_header *mph;
|
|
|
|
|
struct scsi_mode_page_header_sp *mphsp;
|
|
|
|
|
size_t indx, len;
|
|
|
|
|
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, pc, page, subpage, task_attr,
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, 0, pc, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|
if (cdb_len == 6) {
|
|
|
|
@ -880,6 +1042,37 @@ modepage_dump(struct cam_device *device, int cdb_len, int dbd, int pc,
|
|
|
|
|
}
|
|
|
|
|
putchar('\n');
|
|
|
|
|
}
|
|
|
|
|
static void
|
|
|
|
|
modepage_dump_desc(struct cam_device *device, int cdb_len, int llbaa, int pc,
|
|
|
|
|
int page, int subpage, int task_attr, int retries, int timeout)
|
|
|
|
|
{
|
|
|
|
|
uint8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
uint8_t *desc; /* Pointer to block descriptor. */
|
|
|
|
|
size_t indx, len;
|
|
|
|
|
|
|
|
|
|
mode_sense(device, &cdb_len, 0, llbaa, pc, page, subpage, task_attr,
|
|
|
|
|
retries, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|
if (cdb_len == 6) {
|
|
|
|
|
struct scsi_mode_header_6 *mh =
|
|
|
|
|
(struct scsi_mode_header_6 *)data;
|
|
|
|
|
desc = (uint8_t *)(mh + 1);
|
|
|
|
|
len = mh->blk_desc_len;
|
|
|
|
|
} else {
|
|
|
|
|
struct scsi_mode_header_10 *mh =
|
|
|
|
|
(struct scsi_mode_header_10 *)data;
|
|
|
|
|
desc = (uint8_t *)(mh + 1);
|
|
|
|
|
len = scsi_2btoul(mh->blk_desc_len);
|
|
|
|
|
}
|
|
|
|
|
len = MIN(len, sizeof(data) - (desc - data));
|
|
|
|
|
|
|
|
|
|
/* Print the raw mode page data with newlines each 8 bytes. */
|
|
|
|
|
for (indx = 0; indx < len; indx++) {
|
|
|
|
|
printf("%02x%c", desc[indx],
|
|
|
|
|
(((indx + 1) % 8) == 0) ? '\n' : ' ');
|
|
|
|
|
}
|
|
|
|
|
putchar('\n');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
cleanup_editfile(void)
|
|
|
|
@ -892,16 +1085,19 @@ cleanup_editfile(void)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
mode_edit(struct cam_device *device, int cdb_len, int dbd, int pc, int page,
|
|
|
|
|
int subpage, int edit, int binary, int task_attr, int retry_count,
|
|
|
|
|
int timeout)
|
|
|
|
|
mode_edit(struct cam_device *device, int cdb_len, int desc, int dbd, int llbaa,
|
|
|
|
|
int pc, int page, int subpage, int edit, int binary, int task_attr,
|
|
|
|
|
int retry_count, int timeout)
|
|
|
|
|
{
|
|
|
|
|
const char *pagedb_path; /* Path to modepage database. */
|
|
|
|
|
|
|
|
|
|
if (edit && binary)
|
|
|
|
|
errx(EX_USAGE, "cannot edit in binary mode.");
|
|
|
|
|
|
|
|
|
|
if (! binary) {
|
|
|
|
|
if (binary) {
|
|
|
|
|
if (edit)
|
|
|
|
|
errx(EX_USAGE, "cannot edit in binary mode.");
|
|
|
|
|
} else if (desc) {
|
|
|
|
|
editlist_populate_desc(device, cdb_len, llbaa, pc, page,
|
|
|
|
|
subpage, task_attr, retry_count, timeout);
|
|
|
|
|
} else {
|
|
|
|
|
if ((pagedb_path = getenv("SCSI_MODES")) == NULL)
|
|
|
|
|
pagedb_path = DEFAULT_SCSI_MODE_DB;
|
|
|
|
|
|
|
|
|
@ -935,12 +1131,22 @@ mode_edit(struct cam_device *device, int cdb_len, int dbd, int pc, int page,
|
|
|
|
|
errx(EX_USAGE, "it only makes sense to edit page 0 "
|
|
|
|
|
"(current) or page 3 (saved values)");
|
|
|
|
|
modepage_edit();
|
|
|
|
|
editlist_save(device, cdb_len, dbd, pc, page, subpage,
|
|
|
|
|
task_attr, retry_count, timeout);
|
|
|
|
|
if (desc) {
|
|
|
|
|
editlist_save_desc(device, cdb_len, llbaa, pc, page,
|
|
|
|
|
subpage, task_attr, retry_count, timeout);
|
|
|
|
|
} else {
|
|
|
|
|
editlist_save(device, cdb_len, dbd, pc, page, subpage,
|
|
|
|
|
task_attr, retry_count, timeout);
|
|
|
|
|
}
|
|
|
|
|
} else if (binary || STAILQ_EMPTY(&editlist)) {
|
|
|
|
|
/* Display without formatting information. */
|
|
|
|
|
modepage_dump(device, cdb_len, dbd, pc, page, subpage,
|
|
|
|
|
task_attr, retry_count, timeout);
|
|
|
|
|
if (desc) {
|
|
|
|
|
modepage_dump_desc(device, cdb_len, llbaa, pc, page,
|
|
|
|
|
subpage, task_attr, retry_count, timeout);
|
|
|
|
|
} else {
|
|
|
|
|
modepage_dump(device, cdb_len, dbd, pc, page, subpage,
|
|
|
|
|
task_attr, retry_count, timeout);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* Display with format. */
|
|
|
|
|
modepage_write(stdout, 0);
|
|
|
|
@ -951,7 +1157,7 @@ void
|
|
|
|
|
mode_list(struct cam_device *device, int cdb_len, int dbd, int pc, int subpages,
|
|
|
|
|
int task_attr, int retry_count, int timeout)
|
|
|
|
|
{
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE];/* Buffer to hold sense data. */
|
|
|
|
|
u_int8_t data[MAX_DATA_SIZE]; /* Buffer to hold mode parameters. */
|
|
|
|
|
struct scsi_mode_page_header *mph;
|
|
|
|
|
struct scsi_mode_page_header_sp *mphsp;
|
|
|
|
|
struct pagename *nameentry;
|
|
|
|
@ -967,7 +1173,7 @@ mode_list(struct cam_device *device, int cdb_len, int dbd, int pc, int subpages,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Build the list of all mode pages by querying the "all pages" page. */
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, pc, SMS_ALL_PAGES_PAGE,
|
|
|
|
|
mode_sense(device, &cdb_len, dbd, 0, pc, SMS_ALL_PAGES_PAGE,
|
|
|
|
|
subpages ? SMS_SUBPAGE_ALL : 0,
|
|
|
|
|
task_attr, retry_count, timeout, data, sizeof(data));
|
|
|
|
|
|
|
|
|
|