Blob Blame History Raw
From 65cb0f2b0204183617b5d6e8e475f85faa8b789d Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Mon, 14 Feb 2022 16:35:34 +0100
Subject: [PATCH 15/34] EP11: Default unknown CPs to ON

Newer EP11 cards know additional control points that older cards do not
know. When building the combined minimum control point setting, treat
unknown control points as ON, to not disable mechanisms just because an
older card does not know a control point.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
---
 usr/lib/ep11_stdll/ep11_specific.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/usr/lib/ep11_stdll/ep11_specific.c b/usr/lib/ep11_stdll/ep11_specific.c
index 147ce7b2..e3451163 100644
--- a/usr/lib/ep11_stdll/ep11_specific.c
+++ b/usr/lib/ep11_stdll/ep11_specific.c
@@ -10904,13 +10904,18 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
 #ifdef DEBUG
     TRACE_DEBUG("Control points from adapter %02X.%04X\n", adapter, domain);
     TRACE_DEBUG_DUMP("    ", cp, cp_len);
+    TRACE_DEBUG("Max control point index: %lu\n", max_cp_index);
 #endif
 
     if (data->first) {
         data->first_adapter = adapter;
         data->first_domain = domain;
-        memcpy(data->first_cp, cp, cp_len);
-        memcpy(data->combined_cp, cp, cp_len);
+        /* Apply CP bits 0 to max_cp_index-1 only */
+        for (i = 0; i < max_cp_index; i++) {
+            data->combined_cp[CP_BYTE_NO(i)] &=
+                                    (cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
+        }
+        memcpy(data->first_cp, data->combined_cp, sizeof(data->first_cp));
         data->max_cp_index = max_cp_index;
         data->first = 0;
     } else {
@@ -10927,8 +10932,10 @@ static CK_RV control_point_handler(uint_32 adapter, uint_32 domain,
                        data->first_domain);
         }
 
-        for (i = 0; i < cp_len; i++) {
-            data->combined_cp[i] &= cp[i];
+        for (i = 0; i < max_cp_index; i++) {
+            /* Apply CP bits 0 to max_cp_index-1 only */
+            data->combined_cp[CP_BYTE_NO(i)] &=
+                                    (cp[CP_BYTE_NO(i)] | ~CP_BIT_MASK(i));
         }
 
         if (max_cp_index != data->max_cp_index) {
@@ -10973,6 +10980,11 @@ static CK_RV get_control_points(STDLL_TokData_t * tokdata,
     ep11_private_data_t *ep11_data = tokdata->private_data;
 
     memset(&data, 0, sizeof(data));
+    /*
+     * Turn all CPs ON by default, so that newer control points that are unknown
+     * to older cards default to ON. CPs being OFF disable functionality.
+     */
+    memset(data.combined_cp, 0xff, sizeof(data.combined_cp));
     data.first = 1;
     rc = handle_all_ep11_cards(&ep11_data->target_list, control_point_handler,
                                &data);
@@ -10987,6 +10999,7 @@ static CK_RV get_control_points(STDLL_TokData_t * tokdata,
     TRACE_DEBUG("Combined control points from all cards (%lu CPs):\n",
                 data.max_cp_index);
     TRACE_DEBUG_DUMP("    ", cp, *cp_len);
+    TRACE_DEBUG("Max control point index: %lu\n", data.max_cp_index);
     print_control_points(cp, *cp_len, data.max_cp_index);
 #endif
 
-- 
2.16.2.windows.1