diff options
Diffstat (limited to 'drivers/s390/crypto')
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 98 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.h | 22 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex2a.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_mono.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcica.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcicc.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 2 |
8 files changed, 98 insertions, 34 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 16e4a25596e..b77ae519d79 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -6,6 +6,7 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> * Ralph Wuerthner <rwuerthn@de.ibm.com> * Felix Beck <felix.beck@de.ibm.com> + * Holger Dengler <hd@linux.vnet.ibm.com> * * Adjunct processor bus. * @@ -40,7 +41,7 @@ #include <linux/mutex.h> #include <asm/reset.h> #include <asm/airq.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/system.h> #include <asm/isc.h> #include <linux/hrtimer.h> @@ -222,47 +223,52 @@ ap_queue_interruption_control(ap_qid_t qid, void *ind) } #endif -static inline struct ap_queue_status __ap_4096_commands_available(ap_qid_t qid, - int *support) +#ifdef CONFIG_64BIT +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"); - register unsigned long reg2 asm ("2") = 0UL; + register struct ap_queue_status reg1 asm ("1") = AP_QUEUE_STATUS_INVALID; + register unsigned long reg2 asm ("2"); asm volatile( ".long 0xb2af0000\n" - "0: la %1,0\n" - "1:\n" - EX_TABLE(0b, 1b) - : "+d" (reg0), "=d" (reg1), "=d" (reg2) + "0:\n" + EX_TABLE(0b, 0b) + : "+d" (reg0), "+d" (reg1), "=d" (reg2) : : "cc"); - if (reg2 & 0x6000000000000000ULL) - *support = 1; - else - *support = 0; - + *functions = (unsigned int)(reg2 >> 32); return reg1; } +#endif /** - * ap_4096_commands_availablen(): Check for availability of 4096 bit RSA - * support. + * ap_query_functions(): Query supported functions. * @qid: The AP queue number + * @functions: Pointer to functions field. * - * Returns 1 if 4096 bit RSA keys are support fo the AP, returns 0 if not. + * Returns + * 0 on success. + * -ENODEV if queue not valid. + * -EBUSY if device busy. + * -EINVAL if query function is not supported */ -int ap_4096_commands_available(ap_qid_t qid) +static int ap_query_functions(ap_qid_t qid, unsigned int *functions) { +#ifdef CONFIG_64BIT struct ap_queue_status status; - int i, support = 0; - status = __ap_4096_commands_available(qid, &support); + int i; + status = __ap_query_functions(qid, functions); for (i = 0; i < AP_MAX_RESET; i++) { + if (ap_queue_status_invalid_test(&status)) + return -ENODEV; + switch (status.response_code) { case AP_RESPONSE_NORMAL: - return support; + return 0; case AP_RESPONSE_RESET_IN_PROGRESS: case AP_RESPONSE_BUSY: break; @@ -270,7 +276,7 @@ int ap_4096_commands_available(ap_qid_t qid) case AP_RESPONSE_DECONFIGURED: case AP_RESPONSE_CHECKSTOPPED: case AP_RESPONSE_INVALID_ADDRESS: - return 0; + return -ENODEV; case AP_RESPONSE_OTHERWISE_CHANGED: break; default: @@ -278,10 +284,31 @@ int ap_4096_commands_available(ap_qid_t qid) } if (i < AP_MAX_RESET - 1) { udelay(5); - status = __ap_4096_commands_available(qid, &support); + status = __ap_query_functions(qid, functions); } } - return support; + return -EBUSY; +#else + return -EINVAL; +#endif +} + +/** + * ap_4096_commands_availablen(): Check for availability of 4096 bit RSA + * support. + * @qid: The AP queue number + * + * Returns 1 if 4096 bit RSA keys are support fo the AP, returns 0 if not. + */ +int ap_4096_commands_available(ap_qid_t qid) +{ + unsigned int functions; + + if (ap_query_functions(qid, &functions)) + return 0; + + return test_ap_facility(functions, 1) && + test_ap_facility(functions, 2); } EXPORT_SYMBOL(ap_4096_commands_available); @@ -1135,6 +1162,7 @@ static void ap_scan_bus(struct work_struct *unused) struct device *dev; ap_qid_t qid; int queue_depth, device_type; + unsigned int device_functions; int rc, i; if (ap_select_domain() != 0) @@ -1183,14 +1211,30 @@ 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); - if (device_type == 0) { + switch (device_type) { + case 0: if (ap_probe_device_type(ap_dev)) { kfree(ap_dev); continue; } - } - else + break; + case 10: + if (ap_query_functions(qid, &device_functions)) { + kfree(ap_dev); + continue; + } + if (test_ap_facility(device_functions, 3)) + ap_dev->device_type = AP_DEVICE_TYPE_CEX3C; + else if (test_ap_facility(device_functions, 4)) + ap_dev->device_type = AP_DEVICE_TYPE_CEX3A; + else { + kfree(ap_dev); + continue; + } + break; + default: ap_dev->device_type = device_type; + } ap_dev->device.bus = &ap_bus_type; ap_dev->device.parent = ap_root_device; diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 08b9738285b..d960a6309ee 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -6,6 +6,7 @@ * Martin Schwidefsky <schwidefsky@de.ibm.com> * Ralph Wuerthner <rwuerthn@de.ibm.com> * Felix Beck <felix.beck@de.ibm.com> + * Holger Dengler <hd@linux.vnet.ibm.com> * * Adjunct processor bus header file. * @@ -72,7 +73,26 @@ struct ap_queue_status { unsigned int int_enabled : 1; unsigned int response_code : 8; 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 MAX_AP_FACILITY 31 + +static inline int test_ap_facility(unsigned int function, unsigned int nr) +{ + if (nr > MAX_AP_FACILITY) + return 0; + return function & (unsigned int)(0x80000000 >> nr); +} #define AP_RESPONSE_NORMAL 0x00 #define AP_RESPONSE_Q_NOT_AVAIL 0x01 diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 8e65447f76b..88ad33ed5d3 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -36,7 +36,7 @@ #include <linux/seq_file.h> #include <linux/compat.h> #include <linux/slab.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include <linux/hw_random.h> diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 2176d00b395..da171b5f399 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c @@ -30,7 +30,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/err.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include "ap_bus.h" diff --git a/drivers/s390/crypto/zcrypt_mono.c b/drivers/s390/crypto/zcrypt_mono.c index 44253fdd413..eb313c3fb2d 100644 --- a/drivers/s390/crypto/zcrypt_mono.c +++ b/drivers/s390/crypto/zcrypt_mono.c @@ -32,7 +32,7 @@ #include <linux/fs.h> #include <linux/proc_fs.h> #include <linux/compat.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include "ap_bus.h" diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 1afb69c75fe..d84816f144d 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c @@ -30,7 +30,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/err.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include "ap_bus.h" diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index aa4c050a569..bdbdbe19299 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c @@ -30,7 +30,7 @@ #include <linux/init.h> #include <linux/gfp.h> #include <linux/err.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include "ap_bus.h" diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 4f85eb725f4..dd4737808e0 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c @@ -31,7 +31,7 @@ #include <linux/err.h> #include <linux/delay.h> #include <linux/slab.h> -#include <asm/atomic.h> +#include <linux/atomic.h> #include <asm/uaccess.h> #include "ap_bus.h" |