mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Enable user to specify that a device should be configured early, that is during the initial RAM-disk boot phase. This may be necessary, e.g. to override auto-configuration for a device which is also applied during that boot phase. It may also be used to manually specify devices that are required to access the root file system, such as networking devices. Users can mark devices as requiring early configuration by specifying a value of 1 for the newly added internal attribute zdev:early: # chzdev dasd-eckd 0.0.1234 -p zdev:early=1 This can be changed back by removing the attribute setting, or by setting the attribute value to 0: # chzdev dasd-eckd 0.0.1234 -p -r zdev:early or # chzdev dasd-eckd 0.0.1234 -p zdev:early=0 Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
693 lines
19 KiB
C
693 lines
19 KiB
C
/*
|
|
* zdev - Modify and display the persistent configuration of devices
|
|
*
|
|
* Copyright IBM Corp. 2016, 2017
|
|
*
|
|
* s390-tools is free software; you can redistribute it and/or modify
|
|
* it under the terms of the MIT license. See LICENSE for details.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "attrib.h"
|
|
#include "ccw.h"
|
|
#include "dasd.h"
|
|
#include "device.h"
|
|
#include "devtype.h"
|
|
#include "internal.h"
|
|
#include "misc.h"
|
|
#include "modprobe.h"
|
|
#include "module.h"
|
|
#include "path.h"
|
|
#include "setting.h"
|
|
#include "udev.h"
|
|
|
|
#define DASD_MOD_NAME "dasd_mod"
|
|
#define DASD_ECKD_MOD_NAME "dasd_eckd_mod"
|
|
#define DASD_FBA_MOD_NAME "dasd_fba_mod"
|
|
#define DASD_DIAG_MOD_NAME "dasd_diag_mod"
|
|
|
|
/* Subtype specific data. */
|
|
struct dasd_subtype_data {
|
|
const char *ccwdrv;
|
|
const char *module;
|
|
};
|
|
|
|
/* List of dependent modules. */
|
|
static const char *dasd_mods[] = {
|
|
DASD_ECKD_MOD_NAME,
|
|
DASD_FBA_MOD_NAME,
|
|
DASD_DIAG_MOD_NAME,
|
|
NULL,
|
|
};
|
|
|
|
/*
|
|
* DASD type attributes.
|
|
*/
|
|
|
|
static struct attrib dasd_tattr_autodetect = {
|
|
.name = "autodetect",
|
|
.title = "Enable automatic DASD activation",
|
|
.desc =
|
|
"Control whether the DASD driver automatically enables all detected\n"
|
|
"DASDs:\n"
|
|
" 0: Only configured DASDs are enabled\n"
|
|
" 1: All detected DASDs are automatically enabled\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_probeonly = {
|
|
.name = "probeonly",
|
|
.title = "Inhibit access to DASD device nodes",
|
|
.desc =
|
|
"Control whether the DASD driver allows access to DASD devices:\n"
|
|
" 0: All enabled DASDs can be accessed normally\n"
|
|
" 1: Reject any attempt to open DASD devices\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_nopav = {
|
|
.name = "nopav",
|
|
.title = "Deactivate the Parallel Access Volume feature",
|
|
.desc = "Control the use of the Parallel Access Volume (PAV) feature:\n"
|
|
" 0: PAV is used when supported by the storage system\n"
|
|
" 1: The use of PAV is suppressed when running in LPAR\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_nofcx = {
|
|
.name = "nofcx",
|
|
.title = "Deactivate the High Performance FICON feature",
|
|
.desc = "Control the use of the High Performance FICON (HPF) feature:\n"
|
|
" 0: HPF is used when supported by the storage hardware\n"
|
|
" 1: HPF is not used\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_eer_pages = {
|
|
.name = "eer_pages",
|
|
.title = "Modify buffer size for error records",
|
|
.desc =
|
|
"Control the number of 4 KB pages that are used for internal "
|
|
"buffering\n"
|
|
"of error records generated by the Extended Error Reporting (EER)\n"
|
|
"feature.\n",
|
|
.defval = "5",
|
|
.activerem = 1,
|
|
.nounload = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_NUM_GE(1)),
|
|
};
|
|
|
|
/*
|
|
* DASD device attributes.
|
|
*/
|
|
|
|
static struct attrib dasd_attr_failfast = {
|
|
.name = "failfast",
|
|
.title = "Modify error recovery in no-path scenario",
|
|
.desc =
|
|
"Control I/O handling when all paths to a DASD have been lost:\n"
|
|
" 0: Queue I/O until path becomes available\n"
|
|
" 1: Fail I/O request immediately\n",
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_readonly = {
|
|
.name = "readonly",
|
|
.title = "Inhibit write access to DASD",
|
|
.desc = "Control the DASD driver read-only setting for a DASD:\n"
|
|
" 0: Allow writing to the device\n"
|
|
" 1: Deny writing to the device\n",
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_erplog = {
|
|
.name = "erplog",
|
|
.title = "Enable logging of Error Recovery Processing",
|
|
.desc = "Control logging of Error Recovery Processing (ERP), such as\n"
|
|
"failing channel programs:\n"
|
|
" 0: ERP logging is disabled\n"
|
|
" 1: ERP logging is enabled\n",
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static int dasd_raw_diag_order_cmp(struct setting *, struct setting *);
|
|
static bool dasd_raw_diag_check(struct setting *, struct setting *, config_t);
|
|
|
|
static struct attrib dasd_attr_use_diag = {
|
|
.name = "use_diag",
|
|
.title = "Activate z/VM hypervisor assisted I/O processing",
|
|
.desc =
|
|
"Control I/O access mode for a DASD:\n"
|
|
" 0: I/O is performed using standard channel programs\n"
|
|
" 1: I/O is performed using the z/VM DIAGNOSE X'250' interface\n"
|
|
"\n"
|
|
"The DIAGNOSE X'250' access mode works only when:\n"
|
|
" - Running Linux as z/VM guest\n"
|
|
" - Using devices formatted with consistent block sizes, such as\n"
|
|
" ECKD DASDs with LDL or CMS format, or FBA devices\n",
|
|
.order_cmp = dasd_raw_diag_order_cmp,
|
|
.check = dasd_raw_diag_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_raw_track_access = {
|
|
.name = "raw_track_access",
|
|
.title = "Enable access to ECKD track metadata",
|
|
.desc =
|
|
"Control whether the DASD driver provides access to full ECKD tracks,\n"
|
|
"including ECKD-specific meta-data:\n"
|
|
" 0: Only access the data portion of ECKD tracks\n"
|
|
" 1: Access the full track\n",
|
|
.order_cmp = dasd_raw_diag_order_cmp,
|
|
.check = dasd_raw_diag_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
/* Ensure ordering if both use_diag and raw_track_access are modified. */
|
|
static int dasd_raw_diag_order_cmp(struct setting *a, struct setting *b)
|
|
{
|
|
int a_val, b_val;
|
|
|
|
if ((a->attrib == &dasd_attr_use_diag &&
|
|
b->attrib == &dasd_attr_raw_track_access) ||
|
|
(a->attrib == &dasd_attr_raw_track_access &&
|
|
b->attrib == &dasd_attr_use_diag)) {
|
|
/* Define order to ensure that =0 is done before =1. */
|
|
a_val = atoi(a->value);
|
|
b_val = atoi(b->value);
|
|
|
|
if (a_val == 1 && b_val == 0)
|
|
return 1;
|
|
if (a_val == 0 && b_val == 1)
|
|
return -1;
|
|
}
|
|
|
|
return ccw_offline_only_order_cmp(a, b);
|
|
}
|
|
|
|
/* Conflict if both use_diag and raw_track_access are set. */
|
|
static bool dasd_raw_diag_check(struct setting *a, struct setting *b,
|
|
config_t config)
|
|
{
|
|
if ((a->attrib == &dasd_attr_use_diag &&
|
|
b->attrib == &dasd_attr_raw_track_access) ||
|
|
(a->attrib == &dasd_attr_raw_track_access &&
|
|
b->attrib == &dasd_attr_use_diag)) {
|
|
if (atoi(a->value) == 1 && atoi(b->value) == 1)
|
|
return false;
|
|
}
|
|
|
|
return ccw_offline_only_check(a, b, config);
|
|
}
|
|
|
|
static struct attrib dasd_attr_eer_enabled = {
|
|
.name = "eer_enabled",
|
|
.title = "Enable Extended Error Reporting",
|
|
.desc =
|
|
"Control the Extended Error Reporting (EER) feature for a DASD:\n"
|
|
" 0: EER is disabled\n"
|
|
" 1: EER is enabled\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_expires = {
|
|
.name = "expires",
|
|
.title = "Modify I/O operation timeout",
|
|
.desc =
|
|
"Specify the time in seconds that the DASD driver waits for the\n"
|
|
"completion of a single I/O operation before considering that I/O\n"
|
|
"operation to have failed.\n"
|
|
"\n"
|
|
"The default value depends on the DASD type.\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(1, 40000000)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_retries = {
|
|
.name = "retries",
|
|
.title = "Modify I/O operation retry counter",
|
|
.desc =
|
|
"Specify the number of times that a failed I/O should be retried\n"
|
|
"before reporting it as failed.\n"
|
|
"\n"
|
|
"The default value is dependent on the DASD type.\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 32768)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_timeout = {
|
|
.name = "timeout",
|
|
.title = "Modify I/O request timeout",
|
|
.desc =
|
|
"Specify the total time in seconds that the Linux block device layer\n"
|
|
"waits for the completion of an I/O request issued to the DASD driver\n"
|
|
"before considering that I/O to have failed. Specify 0 to deactivate\n"
|
|
"timeout handling.\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_NUM_GE(0)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_reservation_policy = {
|
|
.name = "reservation_policy",
|
|
.title = "Modify lost device reservation behavior",
|
|
.desc =
|
|
"Control the DASD driver behavior if an existing DASD reservation of\n"
|
|
"this system for a DASD is lost:\n"
|
|
" ignore: I/O operations are blocked until the external reservation\n"
|
|
" is released (default)\n"
|
|
" fail: All I/O operations are considered to have failed\n",
|
|
.defval = "ignore",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_STR("ignore"), ACCEPT_STR("fail")),
|
|
};
|
|
|
|
static struct attrib dasd_attr_last_known_reservation_state = {
|
|
.name = "last_known_reservation_state",
|
|
.title = "Display and reset driver device reservation view",
|
|
.desc =
|
|
"Display the DASD driver's view of device reservations held by this\n"
|
|
"system:\n"
|
|
" none: No reservation held or no information available\n"
|
|
" reserved: Device is assumed to be reserved by this system\n"
|
|
" lost: A reservation held by this system was lost\n"
|
|
"\n"
|
|
"To reset the reservation state from 'lost' to 'none', set this\n"
|
|
"attribute to 'reset'.\n",
|
|
.unstable = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_safe_offline = {
|
|
.name = "safe_offline",
|
|
.title = "Deactivate DASD after processing pending I/Os",
|
|
.desc = "Write an arbitrary value to this attribute to attempt to set\n"
|
|
"the DASD offline after all outstanding I/O requests have\n"
|
|
"been processed.\n",
|
|
.activeonly = 1,
|
|
.writeonly = 1,
|
|
};
|
|
|
|
/*
|
|
* DASD subtype methods.
|
|
*/
|
|
|
|
static bool _check_use_diag(struct setting_list *list)
|
|
{
|
|
struct setting *u;
|
|
|
|
u = setting_list_find(list, dasd_attr_use_diag.name);
|
|
if (u && u->modified) {
|
|
if (u->value && atoi(u->value) == 1) {
|
|
delayed_warn("Cannot set 'use_diag=1' on non-z/VM system\n");
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/* Check if use_diag setting can be correctly applied. */
|
|
static exit_code_t check_use_diag(struct device *dev, config_t config)
|
|
{
|
|
if (is_zvm())
|
|
return EXIT_OK;
|
|
|
|
if (SCOPE_ACTIVE(config) && !_check_use_diag(dev->active.settings))
|
|
return EXIT_INVALID_CONFIG;
|
|
if (SCOPE_PERSISTENT(config) &&
|
|
!_check_use_diag(dev->persistent.settings))
|
|
return EXIT_INVALID_CONFIG;
|
|
if (SCOPE_AUTOCONF(config) &&
|
|
!_check_use_diag(dev->autoconf.settings))
|
|
return EXIT_INVALID_CONFIG;
|
|
|
|
return EXIT_OK;
|
|
}
|
|
|
|
static exit_code_t dasd_st_check_pre_configure(struct subtype *st,
|
|
struct device *dev,
|
|
int prereq, config_t config)
|
|
{
|
|
exit_code_t rc;
|
|
|
|
if (dev->active.deconfigured)
|
|
return EXIT_OK;
|
|
rc = check_use_diag(dev, config);
|
|
if (rc)
|
|
return rc;
|
|
|
|
return EXIT_OK;
|
|
}
|
|
|
|
static void dasd_st_add_modules(struct subtype *st, struct device *dev,
|
|
struct util_list *modules)
|
|
{
|
|
int changed, aset, pset;
|
|
|
|
/* Add main module. */
|
|
st->super->add_modules(st, dev, modules);
|
|
|
|
/* Add dasd_diag_mod if use_diag is set. */
|
|
setting_list_get_bool_state(dev->active.settings,
|
|
dasd_attr_use_diag.name, &changed, &aset);
|
|
setting_list_get_bool_state(dev->persistent.settings,
|
|
dasd_attr_use_diag.name, &changed, &pset);
|
|
setting_list_get_bool_state(dev->autoconf.settings,
|
|
dasd_attr_use_diag.name, &changed, &pset);
|
|
|
|
if (aset || pset)
|
|
strlist_add_unique(modules, DASD_DIAG_MOD_NAME);
|
|
}
|
|
|
|
/*
|
|
* DASD methods.
|
|
*/
|
|
|
|
/* Clean up all resources used by devtype object. */
|
|
static void dasd_devtype_exit(struct devtype *dt)
|
|
{
|
|
setting_list_free(dt->active_settings);
|
|
setting_list_free(dt->persistent_settings);
|
|
}
|
|
|
|
/* Split a dasd= module parameter string into a setting_list, based on
|
|
* known attributes encoded in dasd= parameters. */
|
|
static void split_dasd(struct devtype *dt, const char *str,
|
|
struct setting_list *list)
|
|
{
|
|
char *copy, *curr, *next, *dasd_str;
|
|
struct attrib *a;
|
|
struct util_list *dasd;
|
|
|
|
dasd = strlist_new();
|
|
copy = misc_strdup(str);
|
|
next = copy;
|
|
while ((curr = strsep(&next, ","))) {
|
|
if (strcmp(curr, "(null)") == 0)
|
|
continue;
|
|
if (*curr == 0) {
|
|
/* Handle dasd="" */
|
|
continue;
|
|
}
|
|
/* Check for known attributes. */
|
|
a = attrib_find(dt->type_attribs, curr);
|
|
if (a) {
|
|
/* Currently only boolean attributes implemented. */
|
|
setting_list_apply_actual(list, a, curr, "1");
|
|
continue;
|
|
}
|
|
/* An unknown setting or device spec - leave in dasd=. */
|
|
strlist_add(dasd, "%s", curr);
|
|
}
|
|
free(copy);
|
|
|
|
/* Add dasd= setting if necessary. */
|
|
if (!util_list_is_empty(dasd)) {
|
|
dasd_str = strlist_flatten(dasd, ",");
|
|
setting_list_apply_actual(list, NULL, "dasd", dasd_str);
|
|
free(dasd_str);
|
|
}
|
|
strlist_free(dasd);
|
|
}
|
|
|
|
/* Convert a module parameter list into a devtype settings list. */
|
|
static void convert_params_to_settings(struct devtype *dt,
|
|
struct setting_list *from,
|
|
struct setting_list *to)
|
|
{
|
|
struct setting *s;
|
|
|
|
util_list_iterate(&from->list, s) {
|
|
if (strcmp(s->name, "dasd") == 0) {
|
|
/* Special handling: split known attribs out. */
|
|
split_dasd(dt, s->value, to);
|
|
continue;
|
|
}
|
|
/* Just copy remaining attributes. */
|
|
setting_list_apply_actual(to, s->attrib, s->name, s->value);
|
|
}
|
|
}
|
|
|
|
/* Convert a devtype settings list to a module parameter list. */
|
|
static void convert_settings_to_params(struct devtype *dt,
|
|
struct setting_list *from,
|
|
struct setting_list **to)
|
|
{
|
|
struct setting *s_from, *s_to;
|
|
struct util_list *dasd;
|
|
int dasd_mod;
|
|
char *flat;
|
|
|
|
*to = setting_list_new();
|
|
dasd = strlist_new();
|
|
dasd_mod = 0;
|
|
|
|
util_list_iterate(&from->list, s_from) {
|
|
if (s_from->removed)
|
|
continue;
|
|
if (s_from->derived && !s_from->modified)
|
|
continue;
|
|
if (strcmp(s_from->name, "eer_pages") == 0) {
|
|
/* Copy stand-alone parameter. */
|
|
setting_list_add(*to, setting_copy(s_from));
|
|
continue;
|
|
}
|
|
/* All other settings need to go into dasd=. */
|
|
if (strcmp(s_from->name, "dasd") == 0) {
|
|
/* Just add explicit dasd= content. */
|
|
strlist_add(dasd, "%s", s_from->value);
|
|
} else if (strcmp(s_from->value, "0") == 0) {
|
|
/* A flag in dasd= counts as set, so skip the unset
|
|
* ones. */
|
|
continue;
|
|
} else {
|
|
/* Just add the name for set attributes. */
|
|
strlist_add(dasd, "%s", s_from->name);
|
|
dasd_mod += s_from->modified;
|
|
}
|
|
}
|
|
|
|
flat = strlist_flatten(dasd, ",");
|
|
s_to = setting_new(NULL, "dasd", flat);
|
|
free(flat);
|
|
if (dasd_mod > 0)
|
|
s_to->modified = 1;
|
|
if (util_list_is_empty(dasd))
|
|
s_to->removed = 1;
|
|
setting_list_add(*to, s_to);
|
|
strlist_free(dasd);
|
|
}
|
|
|
|
static exit_code_t dasd_devtype_read_settings(struct devtype *dt,
|
|
config_t config)
|
|
{
|
|
struct setting_list *list;
|
|
char *path;
|
|
exit_code_t rc = EXIT_OK;
|
|
|
|
if (SCOPE_ACTIVE(config) && !dt->active_settings) {
|
|
dt->active_exists = 0;
|
|
rc = module_get_params(DASD_MOD_NAME, dt->type_attribs, &list);
|
|
if (rc)
|
|
return rc;
|
|
dt->active_settings = setting_list_new();
|
|
if (list) {
|
|
convert_params_to_settings(dt, list,
|
|
dt->active_settings);
|
|
setting_list_mark_default_derived(dt->active_settings);
|
|
setting_list_apply_defaults(dt->active_settings,
|
|
dt->type_attribs, false);
|
|
setting_list_free(list);
|
|
dt->active_exists = 1;
|
|
}
|
|
}
|
|
|
|
if (SCOPE_PERSISTENT(config) && !dt->persistent_settings) {
|
|
dt->persistent_exists = 0;
|
|
path = path_get_modprobe_conf(dt);
|
|
rc = modprobe_read_settings(path, DASD_MOD_NAME,
|
|
dt->type_attribs, &list);
|
|
free(path);
|
|
if (rc)
|
|
return rc;
|
|
dt->persistent_settings = setting_list_new();
|
|
if (list) {
|
|
convert_params_to_settings(dt, list,
|
|
dt->persistent_settings);
|
|
setting_list_apply_defaults(dt->persistent_settings,
|
|
dt->type_attribs, false);
|
|
setting_list_free(list);
|
|
dt->persistent_exists = 1;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static exit_code_t dasd_devtype_write_settings(struct devtype *dt,
|
|
config_t config)
|
|
{
|
|
struct setting_list *list;
|
|
char *path;
|
|
exit_code_t rc = EXIT_OK;
|
|
|
|
if (SCOPE_ACTIVE(config) && dt->active_settings) {
|
|
/* Try setting parameters directly via Sysfs. */
|
|
if (module_set_params(DASD_MOD_NAME, dt->active_settings))
|
|
goto persistent;
|
|
|
|
convert_settings_to_params(dt, dt->active_settings, &list);
|
|
rc = module_load(DASD_MOD_NAME, dasd_mods, list,
|
|
err_delayed_print);
|
|
setting_list_free(list);
|
|
if (rc)
|
|
return rc;
|
|
}
|
|
|
|
persistent:
|
|
if (SCOPE_PERSISTENT(config) && dt->persistent_settings) {
|
|
path = path_get_modprobe_conf(dt);
|
|
if (!rc) {
|
|
convert_settings_to_params(dt, dt->persistent_settings,
|
|
&list);
|
|
rc = modprobe_write_settings(path, DASD_MOD_NAME, list);
|
|
setting_list_free(list);
|
|
}
|
|
free(path);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* DASD device sub-types.
|
|
*/
|
|
static struct ccw_subtype_data dasd_eckd_data = {
|
|
.ccwdrv = "dasd-eckd",
|
|
.mod = "dasd_eckd_mod",
|
|
};
|
|
|
|
struct subtype dasd_subtype_eckd = {
|
|
.super = &ccw_subtype,
|
|
.devtype = &dasd_devtype,
|
|
.name = "dasd-eckd",
|
|
.title = "Enhanced Count Key Data (ECKD) DASDs",
|
|
.devname = "ECKD DASD",
|
|
.modules = STRING_ARRAY(DASD_ECKD_MOD_NAME),
|
|
.namespace = &ccw_namespace,
|
|
.data = &dasd_eckd_data,
|
|
|
|
.dev_attribs = ATTRIB_ARRAY(
|
|
&ccw_attr_online_force,
|
|
&ccw_attr_cmb_enable,
|
|
&dasd_attr_failfast,
|
|
&dasd_attr_readonly,
|
|
&dasd_attr_erplog,
|
|
&dasd_attr_use_diag,
|
|
&dasd_attr_raw_track_access,
|
|
&dasd_attr_eer_enabled,
|
|
&dasd_attr_expires,
|
|
&dasd_attr_retries,
|
|
&dasd_attr_timeout,
|
|
&dasd_attr_reservation_policy,
|
|
&dasd_attr_last_known_reservation_state,
|
|
&dasd_attr_safe_offline,
|
|
&internal_attr_early,
|
|
),
|
|
.unknown_dev_attribs = 1,
|
|
|
|
.check_pre_configure = &dasd_st_check_pre_configure,
|
|
.add_modules = &dasd_st_add_modules,
|
|
};
|
|
|
|
static struct ccw_subtype_data dasd_fba_data = {
|
|
.ccwdrv = "dasd-fba",
|
|
.mod = "dasd_fba_mod",
|
|
};
|
|
|
|
struct subtype dasd_subtype_fba = {
|
|
.super = &ccw_subtype,
|
|
.devtype = &dasd_devtype,
|
|
.name = "dasd-fba",
|
|
.title = "Fixed Block Architecture (FBA) DASDs",
|
|
.devname = "FBA DASD",
|
|
.modules = STRING_ARRAY(DASD_FBA_MOD_NAME),
|
|
.namespace = &ccw_namespace,
|
|
.data = &dasd_fba_data,
|
|
|
|
.dev_attribs = ATTRIB_ARRAY(
|
|
&ccw_attr_online_force,
|
|
&ccw_attr_cmb_enable,
|
|
&dasd_attr_failfast,
|
|
&dasd_attr_readonly,
|
|
&dasd_attr_erplog,
|
|
&dasd_attr_use_diag,
|
|
&dasd_attr_expires,
|
|
&dasd_attr_retries,
|
|
&dasd_attr_timeout,
|
|
&dasd_attr_reservation_policy,
|
|
&dasd_attr_last_known_reservation_state,
|
|
&dasd_attr_safe_offline,
|
|
&internal_attr_early,
|
|
),
|
|
.unknown_dev_attribs = 1,
|
|
|
|
.check_pre_configure = &dasd_st_check_pre_configure,
|
|
.add_modules = &dasd_st_add_modules,
|
|
};
|
|
|
|
/*
|
|
* DASD device type.
|
|
*/
|
|
|
|
struct devtype dasd_devtype = {
|
|
.name = "dasd",
|
|
.title = "FICON-attached Direct Access Storage Devices "
|
|
"(DASDs)",
|
|
.devname = "DASD",
|
|
.modules = STRING_ARRAY(DASD_MOD_NAME),
|
|
|
|
.subtypes = SUBTYPE_ARRAY(
|
|
&dasd_subtype_eckd,
|
|
&dasd_subtype_fba,
|
|
),
|
|
|
|
.type_attribs = ATTRIB_ARRAY(
|
|
&dasd_tattr_autodetect,
|
|
&dasd_tattr_probeonly,
|
|
&dasd_tattr_nopav,
|
|
&dasd_tattr_nofcx,
|
|
&dasd_tattr_eer_pages,
|
|
),
|
|
|
|
.exit = &dasd_devtype_exit,
|
|
|
|
.read_settings = &dasd_devtype_read_settings,
|
|
.write_settings = &dasd_devtype_write_settings,
|
|
};
|