s390/zcrypt: remove duplicate low level functions
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 26 Jun 2015 13:40:41 +0000 (15:40 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 14 Oct 2015 12:32:19 +0000 (14:32 +0200)
ap_test_queue, ap_query_facilities, __ap_query_functions all use
the same PQAP(TAPQ) command. Consolidate the three into a single
ap_test_queue function that returns the AP status and the 64-bit
result. The exception table entry for PQAP(TAPQ) can be avoided
if the T bit for the APFT facility is set only if test_facility(15)
indicated that the facility is present.

Integrate ap_query_function into ap_query queue to avoid calling
PQAP(TAPQ) twice.

Reviewed-by: Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h

index d78b3d629d78dd9175736b99a2ac2a14adaf26c9..613c92b22445288880d6f84454002022fa365aea 100644 (file)
@@ -182,43 +182,26 @@ static int ap_configuration_available(void)
 /**
  * ap_test_queue(): Test adjunct processor queue.
  * @qid: The AP queue number
- * @queue_depth: Pointer to queue depth value
- * @device_type: Pointer to device type value
+ * @info: Pointer to queue descriptor
  *
  * Returns AP queue status structure.
  */
 static inline struct ap_queue_status
-ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type)
+ap_test_queue(ap_qid_t qid, unsigned long *info)
 {
        register unsigned long reg0 asm ("0") = qid;
        register struct ap_queue_status reg1 asm ("1");
        register unsigned long reg2 asm ("2") = 0UL;
 
+       if (test_facility(15))
+               reg0 |= 1UL << 23;              /* set APFT T bit*/
        asm volatile(".long 0xb2af0000"         /* PQAP(TAPQ) */
                     : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
-       *device_type = (int) (reg2 >> 24);
-       *queue_depth = (int) (reg2 & 0xff);
+       if (info)
+               *info = reg2;
        return reg1;
 }
 
-/**
- * ap_query_facilities(): PQAP(TAPQ) query facilities.
- * @qid: The AP queue number
- *
- * Returns content of general register 2 after the PQAP(TAPQ)
- * instruction was called.
- */
-static inline unsigned long ap_query_facilities(ap_qid_t qid)
-{
-       register unsigned long reg0 asm ("0") = qid | 0x00800000UL;
-       register unsigned long reg1 asm ("1");
-       register unsigned long reg2 asm ("2") = 0UL;
-
-       asm volatile(".long 0xb2af0000"  /* PQAP(TAPQ) */
-                    : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc");
-       return reg2;
-}
-
 /**
  * ap_reset_queue(): Reset adjunct processor queue.
  * @qid: The AP queue number
@@ -259,25 +242,6 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind)
        return reg1_out;
 }
 
-static inline struct ap_queue_status
-__ap_query_functions(ap_qid_t qid, unsigned int *functions)
-{
-       register unsigned long reg0 asm ("0") = 0UL | qid | (1UL << 23);
-       register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID;
-       register unsigned long reg2 asm ("2");
-
-       asm volatile(
-               ".long 0xb2af0000\n"            /* PQAP(TAPQ) */
-               "0:\n"
-               EX_TABLE(0b, 0b)
-               : "+d" (reg0), "+d" (reg1), "=d" (reg2)
-               :
-               : "cc");
-
-       *functions = (unsigned int)(reg2 >> 32);
-       return reg1;
-}
-
 static inline int __ap_query_configuration(struct ap_config_info *config)
 {
        register unsigned long reg0 asm ("0") = 0x04000000UL;
@@ -296,42 +260,6 @@ static inline int __ap_query_configuration(struct ap_config_info *config)
        return reg1;
 }
 
