diff --git a/zdev/dracut/95zdev-kdump/module-setup.sh b/zdev/dracut/95zdev-kdump/module-setup.sh index 71855bc6..1052190f 100755 --- a/zdev/dracut/95zdev-kdump/module-setup.sh +++ b/zdev/dracut/95zdev-kdump/module-setup.sh @@ -55,7 +55,7 @@ cmdline() { installkernel() { # Add modules for all device types supported by chzdev (required for # auto-configuration) - instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \ + instmods ctcm qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \ dasd_diag_mod zfcp } diff --git a/zdev/dracut/95zdev/module-setup.sh b/zdev/dracut/95zdev/module-setup.sh index ae5c9811..d4ba2ed8 100644 --- a/zdev/dracut/95zdev/module-setup.sh +++ b/zdev/dracut/95zdev/module-setup.sh @@ -61,7 +61,7 @@ installkernel() { # Add modules for all device types supported by chzdev (required for # auto-configuration) hostonly="$(optional_hostonly)" \ - instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \ + instmods ctcm qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \ dasd_diag_mod zfcp } diff --git a/zdev/include/lcs.h b/zdev/include/lcs.h deleted file mode 100644 index 4b9a01b4..00000000 --- a/zdev/include/lcs.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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. - */ - -#ifndef LCS_H -#define LCS_H - -#define LCS_MOD_NAME "lcs" -#define LCS_CCWGROUPDRV_NAME "lcs" -#define LCS_CCWDRV_NAME "lcs" -#define LCS_ROOTDRV_NAME "lcs" -#define LCS_NUM_DEVS 2 - -struct devtype; -struct namespace; - -extern struct devtype lcs_devtype; -extern struct namespace lcs_namespace; - -#endif /* LCS_H */ diff --git a/zdev/include/lcs_auto.h b/zdev/include/lcs_auto.h deleted file mode 100644 index 31b9c367..00000000 --- a/zdev/include/lcs_auto.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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. - */ - -#ifndef LCS_AUTO_H -#define LCS_AUTO_H - -#include "misc.h" - -struct util_list; -struct ccwgroup_devid; -struct ccw_devid; - -void lcs_auto_add_ids(struct util_list *); -exit_code_t lcs_auto_get_devid(struct ccwgroup_devid *, struct ccw_devid *, - err_t); -exit_code_t lcs_auto_is_possible(struct ccwgroup_devid *, err_t); - -#endif /* LCS_AUTO_H */ diff --git a/zdev/initramfs/hooks/s390-tools-zdev b/zdev/initramfs/hooks/s390-tools-zdev index 06351995..9ac5a6b6 100644 --- a/zdev/initramfs/hooks/s390-tools-zdev +++ b/zdev/initramfs/hooks/s390-tools-zdev @@ -29,7 +29,7 @@ esac # Add modules for all device types supported by chzdev (required for # auto-configuration) -zdev_modules="lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod dasd_diag_mod zfcp" +zdev_modules="qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod dasd_diag_mod zfcp" for x in $zdev_modules ; do manual_add_modules ${x} diff --git a/zdev/man/chzdev.8 b/zdev/man/chzdev.8 index 91dddc35..6e402719 100644 --- a/zdev/man/chzdev.8 +++ b/zdev/man/chzdev.8 @@ -61,7 +61,7 @@ chzdev - Configure z Systems specific devices .B chzdev is a tool for configuring devices and device drivers which are specific to the IBM z Systems platform. Supported device types include storage devices (DASD -and zFCP) and networking devices (QETH, CTC and LCS). +and zFCP) and networking devices (QETH and CTC). .PP . .SS "Configurations" diff --git a/zdev/man/lszdev.8 b/zdev/man/lszdev.8 index 3aa1b941..03b80c30 100644 --- a/zdev/man/lszdev.8 +++ b/zdev/man/lszdev.8 @@ -60,7 +60,7 @@ lszdev - Display configuration of z Systems specific devices .B lszdev displays the configuration of devices and device drivers that are specific to IBM z Systems. Supported device types include -storage devices (DASD and zFCP) and networking devices (QETH, CTC and LCS). +storage devices (DASD and zFCP) and networking devices (QETH and CTC). .PP . .PP diff --git a/zdev/src/Makefile b/zdev/src/Makefile index d0163390..dc56c9b3 100644 --- a/zdev/src/Makefile +++ b/zdev/src/Makefile @@ -36,9 +36,6 @@ chzdev_objects += nic.o qeth.o qeth_auto.o # CTC devtype chzdev_objects += ctc.o ctc_auto.o -# LCS devtype -chzdev_objects += lcs.o lcs_auto.o - # AP devtype chzdev_objects += ap.o @@ -72,9 +69,6 @@ lszdev_objects += nic.o qeth.o qeth_auto.o # CTC devtype lszdev_objects += ctc.o ctc_auto.o -# LCS devtype -lszdev_objects += lcs.o lcs_auto.o - # AP devtype lszdev_objects += ap.o diff --git a/zdev/src/ctc_auto.c b/zdev/src/ctc_auto.c index e2b7701b..11c0a5e0 100644 --- a/zdev/src/ctc_auto.c +++ b/zdev/src/ctc_auto.c @@ -15,7 +15,6 @@ #include "ccwgroup.h" #include "ctc.h" #include "ctc_auto.h" -#include "lcs.h" #include "module.h" #include "path.h" @@ -39,9 +38,7 @@ static struct cutype ctc_cutypes[] = { * 1. A CTC device can be grouped from 2 CCW devices * a) Read device * b) Write device - * 2. All CCW devices must be bound to the CTC CCW device driver. Note that - * due to an overlap in CU-Types, CCW device could also be bound to - * the LCS device driver. + * 2. All CCW devices must be bound to the CTC CCW device driver. * 3. The subchannel of all CCW devices must be defined with the same CHPID * 4. None of the CCW devices is part of an existing CCWGROUP device */ @@ -113,7 +110,7 @@ static exit_code_t add_cb(const char *path, const char *filename, void *data) } /* Return a sorted ptrlist of struct ccw_devinfos for all CCW devices - * bound to the ctc or lcs CCW device driver with matching CUTYPE. + * bound to the ctc CCW device driver with matching CUTYPE. * The result must be freed using ptrlist_free(,1); */ static struct util_list *read_sorted_ctc_devinfos(void) { @@ -130,12 +127,6 @@ static struct util_list *read_sorted_ctc_devinfos(void) path_for_each(path, add_cb, infos); free(path); - /* Add CCW devices bound to the LCS CCW device driver. */ - path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME); - if (util_path_is_dir(path)) - path_for_each(path, add_cb, infos); - free(path); - /* For each CHPID: Find groups. Add to result list. */ util_list_sort(infos, info_cmp, NULL); diff --git a/zdev/src/devtype.c b/zdev/src/devtype.c index 3085fdd6..fd34bb5a 100644 --- a/zdev/src/devtype.c +++ b/zdev/src/devtype.c @@ -18,7 +18,6 @@ #include "devnode.h" #include "devtype.h" #include "generic_ccw.h" -#include "lcs.h" #include "misc.h" #include "module.h" #include "namespace.h" @@ -36,7 +35,6 @@ struct devtype *devtypes[] = { &zfcp_devtype, &qeth_devtype, &ctc_devtype, - &lcs_devtype, &ap_devtype, &virtio_devtype, &generic_ccw_devtype, /* Generic types should come last. */ diff --git a/zdev/src/lcs.c b/zdev/src/lcs.c deleted file mode 100644 index 861d030d..00000000 --- a/zdev/src/lcs.c +++ /dev/null @@ -1,429 +0,0 @@ -/* - * 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 -#include - -#include "attrib.h" -#include "ccw.h" -#include "ccwgroup.h" -#include "device.h" -#include "devtype.h" -#include "internal.h" -#include "lcs.h" -#include "lcs_auto.h" -#include "misc.h" -#include "namespace.h" -#include "setting.h" - -#define DEVNAME "LCS device" - -/* - * LCS device ID namespace methods. - */ -static exit_code_t lcs_parse_devid(struct ccwgroup_devid *devid_ptr, - const char *id, err_t err) -{ - struct ccwgroup_devid devid; - const char *reason = NULL; - exit_code_t rc; - - rc = ccwgroup_parse_devid(&devid, id, err); - if (rc) - return rc; - - if (devid.num > LCS_NUM_DEVS) { - reason = "Too many CCW device IDs specified"; - rc = EXIT_INVALID_ID; - } else if (devid_ptr) - *devid_ptr = devid; - - if (reason) { - err_t_print(err, "Error in %s ID format: %s: %s\n", DEVNAME, - reason, id); - } - - return rc; -} - -static exit_code_t lcs_parse_devid_range(struct ccwgroup_devid *from_ptr, - struct ccwgroup_devid *to_ptr, - const char *range, err_t err) -{ - char *from_str, *to_str; - struct ccwgroup_devid from, to; - exit_code_t rc; - const char *reason = NULL; - - /* Split range. */ - from_str = misc_strdup(range); - to_str = strchr(from_str, '-'); - if (!to_str) { - rc = EXIT_INVALID_ID; - reason = "Missing hyphen"; - goto out; - } - *to_str = 0; - to_str++; - - /* Parse range start end end ID. */ - rc = lcs_parse_devid(&from, from_str, err); - if (rc) - goto out; - - rc = lcs_parse_devid(&to, to_str, err); - if (rc) - goto out; - - /* Only allow ranges on CCWGROUP devices specified as single ID. */ - if (from.num != 1 || to.num != 1) { - rc = EXIT_INVALID_ID; - reason = "Ranges only supported on single CCW device IDs"; - goto out; - } - - rc = EXIT_OK; - if (from_ptr) - *from_ptr = from; - if (to_ptr) - *to_ptr = to; - -out: - free(from_str); - - if (reason) { - err_t_print(err, "Error in %s ID range format: %s: %s\n", - DEVNAME, reason, range); - } - - return rc; -} - -static bool lcs_parse_devid_range_simple(struct ccwgroup_devid *from, - struct ccwgroup_devid *to, - const char *range) -{ - if (lcs_parse_devid_range(from, to, range, err_ignore) == EXIT_OK) - return true; - - return false; -} - -static exit_code_t lcs_ns_is_id_valid(const char *id, err_t err) -{ - return lcs_parse_devid(NULL, id, err); -} - -static char *lcs_ns_normalize_id(const char *id) -{ - struct ccwgroup_devid devid; - - if (lcs_parse_devid(&devid, id, err_ignore) != EXIT_OK) - return NULL; - - return ccwgroup_devid_to_str(&devid); -} - -static void *lcs_ns_parse_id(const char *id, err_t err) -{ - struct ccwgroup_devid *devid; - - devid = misc_malloc(sizeof(struct ccwgroup_devid)); - if (lcs_parse_devid(devid, id, err) != EXIT_OK) { - free(devid); - return NULL; - } - - return devid; -} - -static exit_code_t lcs_ns_is_id_range_valid(const char *range, err_t err) -{ - return lcs_parse_devid_range(NULL, NULL, range, err); -} - -static unsigned long lcs_ns_num_ids_in_range(const char *range) -{ - struct ccwgroup_devid f, t; - - if (!lcs_parse_devid_range_simple(&f, &t, range)) - return 0; - - if (f.devid[0].cssid != t.devid[0].cssid || - f.devid[0].ssid != t.devid[0].ssid) - return 0; - - if (f.devid[0].devno > t.devid[0].devno) - return 0; - - return t.devid[0].devno - f.devid[0].devno + 1; -} - -static void lcs_ns_range_start(struct ns_range_iterator *it, const char *range) -{ - struct ccwgroup_devid from, to; - - if (!lcs_parse_devid_range_simple(&from, &to, range)) { - memset(it, 0, sizeof(struct ns_range_iterator)); - return; - } - - it->devid = ccwgroup_copy_devid(&from); - it->devid_last = ccwgroup_copy_devid(&to); - it->id = ccwgroup_devid_to_str(it->devid); -} - -static bool lcs_ns_is_id_blacklisted(const char *id) -{ - struct ccwgroup_devid devid; - char *ccw_id; - unsigned int i; - bool result = false; - - if (lcs_parse_devid(&devid, id, err_ignore) != EXIT_OK) - return false; - for (i = 0; i < devid.num; i++) { - ccw_id = ccw_devid_to_str(&devid.devid[i]); - result = ccw_is_id_blacklisted(ccw_id); - free(ccw_id); - if (result) - break; - } - - return result; -} - -static void lcs_ns_unblacklist_id(const char *id) -{ - struct ccwgroup_devid devid; - char *ccw_id; - unsigned int i; - - if (lcs_parse_devid(&devid, id, err_ignore) != EXIT_OK) - return; - for (i = 0; i < devid.num; i++) { - ccw_id = ccw_devid_to_str(&devid.devid[i]); - if (ccw_is_id_blacklisted(ccw_id)) - ccw_unblacklist_id(ccw_id); - free(ccw_id); - } -} - -/* - * LCS device ID namespace. - */ - -struct namespace lcs_namespace = { - .devname = DEVNAME, - .is_id_valid = lcs_ns_is_id_valid, - .is_id_similar = ccwgroup_is_id_similar, - .cmp_ids = ccwgroup_cmp_ids, - .normalize_id = lcs_ns_normalize_id, - .parse_id = lcs_ns_parse_id, - .cmp_parsed_ids = ccwgroup_cmp_parsed_ids, - .qsort_cmp = ccwgroup_qsort_cmp, - .is_id_range_valid = lcs_ns_is_id_range_valid, - .num_ids_in_range = lcs_ns_num_ids_in_range, - .is_id_in_range = ccwgroup_is_id_in_range, - .range_start = lcs_ns_range_start, - .range_next = ccwgroup_range_next, - - /* Blacklist handling. */ - .is_blacklist_active = ccw_is_blacklist_active, - .is_id_blacklisted = lcs_ns_is_id_blacklisted, - .is_id_range_blacklisted = ccw_is_id_range_blacklisted, - .unblacklist_id = lcs_ns_unblacklist_id, - .unblacklist_id_range = ccw_unblacklist_id_range, - .blacklist_persist = ccw_blacklist_persist, -}; - -/* - * LCS device attributes. - */ - -static struct attrib lcs_attr_lancmd_timeout = { - .name = "lancmd_timeout", - .title = "Modify LAN command timeout", - .desc = - "Specify the time in seconds that the LCS driver waits for a reply\n" - "after issuing a LAN command to the LAN adapter.\n", - .defval = "5", - .accept = ACCEPT_ARRAY(ACCEPT_NUM_GE(1)), -}; - -static struct attrib lcs_attr_recover = { - .name = "recover", - .title = "Trigger device recovery", - .desc = - "Write '1' to this attribute to restart the recovery process for the\n" - "QETH device.\n", - .accept = ACCEPT_ARRAY(ACCEPT_NUM(1)), - .writeonly = 1, - .activeonly = 1, -}; - -/* - * LCS subtype methods. - */ - -static exit_code_t lcs_st_is_definable(struct subtype *st, const char *id, - err_t err) -{ - struct ccwgroup_subtype_data *data = st->data; - struct ccwgroup_devid devid; - exit_code_t rc; - - rc = ccwgroup_parse_devid(&devid, id, err); - if (rc) - return rc; - - if (subtype_device_exists_active(st, id)) - return EXIT_OK; - - if (devid.num == data->num_devs) - return lcs_auto_is_possible(&devid, err); - - if (devid.num == 1) - return lcs_auto_get_devid(NULL, &devid.devid[0], err); - - err_t_print(err, "Invalid number of CCW device IDs\n"); - - return EXIT_INVALID_ID; -} - -/** - * device_detect_definable - Detect configuration of definable device - * @st: Device subtype - * @dev: Device - * - * Detect the full ID and default parameters for non-existing but definable - * device @dev and update active.definable. Return %EXIT_OK on success, or an - * error code otherwise. - */ -static exit_code_t lcs_st_detect_definable(struct subtype *st, - struct device *dev) -{ - struct ccwgroup_devid *devid; - exit_code_t rc; - - devid = dev->devid; - if (devid->num == 1) { - /* Detect possible group for this device. */ - rc = lcs_auto_get_devid(devid, &devid->devid[0], - err_delayed_print); - if (rc) { - error("Auto-detection failed for %s %s\n" - "Please be sure to specify full CCWGROUP ID!\n", - st->devname, dev->id); - return rc; - } - free(dev->id); - dev->id = ccwgroup_devid_to_str(dev->devid); - } - - dev->active.definable = 1; - - return EXIT_OK; -} - -static void lcs_st_add_definable_ids(struct subtype *st, struct util_list *ids) -{ - lcs_auto_add_ids(ids); -} - -/* - * LCS subtype. - */ - -static struct ccwgroup_subtype_data lcs_data = { - .ccwgroupdrv = LCS_CCWGROUPDRV_NAME, - .ccwdrv = LCS_CCWDRV_NAME, - .rootdrv = LCS_ROOTDRV_NAME, - .mod = LCS_MOD_NAME, - .num_devs = LCS_NUM_DEVS, -}; - -static struct subtype lcs_subtype = { - .super = &ccwgroup_subtype, - .devtype = &lcs_devtype, - .name = "lcs", - .title = "LAN-Channel-Station (LCS) network devices", - .devname = DEVNAME, - .modules = STRING_ARRAY(LCS_MOD_NAME), - .namespace = &lcs_namespace, - .data = &lcs_data, - - .dev_attribs = ATTRIB_ARRAY( - &ccw_attr_online, - &lcs_attr_lancmd_timeout, - &lcs_attr_recover, - &internal_attr_early, - ), - .unknown_dev_attribs = 1, - .support_definable = 1, - - .is_definable = &lcs_st_is_definable, - .detect_definable = &lcs_st_detect_definable, - .add_definable_ids = &lcs_st_add_definable_ids, -}; - -/* - * LCS devtype methods. - */ - -/* Clean up all resources used by devtype object. */ -static void lcs_devtype_exit(struct devtype *dt) -{ - setting_list_free(dt->active_settings); - setting_list_free(dt->persistent_settings); -} - -static exit_code_t lcs_devtype_read_settings(struct devtype *dt, - config_t config) -{ - /* No kernel or module parameters exist for the lcs device driver, - * but at least determine module loaded state. */ - dt->active_settings = setting_list_new(); - dt->persistent_settings = setting_list_new(); - - if (SCOPE_ACTIVE(config)) - dt->active_exists = devtype_is_module_loaded(dt); - - return EXIT_OK; -} - -static exit_code_t lcs_devtype_write_settings(struct devtype *dt, - config_t config) -{ - /* No kernel or module parameters exist for the lcs device driver. */ - - return EXIT_OK; -} - -/* - * LCS devtype. - */ - -struct devtype lcs_devtype = { - .name = "lcs", - .title = "", /* Only use subtypes. */ - .devname = "LCS", - - .subtypes = SUBTYPE_ARRAY( - &lcs_subtype, - ), - - .type_attribs = ATTRIB_ARRAY( - ), - - .exit = &lcs_devtype_exit, - - .read_settings = &lcs_devtype_read_settings, - .write_settings = &lcs_devtype_write_settings, -}; diff --git a/zdev/src/lcs_auto.c b/zdev/src/lcs_auto.c deleted file mode 100644 index 848897cb..00000000 --- a/zdev/src/lcs_auto.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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 - -#include "lib/util_path.h" - -#include "ccw.h" -#include "ccwgroup.h" -#include "ctc.h" -#include "lcs.h" -#include "lcs_auto.h" -#include "module.h" -#include "path.h" - -struct cutype { - unsigned int cutype:16; - unsigned int cumodel:8; -}; - -static struct cutype lcs_cutypes[] = { - { .cutype = 0x3088, .cumodel = 0x08, }, - { .cutype = 0x3088, .cumodel = 0x1f, }, - { .cutype = 0x3088, .cumodel = 0x60, }, -}; - -/* - * LCS autodetection - * - * A LCS device must be grouped before it can be used. The following - * rules apply to grouping: - * - * 1. A LCS device can be grouped from 2 CCW devices - * a) Read device - * b) Write device - * 2. All CCW devices must be bound to the LCS CCW device driver. Note that - * due to an overlap in CU-Types, CCW device could also be bound to - * the LCS device driver. - * 3. The subchannel of all CCW devices must be defined with the same CHPID - * 4. None of the CCW devices is part of an existing CCWGROUP device - */ - -/* Compare by: 1. CHPID, 2. CUTYPE, 3. DEVTYPE, 4. CCW device ID - * -1 = a < b 1 = a > b 0 = a == b. */ -static int info_cmp(void *a, void *b, void *data) -{ - struct ptrlist_node *pa = a, *pb = b; - struct ccw_devinfo *ia = pa->ptr, *ib = pb->ptr; - int r; - - r = ccw_devinfo_chpids_cmp(ia, ib); - if (r) - return r; - - r = ccw_devinfo_cutype_cmp(ia, ib); - if (r) - return r; - - r = ccw_devinfo_devtype_cmp(ia, ib); - if (r) - return r; - - return ccw_cmp_devids(&ia->devid, &ib->devid); -} - -static bool is_compatible(struct ccw_devinfo *a, struct ccw_devinfo *b) -{ - if (ccw_devinfo_chpids_cmp(a, b) == 0 && - ccw_devinfo_cutype_cmp(a, b) == 0 && - ccw_devinfo_devtype_cmp(a, b) == 0) - return true; - - return false; -} - -static bool is_lcs(struct ccw_devinfo *info) -{ - unsigned int i; - - /* Rule out devices which can be confirmed to be CTC devices. */ - if (ctc_confirm(&info->devid)) - return false; - - for (i = 0; i < ARRAY_SIZE(lcs_cutypes); i++) { - if (info->cutype == lcs_cutypes[i].cutype && - info->cumodel == lcs_cutypes[i].cumodel) - return true; - } - - return false; -} - -/* Add device info for all LCS CCW devices to ptrlist in data. */ -static exit_code_t add_cb(const char *path, const char *filename, void *data) -{ - struct ccw_devid devid; - struct util_list *infos = data; - struct ccw_devinfo *devinfo; - - if (!strchr(filename, '.')) - return EXIT_OK; - if (!ccw_parse_devid_simple(&devid, filename)) - return EXIT_OK; - devinfo = ccw_devinfo_get(&devid, 0); - if (devinfo->exists && is_lcs(devinfo)) - ptrlist_add(infos, devinfo); - else - free(devinfo); - - return EXIT_OK; -} - -/* Return a sorted ptrlist of struct ccw_devinfos for all CCW devices - * bound to the lcs or ctc CCW device driver with matching CUTYPE. - * The result must be freed using ptrlist_free(,1); */ -static struct util_list *read_sorted_lcs_devinfos(void) -{ - struct util_list *infos; - char *path; - - /* Get CHPID information for all devices handled by the LCS driver. */ - infos = ptrlist_new(); - - /* Add CCW devices bound to the LCS CCW device driver. */ - module_try_load_once(LCS_MOD_NAME, NULL); - path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME); - if (util_path_is_dir(path)) - path_for_each(path, add_cb, infos); - free(path); - - /* Add CCW devices bound to the CTC CCW device driver. */ - path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME); - if (util_path_is_dir(path)) - path_for_each(path, add_cb, infos); - free(path); - - /* For each CHPID: Find groups. Add to result list. */ - util_list_sort(infos, info_cmp, NULL); - - return infos; -} - -static void add_ccwgroup_devid(struct util_list *devids, struct ccw_devid *read, - struct ccw_devid *write) -{ - struct ccwgroup_devid devid; - - devid.devid[0] = *read; - devid.devid[1] = *write; - devid.num = LCS_NUM_DEVS; - - ptrlist_add(devids, ccwgroup_copy_devid(&devid)); -} - -static void add_groupable_devids(struct util_list *devids, - struct util_list *infos) -{ - struct ptrlist_node *curr, *next; - struct ccw_devinfo *r, *w; - - /* For each CHPID: Find groups. Add to result list. */ - curr = util_list_start(infos); - while (curr) { - next = util_list_next(infos, curr); - if (!next) - break; - r = curr->ptr; - w = next->ptr; - if (is_compatible(r, w) && EVEN(r->devid.devno) && - ccw_devid_distance(&r->devid, &w->devid) == 1) { - add_ccwgroup_devid(devids, &r->devid, &w->devid); - curr = util_list_next(infos, next); - } else - curr = next; - } -} - -/* Add CCWGROUP IDs of lcs devices that can be grouped to strlist @ids. */ -void lcs_auto_add_ids(struct util_list *ids) -{ - struct util_list *infos, *devids; - struct ptrlist_node *p; - char *id; - - infos = read_sorted_lcs_devinfos(); - devids = ptrlist_new(); - add_groupable_devids(devids, infos); - - util_list_iterate(devids, p) { - id = ccwgroup_devid_to_str(p->ptr); - strlist_add(ids, id); - free(id); - } - - ptrlist_free(devids, 1); - ptrlist_free(infos, 1); -} - -exit_code_t lcs_auto_get_devid(struct ccwgroup_devid *devid_ptr, - struct ccw_devid *ccw_devid, err_t err) -{ - struct util_list *devids, *infos; - struct ptrlist_node *p, *read, *write; - struct ccw_devinfo *r, *w; - struct ccwgroup_devid *devid; - exit_code_t rc; - - infos = read_sorted_lcs_devinfos(); - - /* Try to find an ID from the canonical auto-generated list. */ - devids = ptrlist_new(); - add_groupable_devids(devids, infos); - - util_list_iterate(devids, p) { - devid = p->ptr; - if (ccw_cmp_devids(ccw_devid, &devid->devid[0]) != 0) - continue; - rc = EXIT_OK; - if (devid_ptr) - *devid_ptr = *devid; - goto out; - } - - /* Try to create a CCWGROUP ID with the specified ID as read device. */ - - /* Get CCW device info for read device. */ - read = NULL; - util_list_iterate(infos, read) { - r = read->ptr; - if (ccw_cmp_devids(&r->devid, ccw_devid) == 0) - break; - } - if (!read) { - err_t_print(err, "Read CCW device not found\n"); - rc = EXIT_GROUP_NOT_FOUND; - goto out; - } - if (!EVEN(r->devid.devno)) { - err_t_print(err, "Read CCW device number not even\n"); - rc = EXIT_GROUP_INVALID; - goto out; - } - - /* Get CCW device ID for write device. */ - write = util_list_next(infos, read); - if (!write) { - err_t_print(err, "Write CCW device not found\n"); - rc = EXIT_GROUP_NOT_FOUND; - goto out; - } - w = write->ptr; - if (!is_compatible(r, w)) { - err_t_print(err, "No compatible write CCW device found\n"); - rc = EXIT_GROUP_INVALID; - goto out; - } - if (ccw_devid_distance(&r->devid, &w->devid) != 1) { - err_t_print(err, "Write CCW device ID must be read plus one\n"); - rc = EXIT_GROUP_INVALID; - goto out; - } - - rc = EXIT_OK; - if (devid_ptr) { - devid_ptr->devid[0] = r->devid; - devid_ptr->devid[1] = w->devid; - devid_ptr->num = LCS_NUM_DEVS; - } - -out: - ptrlist_free(devids, 1); - ptrlist_free(infos, 1); - - return rc; -} - -exit_code_t lcs_auto_is_possible(struct ccwgroup_devid *devid, err_t err) -{ - struct ccw_devinfo *info[LCS_NUM_DEVS]; - unsigned int i; - char *ccwid; - const char *msg; - exit_code_t rc; - - if (devid->num < LCS_NUM_DEVS) { - err_t_print(err, "Not enough CCW device IDs in LCS device " - "ID\n"); - return EXIT_INCOMPLETE_ID; - } - if (devid->num > LCS_NUM_DEVS) { - err_t_print(err, "LCS device ID contains too many CCW device " - "IDs\n"); - return EXIT_INVALID_ID; - } - if (ccw_devid_distance(&devid->devid[0], &devid->devid[1]) != 1) { - err_t_print(err, "Write device ID must be read plus one\n"); - return EXIT_GROUP_INVALID; - } - if (!EVEN(devid->devid[0].devno)) { - err_t_print(err, "Device number of read device ID must be " - "even\n"); - return EXIT_GROUP_INVALID; - } - - for (i = 0; i < ARRAY_SIZE(info); i++) - info[i] = ccw_devinfo_get(&devid->devid[i], 1); - - rc = EXIT_OK; - msg = NULL; - for (i = 0; i < ARRAY_SIZE(info); i++) { - if (!info[i]->exists) { - msg = "CCW device %s does not exist\n"; - rc = EXIT_GROUP_NOT_FOUND; - } else if (info[i]->grouped) { - msg = "CCW device %s already grouped\n"; - rc = EXIT_GROUP_ALREADY; - } else if (i > 0 && - ccw_devinfo_chpids_cmp(info[i - 1], info[i]) != 0) { - msg = "CCW device %s is not on the same CHPID\n"; - rc = EXIT_GROUP_INVALID; - } else if (i > 0 && - ccw_devinfo_cutype_cmp(info[i - 1], info[i]) != 0) { - msg = "CUTYPE of CCW device %s differs\n"; - rc = EXIT_GROUP_INVALID; - } else if (i > 0 && - ccw_devinfo_devtype_cmp(info[i - 1], info[i]) != 0) { - msg = "DEVTYPE of CCW device %s differs\n"; - rc = EXIT_GROUP_INVALID; - } - if (!msg) - continue; - ccwid = ccw_devid_to_str(&devid->devid[i]); - err_t_print(err, msg, ccwid); - free(ccwid); - break; - } - - for (i = 0; i < ARRAY_SIZE(info); i++) - free(info[i]); - - return rc; -} diff --git a/zdev/src/namespace.c b/zdev/src/namespace.c index f0ed3c97..b4c3d754 100644 --- a/zdev/src/namespace.c +++ b/zdev/src/namespace.c @@ -13,7 +13,6 @@ #include "ccw.h" #include "ctc.h" #include "devtype.h" -#include "lcs.h" #include "namespace.h" #include "qeth.h" #include "zfcp_lun.h" @@ -24,7 +23,6 @@ struct namespace *namespaces[] = { &zfcp_lun_namespace, &qeth_namespace, &ctc_namespace, - &lcs_namespace, &ap_namespace, NULL, };