mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdev: Fix double device configuration on DPM systems
During autoconfig, DPM systems currently configures DASD devices twice:
once for dasd-eckd and once for dasd-fba. Because the firmware
configuration file does not provide the DASD type, this can lead
to inconsistent and redundant configurations.
For example, lszdev may show two devices with the same ID:
TYPE ID ON PERS NAMES
dasd-eckd 0.0.f001 yes auto dasda
dasd-fba 0.0.f001 no auto
However, only dasd-eckd is actually present on the machine, and
the dasd-fba entry is incorrect.
Modify this configuration logic to determine the DASD type dynamically
by parsing the modalias for each device-ID, and configures only the
correct dasd-type. The resulting lszdev output accurately reflects
the actual DASD devices present.
Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
committed by
Steffen Eiden
parent
d1bf9e68c6
commit
f45a45c38c
@@ -29,6 +29,7 @@
|
||||
#include "export.h"
|
||||
#include "firmware.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "qeth.h"
|
||||
#include "subtype.h"
|
||||
#include "zfcp_host.h"
|
||||
@@ -143,6 +144,13 @@ struct fw_qeth {
|
||||
char settings[];
|
||||
} __packed;
|
||||
|
||||
/* Dasd types definitions for rd.dasd parser */
|
||||
enum dasd_type {
|
||||
DASD_NO_DEVICE,
|
||||
DASD_ECKD,
|
||||
DASD_NO_ECKD,
|
||||
};
|
||||
|
||||
/* Emit a warning that refers to a position in a firmware file. */
|
||||
static void fwwarn(struct fw_file *f, const char *fmt, ...)
|
||||
{
|
||||
@@ -491,13 +499,49 @@ static struct device *add_device(struct fw_file *f, struct subtype *st,
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* Return the device-type of the provided device-id by analysing modalias */
|
||||
static enum dasd_type is_eckd(const char *id)
|
||||
{
|
||||
const char * const eckd_type[] = { "3390", "3380", "9345" };
|
||||
size_t i;
|
||||
char *device_path, *buffer;
|
||||
int rc = DASD_NO_ECKD;
|
||||
|
||||
/* Remove the device-id from the blacklist */
|
||||
ccw_unblacklist_id(id);
|
||||
|
||||
/* Do a cio_settle before trying to read the modalias */
|
||||
cio_settle(1);
|
||||
|
||||
device_path = path_get_ccw_device(NULL, id);
|
||||
/* Read the modalias value */
|
||||
buffer = path_read_text_file(1, err_ignore, "%s/modalias",
|
||||
device_path);
|
||||
if (!buffer) {
|
||||
rc = DASD_NO_DEVICE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(eckd_type); i++) {
|
||||
if (strstr(buffer, eckd_type[i])) {
|
||||
rc = DASD_ECKD;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
free(buffer);
|
||||
free(device_path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Parse a DASD device entry. */
|
||||
static void parse_dasd(struct fw_file *f, struct fw_dehdr *de, config_t config,
|
||||
struct util_list *objects)
|
||||
{
|
||||
struct fw_dasd *dasd = (struct fw_dasd *) de;
|
||||
struct ccw_devid devid;
|
||||
struct device *dev_eckd, *dev_fba;
|
||||
struct device *dev_eckd = NULL, *dev_fba = NULL;
|
||||
char *id;
|
||||
|
||||
if (!check_de_size(f, de, sizeof(struct fw_dasd)))
|
||||
@@ -508,8 +552,22 @@ static void parse_dasd(struct fw_file *f, struct fw_dehdr *de, config_t config,
|
||||
/* Could be either dasd_eckd or dasd_fba - add both entries */
|
||||
io_to_ccw(&devid, &dasd->id);
|
||||
id = ccw_devid_to_str(&devid);
|
||||
dev_eckd = add_device(f, &dasd_subtype_eckd, id, config, objects);
|
||||
dev_fba = add_device(f, &dasd_subtype_fba, id, config, objects);
|
||||
|
||||
switch (is_eckd(id)) {
|
||||
case DASD_ECKD:
|
||||
dev_eckd = add_device(f, &dasd_subtype_eckd, id, config,
|
||||
objects);
|
||||
break;
|
||||
case DASD_NO_ECKD:
|
||||
dev_fba = add_device(f, &dasd_subtype_fba, id, config, objects);
|
||||
break;
|
||||
case DASD_NO_DEVICE:
|
||||
fwwarn(f, "DASD device %s does not exist", id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
free(id);
|
||||
|
||||
if (dasd->hdr.len > sizeof(struct fw_dasd)) {
|
||||
|
||||
Reference in New Issue
Block a user