-/**
- * ap_query_functions(): Query supported functions.
- * @qid: The AP queue number
- * @functions: Pointer to functions field.
- *
- * Returns
- *   0      on success.
- *   -ENODEV  if queue not valid.
- *   -EBUSY   if device busy.
- *   -EINVAL  if query function is not supported
- */
-static int ap_query_functions(ap_qid_t qid, unsigned int *functions)
-{
-       struct ap_queue_status status;
-
-       status = __ap_query_functions(qid, functions);
-
-       if (ap_queue_status_invalid_test(&status))
-               return -ENODEV;
-
-       switch (status.response_code) {
-       case AP_RESPONSE_NORMAL:
-               return 0;
-       case AP_RESPONSE_Q_NOT_AVAIL:
-       case AP_RESPONSE_DECONFIGURED:
-       case AP_RESPONSE_CHECKSTOPPED:
-       case AP_RESPONSE_INVALID_ADDRESS:
-               return -ENODEV;
-       case AP_RESPONSE_RESET_IN_PROGRESS:
-       case AP_RESPONSE_BUSY:
-       case AP_RESPONSE_OTHERWISE_CHANGED:
-       default:
-               return -EBUSY;
-       }
-}
-
 /**
  * ap_queue_enable_interruption(): Enable interruption on an AP.
  * @qid: The AP queue number
@@ -515,17 +443,20 @@ static inline void ap_schedule_poll_timer(void)
  * @qid: The AP queue number
  * @queue_depth: Pointer to queue depth value
  * @device_type: Pointer to device type value
+ * @facilities: Pointer to facility indicator
  */
