diff --git a/zconf/chp/chpstat/chpstat.c b/zconf/chp/chpstat/chpstat.c index ee6da600..1b0cf8c4 100644 --- a/zconf/chp/chpstat/chpstat.c +++ b/zconf/chp/chpstat/chpstat.c @@ -702,16 +702,29 @@ err: /* * Read the channel-measurements characteristics block for CHPID @chpid to - * @cmcb. + * @cmcb. Return %true if full CMCB was read, %false otherwise. */ -static void read_cmcb(int chpid, cmcb_t *cmcb) +static bool read_cmcb(int chpid, cmcb_t *cmcb) { + bool full = false; char *path; memset(cmcb, 0, sizeof(*cmcb)); - path = get_chpid_path(chpid, "measurement_chars"); - read_bin(path, cmcb, sizeof(*cmcb), false); + path = get_chpid_path(chpid, "measurement_chars_full"); + if (util_path_exists(path)) { + /* Full CMCB starts at offset 0. */ + read_bin(path, cmcb, CMCB_SIZE, false); + full = true; + } else { + free(path); + path = get_chpid_path(chpid, "measurement_chars"); + /* Partial CMCB contains data starting at word 3. */ + read_bin(path, &cmcb[PARTIAL_CMCB_OFFSET], + PARTIAL_CMCB_SIZE, false); + } free(path); + + return full; } /* @@ -828,7 +841,7 @@ static bool select_chpid(int chpid, bool try) c->shared = read_chpid_attr_as_int(chpid, "shared", 10); c->speed = read_speed(chpid); if (cmg_t->has_cmcb) - read_cmcb(chpid, &c->data.cmcb); + c->data.full_cmcb = read_cmcb(chpid, &c->data.cmcb); read_util(chpid, cmg, &c->data.util_a); c->data.util_b = c->data.util_a; c->selected = true; diff --git a/zconf/chp/chpstat/cmg.h b/zconf/chp/chpstat/cmg.h index bd9e58c9..7b78d060 100644 --- a/zconf/chp/chpstat/cmg.h +++ b/zconf/chp/chpstat/cmg.h @@ -16,7 +16,9 @@ #include "lib/util_list.h" #include "column.h" -#define CMCB_SIZE (5 * sizeof(u32)) +#define CMCB_SIZE (8 * sizeof(u32)) +#define PARTIAL_CMCB_OFFSET 3 +#define PARTIAL_CMCB_SIZE (CMCB_SIZE - PARTIAL_CMCB_OFFSET * sizeof(u32)) #define CUE_SIZE (8 * sizeof(u32)) #define EXT_CUE_SIZE (16 * sizeof(u32)) #define METRICS_SIZE (17 * sizeof(double)) @@ -44,6 +46,7 @@ struct util_t { /* CMG-specific CHPID data. */ struct cmg_data_t { cmcb_t cmcb; + bool full_cmcb; struct util_t util_a; struct util_t util_b; metrics_t metrics; diff --git a/zconf/chp/chpstat/cmg2.c b/zconf/chp/chpstat/cmg2.c index 84ec037b..0d84b9d8 100644 --- a/zconf/chp/chpstat/cmg2.c +++ b/zconf/chp/chpstat/cmg2.c @@ -22,6 +22,7 @@ /* CMG 2 format Channel-Measurement-Characteristics Block (CMCB). */ struct cmcb2_t { + u32 reserved[3]; u32 max_bus_cycles; u32 max_channel_work_units; u32 max_write_data_units; diff --git a/zconf/chp/chpstat/cmg3.c b/zconf/chp/chpstat/cmg3.c index 4ab38504..21fa8fa7 100644 --- a/zconf/chp/chpstat/cmg3.c +++ b/zconf/chp/chpstat/cmg3.c @@ -21,6 +21,7 @@ /* CMG 3 format Channel-Measurement-Characteristics Block (CMCB). */ struct cmcb3_t { + u32 reserved[3]; u32 data_unit_size; u32 data_unit_size_cpc; u32 msg_unit_size;