-static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type)
+static int ap_query_queue(ap_qid_t qid, int *queue_depth, int *device_type,
+                         unsigned int *facilities)
 {
        struct ap_queue_status status;
-       int t_depth, t_device_type;
+       unsigned long info;
 
-       status = ap_test_queue(qid, &t_depth, &t_device_type);
+       status = ap_test_queue(qid, &info);
        switch (status.response_code) {
        case AP_RESPONSE_NORMAL:
-               *queue_depth = t_depth + 1;
-               *device_type = t_device_type;
+               *queue_depth = (int)(info & 0xff);
+               *device_type = (int)((info >> 24) & 0xff);
+               *facilities = (unsigned int)(info >> 32);
                return 0;
        case AP_RESPONSE_Q_NOT_AVAIL:
        case AP_RESPONSE_DECONFIGURED:
@@ -1184,6 +1115,7 @@ static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store);
 
 static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
 {
+       struct ap_queue_status status;
        ap_qid_t qid;
        int i, nd, max_domain_id = -1;
        unsigned long fbits;
@@ -1194,7 +1126,9 @@ static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf)
                                if (!ap_test_config_card_id(i))
                                        continue;
                                qid = AP_MKQID(i, ap_domain_index);
-                               fbits = ap_query_facilities(qid);
+                               status = ap_test_queue(qid, &fbits);
+                               if (status.response_code != AP_RESPONSE_NORMAL)
+                                       continue;
                                if (fbits & (1UL << 57)) {
                                        /* the N bit is 0, Nd field is filled */
                                        nd = (int)((fbits & 0x00FF0000UL)>>16);
@@ -1254,9 +1188,9 @@ static void ap_query_configuration(void)
  */
 static int ap_select_domain(void)
 {
-       int queue_depth, device_type, count, max_count, best_domain;
-       ap_qid_t qid;
-       int rc, i, j;
+       int count, max_count, best_domain;
+       struct ap_queue_status status;
+       int i, j;
 
        /* IF APXA isn't installed, only 16 domains could be defined */
        if (!ap_configuration->ap_extended && (ap_domain_index > 15))
@@ -1279,9 +1213,8 @@ static int ap_select_domain(void)
                for (j = 0; j < AP_DEVICES; j++) {
                        if (!ap_test_config_card_id(j))
                                continue;
-                       qid = AP_MKQID(j, i);
-                       rc = ap_query_queue(qid, &queue_depth, &device_type);
-                       if (rc)
+                       status = ap_test_queue(AP_MKQID(j, i), NULL);
+                       if (status.response_code != AP_RESPONSE_NORMAL)
                                continue;
                        count++;
                }
@@ -1438,7 +1371,8 @@ static void ap_scan_bus(struct work_struct *unused)
                                      (void *)(unsigned long)qid,
                                      __ap_scan_bus);
                if (ap_test_config_card_id(i))
-                       rc = ap_query_queue(qid, &queue_depth, &device_type);
+                       rc = ap_query_queue(qid, &queue_depth, &device_type,
+                                           &device_functions);
                else
                        rc = -ENODEV;
                if (dev) {
@@ -1468,6 +1402,9 @@ static void ap_scan_bus(struct work_struct *unused)
                        continue;
                }
                ap_dev->queue_depth = queue_depth;
+               ap_dev->raw_hwtype = device_type;
+               ap_dev->device_type = device_type;
+               ap_dev->functions = device_functions;
                ap_dev->unregistered = 1;
                spin_lock_init(&ap_dev->lock);
                INIT_LIST_HEAD(&ap_dev->pendingq);
@@ -1475,24 +1412,12 @@ static void ap_scan_bus(struct work_struct *unused)
                INIT_LIST_HEAD(&ap_dev->list);
                setup_timer(&ap_dev->timeout, ap_request_timeout,
                            (unsigned long) ap_dev);
-               switch (device_type) {
-               case 0:
+               if (ap_dev->device_type == 0)
                        /* device type probing for old cards */
                        if (ap_probe_device_type(ap_dev)) {
                                kfree(ap_dev);
                                continue;
                        }
-                       break;
-               default:
-                       ap_dev->device_type = device_type;
-               }
-               ap_dev->raw_hwtype = device_type;
-
-               rc = ap_query_functions(qid, &device_functions);
-               if (!rc)
-                       ap_dev->functions = device_functions;
-               else
-                       ap_dev->functions = 0u;
 
                ap_dev->device.bus = &ap_bus_type;
                ap_dev->device.parent = ap_root_device;
@@ -1640,12 +1565,11 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags)
  */
 static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
 {
-       int rc, depth, type;
        struct ap_queue_status status;
-
+       int rc;
 
        if (ap_dev->reset == AP_RESET_IN_PROGRESS) {
-               status = ap_test_queue(ap_dev->qid, &depth, &type);
+               status = ap_test_queue(ap_dev->qid, NULL);
                switch (status.response_code) {
                case AP_RESPONSE_NORMAL:
                        ap_dev->reset = AP_RESET_IGNORE;
@@ -1676,7 +1600,7 @@ static inline int ap_poll_queue(struct ap_device *ap_dev, unsigned long *flags)
 
        if ((ap_dev->reset != AP_RESET_IN_PROGRESS) &&
                (ap_dev->interrupt == AP_INTR_IN_PROGRESS)) {
-               status = ap_test_queue(ap_dev->qid, &depth, &type);
+               status = ap_test_queue(ap_dev->qid, NULL);
                if (ap_using_interrupts()) {
                        if (status.int_enabled == 1)
                                ap_dev->interrupt = AP_INTR_ENABLED;
index 00468c8d0781c59aa817e4d9bb7b6f4d6f15a2e6..2e0a21f84f3d3b72d26cd0d3dddd49ecfbf773e1 100644 (file)
@@ -75,15 +75,6 @@ struct ap_queue_status {
        unsigned int pad2               : 16;
 } __packed;
 
-#define AP_QUEUE_STATUS_INVALID \
-               { 1, 1, 1, 0xF, 1, 0xFF, 0xFFFF }
-
-static inline
-int ap_queue_status_invalid_test(struct ap_queue_status *status)
-{
-       struct ap_queue_status invalid = AP_QUEUE_STATUS_INVALID;
-       return !(memcmp(status, &invalid, sizeof(struct ap_queue_status)));
-}
 
 #define AP_MAX_BITS 31
 static inline int ap_test_bit(unsigned int *ptr, unsigned int nr)