summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-13 09:43:20 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-13 09:43:20 -0700
commit6c21e4334adaf1ea0f74349be01adddf40e36a27 (patch)
tree2fe5b781780664caaf44d1e4893662d91e725837 /drivers
parent16e205cf42da1f497b10a4a24f563e6c0d574eec (diff)
parent6a3d1e81a434fc311f224b8be77258bafc18ccc6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull more s390 updates from Martin Schwidefsky: "Three notable larger changes next to the usual bug fixing: - update the email addresses in MAINTAINERS for the s390 folks to use the simpler linux.ibm.com domain instead of the old linux.vnet.ibm.com - an update for the zcrypt device driver that removes some old and obsolete interfaces and add support for up to 256 crypto adapters - a rework of the IPL aka boot code" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (23 commits) s390: correct nospec auto detection init order s390/zcrypt: Support up to 256 crypto adapters. s390/zcrypt: Remove deprecated zcrypt proc interface. s390/zcrypt: Remove deprecated ioctls. s390/zcrypt: Make ap init functions static. MAINTAINERS: update s390 maintainers email addresses s390/ipl: remove reipl_method and dump_method s390/ipl: correct kdump reipl block checksum calculation s390/ipl: remove non-existing functions declaration s390: assume diag308 set always works s390/ipl: avoid adding scpdata to cmdline during ftp/dvd boot s390/ipl: correct ipl parmblock valid checks s390/ipl: rely on diag308 store to get ipl info s390/ipl: move ipl_flags to ipl.c s390/ipl: get rid of ipl_ssid and ipl_devno s390/ipl: unite diag308 and scsi boot ipl blocks s390/ipl: ensure loadparm valid flag is set s390/qdio: lock device while installing IRQ handler s390/qdio: clear intparm during shutdown s390/ccwgroup: require at least one ccw device ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/cio/ccwgroup.c5
-rw-r--r--drivers/s390/cio/cio.c257
-rw-r--r--drivers/s390/cio/ioasm.c24
-rw-r--r--drivers/s390/cio/ioasm.h1
-rw-r--r--drivers/s390/cio/qdio_main.c4
-rw-r--r--drivers/s390/cio/qdio_setup.c2
-rw-r--r--drivers/s390/crypto/ap_bus.c32
-rw-r--r--drivers/s390/crypto/ap_bus.h5
-rw-r--r--drivers/s390/crypto/ap_debug.h3
-rw-r--r--drivers/s390/crypto/pkey_api.c41
-rw-r--r--drivers/s390/crypto/zcrypt_api.c471
-rw-r--r--drivers/s390/crypto/zcrypt_api.h26
12 files changed, 166 insertions, 705 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index bfec1485ca23..5535312602af 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -323,6 +323,9 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
struct ccw_dev_id dev_id;
int rc, i;
+ if (num_devices < 1)
+ return -EINVAL;
+
gdev = kzalloc(sizeof(*gdev) + num_devices * sizeof(gdev->cdev[0]),
GFP_KERNEL);
if (!gdev)
@@ -375,7 +378,7 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
goto error;
}
/* Check if the devices are bound to the required ccw driver. */
- if (gdev->count && gdrv && gdrv->ccw_driver &&
+ if (gdrv && gdrv->ccw_driver &&
gdev->cdev[0]->drv != gdrv->ccw_driver) {
rc = -EINVAL;
goto error;
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 6886b3d34cf8..5130d7c67239 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -25,7 +25,6 @@
#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/setup.h>
-#include <asm/reset.h>
#include <asm/ipl.h>
#include <asm/chpid.h>
#include <asm/airq.h>
@@ -767,262 +766,6 @@ void cio_register_early_subchannels(void)
}
#endif /* CONFIG_CCW_CONSOLE */
-static int
-__disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
-{
- int retry, cc;
-
- cc = 0;
- for (retry=0;retry<3;retry++) {
- schib->pmcw.ena = 0;
- cc = msch(schid, schib);
- if (cc)
- return (cc==3?-ENODEV:-EBUSY);
- if (stsch(schid, schib) || !css_sch_is_valid(schib))
- return -ENODEV;
- if (!schib->pmcw.ena)
- return 0;
- }
- return -EBUSY; /* uhm... */
-}
-
-static int
-__clear_io_subchannel_easy(struct subchannel_id schid)
-{
- int retry;
-
- if (csch(schid))
- return -ENODEV;
- for (retry=0;retry<20;retry++) {
- struct tpi_info ti;
-
- if (tpi(&ti)) {
- tsch(ti.schid, this_cpu_ptr(&cio_irb));
- if (schid_equal(&ti.schid, &schid))
- return 0;
- }
- udelay_simple(100);
- }
- return -EBUSY;
-}
-
-static void __clear_chsc_subchannel_easy(void)
-{
- /* It seems we can only wait for a bit here :/ */
- udelay_simple(100);
-}
-
-static int pgm_check_occured;
-
-static void cio_reset_pgm_check_handler(void)
-{
- pgm_check_occured = 1;
-}
-
-static int stsch_reset(struct subchannel_id schid, struct schib *addr)
-{
- int rc;
-
- pgm_check_occured = 0;
- s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
- rc = stsch(schid, addr);
- s390_base_pgm_handler_fn = NULL;
-
- /* The program check handler could have changed pgm_check_occured. */
- barrier();
-
- if (pgm_check_occured)
- return -EIO;
- else
- return rc;
-}
-
-static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
-{
- struct schib schib;
-
- if (stsch_reset(schid, &schib))
- return -ENXIO;
- if (!schib.pmcw.ena)
- return 0;
- switch(__disable_subchannel_easy(schid, &schib)) {
- case 0:
- case -ENODEV:
- break;
- default: /* -EBUSY */
- switch (schib.pmcw.st) {
- case SUBCHANNEL_TYPE_IO:
- if (__clear_io_subchannel_easy(schid))
- goto out; /* give up... */
- break;
- case SUBCHANNEL_TYPE_CHSC:
- __clear_chsc_subchannel_easy();
- break;
- default:
- /* No default clear strategy */
- break;
- }
- stsch(schid, &schib);
- __disable_subchannel_easy(schid, &schib);
- }
-out:
- return 0;
-}
-
-static atomic_t chpid_reset_count;
-
-static void s390_reset_chpids_mcck_handler(void)
-{
- struct crw crw;
- union mci mci;
-
- /* Check for pending channel report word. */
- mci.val = S390_lowcore.mcck_interruption_code;
- if (!mci.cp)
- return;
- /* Process channel report words. */
- while (stcrw(&crw) == 0) {
- /* Check for responses to RCHP. */
- if (crw.slct && crw.rsc == CRW_RSC_CPATH)
- atomic_dec(&chpid_reset_count);
- }
-}
-
-#define RCHP_TIMEOUT (30 * USEC_PER_SEC)
-static void css_reset(void)
-{
- int i, ret;
- unsigned long long timeout;
- struct chp_id chpid;
-
- /* Reset subchannels. */
- for_each_subchannel(__shutdown_subchannel_easy, NULL);
- /* Reset channel paths. */
- s390_base_mcck_handler_fn = s390_reset_chpids_mcck_handler;
- /* Enable channel report machine checks. */
- __ctl_set_bit(14, 28);
- /* Temporarily reenable machine checks. */
- local_mcck_enable();
- chp_id_init(&chpid);
- for (i = 0; i <= __MAX_CHPID; i++) {
- chpid.id = i;
- ret = rchp(chpid);
- if ((ret == 0) || (ret == 2))
- /*
- * rchp either succeeded, or another rchp is already
- * in progress. In either case, we'll get a crw.
- */
- atomic_inc(&chpid_reset_count);
- }
- /* Wait for machine check for all channel paths. */
- timeout = get_tod_clock_fast() + (RCHP_TIMEOUT << 12);
- while (atomic_read(&chpid_reset_count) != 0) {
- if (get_tod_clock_fast() > timeout)
- break;
- cpu_relax();
- }
- /* Disable machine checks again. */
- local_mcck_disable();
- /* Disable channel report machine checks. */
- __ctl_clear_bit(14, 28);
- s390_base_mcck_handler_fn = NULL;
-}
-
-static struct reset_call css_reset_call = {
- .fn = css_reset,
-};
-
-static int __init init_css_reset_call(void)
-{
- atomic_set(&chpid_reset_count, 0);
- register_reset_call(&css_reset_call);
- return 0;
-}
-
-arch_initcall(init_css_reset_call);
-
-struct sch_match_id {
- struct subchannel_id schid;
- struct ccw_dev_id devid;
- int rc;
-};
-
-static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
-{
- struct schib schib;
- struct sch_match_id *match_id = data;
-
- if (stsch_reset(schid, &schib))
- return -ENXIO;
- if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv &&
- (schib.pmcw.dev == match_id->devid.devno) &&
- (schid.ssid == match_id->devid.ssid)) {
- match_id->schid = schid;
- match_id->rc = 0;
- return 1;
- }
- return 0;
-}
-
-static int reipl_find_schid(struct ccw_dev_id *devid,
- struct subchannel_id *schid)
-{
- struct sch_match_id match_id;
-
- match_id.devid = *devid;
- match_id.rc = -ENODEV;
- for_each_subchannel(__reipl_subchannel_match, &match_id);
- if (match_id.rc == 0)
- *schid = match_id.schid;
- return match_id.rc;
-}
-
-extern void do_reipl_asm(__u32 schid);
-
-/* Make sure all subchannels are quiet before we re-ipl an lpar. */
-void reipl_ccw_dev(struct ccw_dev_id *devid)
-{
- struct subchannel_id uninitialized_var(schid);
-
- s390_reset_system();
- if (reipl_find_schid(devid, &schid) != 0)
- panic("IPL Device not found\n");
- do_reipl_asm(*((__u32*)&schid));
-}
-
-int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
-{
- static struct chsc_sda_area sda_area __initdata;
- struct subchannel_id schid;
- struct schib schib;
-
- schid = *(struct subchannel_id *)&S390_lowcore.subchannel_id;
- if (!schid.one)
- return -ENODEV;
-
- if (schid.ssid) {
- /*
- * Firmware should have already enabled MSS but whoever started
- * the kernel might have initiated a channel subsystem reset.
- * Ensure that MSS is enabled.
- */
- memset(&sda_area, 0, sizeof(sda_area));
- if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS))
- return -ENODEV;
- }
- if (stsch(schid, &schib))
- return -ENODEV;
- if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
- return -ENODEV;
- if (!schib.pmcw.dnv)
- return -ENODEV;
-
- iplinfo->ssid = schid.ssid;
- iplinfo->devno = schib.pmcw.dev;
- iplinfo->is_qdio = schib.pmcw.qf;
- return 0;
-}
-
/**
* cio_tm_start_key - perform start function
* @sch: subchannel on which to perform the start function
diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c
index 4fa9ee1d09fa..14d328338ce2 100644
--- a/drivers/s390/cio/ioasm.c
+++ b/drivers/s390/cio/ioasm.c
@@ -183,30 +183,6 @@ int chsc(void *chsc_area)
}
EXPORT_SYMBOL(chsc);
-static inline int __rchp(struct chp_id chpid)
-{
- register struct chp_id reg1 asm ("1") = chpid;
- int ccode;
-
- asm volatile(
- " lr 1,%1\n"
- " rchp\n"
- " ipm %0\n"
- " srl %0,28"
- : "=d" (ccode) : "d" (reg1) : "cc");
- return ccode;
-}
-
-int rchp(struct chp_id chpid)
-{
- int ccode;
-
- ccode = __rchp(chpid);
- trace_s390_cio_rchp(chpid, ccode);
-
- return ccode;
-}
-
static inline int __rsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h
index 35ad4ddd61e0..4be539cb9adc 100644
--- a/drivers/s390/cio/ioasm.h
+++ b/drivers/s390/cio/ioasm.h
@@ -20,7 +20,6 @@ int ssch(struct subchannel_id schid, union orb *addr);
int csch(struct subchannel_id schid);
int tpi(struct tpi_info *addr);
int chsc(void *chsc_area);
-int rchp(struct chp_id chpid);
int rsch(struct subchannel_id schid);
int hsch(struct subchannel_id schid);
int xsch(struct subchannel_id schid);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index a337281337a7..f4ca72dd862f 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -1207,8 +1207,10 @@ no_cleanup:
qdio_shutdown_thinint(irq_ptr);
/* restore interrupt handler */
- if ((void *)cdev->handler == (void *)qdio_int_handler)
+ if ((void *)cdev->handler == (void *)qdio_int_handler) {
cdev->handler = irq_ptr->orig_handler;
+ cdev->private->intparm = 0;
+ }
spin_unlock_irq(get_ccwdev_lock(cdev));
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 98f3cfdc0d02..439991d71b14 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -507,8 +507,10 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
irq_ptr->aqueue = *ciw;
/* set new interrupt handler */
+ spin_lock_irq(get_ccwdev_lock(irq_ptr->cdev));
irq_ptr->orig_handler = init_data->cdev->handler;
init_data->cdev->handler = qdio_int_handler;
+ spin_unlock_irq(get_ccwdev_lock(irq_ptr->cdev));
return 0;
out_err:
qdio_release_memory(irq_ptr);
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 48d55dc9e986..35a0c2b52f82 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -25,7 +25,6 @@
#include <linux/kthread.h>
#include <linux/mutex.h>
#include <linux/suspend.h>
-#include <asm/reset.h>
#include <asm/airq.h>
#include <linux/atomic.h>
#include <asm/isc.h>
@@ -1197,26 +1196,7 @@ static void ap_config_timeout(struct timer_list *unused)
queue_work(system_long_wq, &ap_scan_work);
}
-static void ap_reset_all(void)
-{
- int i, j;
-
- for (i = 0; i < AP_DOMAINS; i++) {
- if (!ap_test_config_domain(i))
- continue;
- for (j = 0; j < AP_DEVICES; j++) {
- if (!ap_test_config_card_id(j))
- continue;
- ap_rapq(AP_MKQID(j, i));
- }
- }
-}
-
-static struct reset_call ap_reset_call = {
- .fn = ap_reset_all,
-};
-
-int __init ap_debug_init(void)
+static int __init ap_debug_init(void)
{
ap_dbf_info = debug_register("ap", 1, 1,
DBF_MAX_SPRINTF_ARGS * sizeof(long));
@@ -1226,17 +1206,12 @@ int __init ap_debug_init(void)
return 0;
}
-void ap_debug_exit(void)
-{
- debug_unregister(ap_dbf_info);
-}
-
/**
* ap_module_init(): The module initialization code.
*
* Initializes the module.
*/
-int __init ap_module_init(void)
+static int __init ap_module_init(void)
{
int max_domain_id;
int rc, i;
@@ -1274,8 +1249,6 @@ int __init ap_module_init(void)
ap_airq_flag = (rc == 0);
}
- register_reset_call(&ap_reset_call);
-
/* Create /sys/bus/ap. */
rc = bus_register(&ap_bus_type);
if (rc)
@@ -1331,7 +1304,6 @@ out_bus:
bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
bus_unregister(&ap_bus_type);
out:
- unregister_reset_call(&ap_reset_call);
if (ap_using_interrupts())
unregister_adapter_interrupt(&ap_airq);
kfree(ap_configuration);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index e0827eaa42f1..02184cf35834 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -17,7 +17,7 @@
#include <linux/types.h>
#include <asm/ap.h>
-#define AP_DEVICES 64 /* Number of AP devices. */
+#define AP_DEVICES 256 /* Number of AP devices. */
#define AP_DOMAINS 256 /* Number of AP domains. */
#define AP_RESET_TIMEOUT (HZ*0.7) /* Time in ticks for reset timeouts. */
#define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */
@@ -240,7 +240,4 @@ void ap_queue_resume(struct ap_device *ap_dev);
struct ap_card *ap_card_create(int id, int queue_depth, int raw_device_type,
int comp_device_type, unsigned int functions);
-int ap_module_init(void);
-void ap_module_exit(void);
-
#endif /* _AP_BUS_H_ */
diff --git a/drivers/s390/crypto/ap_debug.h b/drivers/s390/crypto/ap_debug.h
index 6a9d77c75ec3..dc675eb5aef6 100644
--- a/drivers/s390/crypto/ap_debug.h
+++ b/drivers/s390/crypto/ap_debug.h
@@ -23,7 +23,4 @@
extern debug_info_t *ap_dbf_info;
-int ap_debug_init(void);
-void ap_debug_exit(void);
-
#endif /* AP_DEBUG_H */
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index e7c2e4f9529a..ed80d00cdb6f 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -889,7 +889,7 @@ int pkey_findcard(const struct pkey_seckey *seckey,
u16 *pcardnr, u16 *pdomain, int verify)
{
struct secaeskeytoken *t = (struct secaeskeytoken *) seckey;
- struct zcrypt_device_matrix *device_matrix;
+ struct zcrypt_device_status_ext *device_status;
u16 card, dom;
u64 mkvp[2];
int i, rc, oi = -1;
@@ -899,18 +899,19 @@ int pkey_findcard(const struct pkey_seckey *seckey,
return -EINVAL;
/* fetch status of all crypto cards */
- device_matrix = kmalloc(sizeof(struct zcrypt_device_matrix),
+ device_status = kmalloc(MAX_ZDEV_ENTRIES_EXT
+ * sizeof(struct zcrypt_device_status_ext),
GFP_KERNEL);
- if (!device_matrix)
+ if (!device_status)
return -ENOMEM;
- zcrypt_device_status_mask(device_matrix);
+ zcrypt_device_status_mask_ext(device_status);
/* walk through all crypto cards */
- for (i = 0; i < MAX_ZDEV_ENTRIES; i++) {
- card = AP_QID_CARD(device_matrix->device[i].qid);
- dom = AP_QID_QUEUE(device_matrix->device[i].qid);
- if (device_matrix->device[i].online &&
- device_matrix->device[i].functions & 0x04) {
+ for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+ card = AP_QID_CARD(device_status[i].qid);
+ dom = AP_QID_QUEUE(device_status[i].qid);
+ if (device_status[i].online &&
+ device_status[i].functions & 0x04) {
/* an enabled CCA Coprocessor card */
/* try cached mkvp */
if (mkvp_cache_fetch(card, dom, mkvp) == 0 &&
@@ -930,14 +931,14 @@ int pkey_findcard(const struct pkey_seckey *seckey,
mkvp_cache_scrub(card, dom);
}
}
- if (i >= MAX_ZDEV_ENTRIES) {
+ if (i >= MAX_ZDEV_ENTRIES_EXT) {
/* nothing found, so this time without cache */
- for (i = 0; i < MAX_ZDEV_ENTRIES; i++) {
- if (!(device_matrix->device[i].online &&
- device_matrix->device[i].functions & 0x04))
+ for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+ if (!(device_status[i].online &&
+ device_status[i].functions & 0x04))
continue;
- card = AP_QID_CARD(device_matrix->device[i].qid);
- dom = AP_QID_QUEUE(device_matrix->device[i].qid);
+ card = AP_QID_CARD(device_status[i].qid);
+ dom = AP_QID_QUEUE(device_status[i].qid);
/* fresh fetch mkvp from adapter */
if (fetch_mkvp(card, dom, mkvp) == 0) {
mkvp_cache_update(card, dom, mkvp);
@@ -947,13 +948,13 @@ int pkey_findcard(const struct pkey_seckey *seckey,
oi = i;
}
}
- if (i >= MAX_ZDEV_ENTRIES && oi >= 0) {
+ if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) {
/* old mkvp matched, use this card then */
- card = AP_QID_CARD(device_matrix->device[oi].qid);
- dom = AP_QID_QUEUE(device_matrix->device[oi].qid);
+ card = AP_QID_CARD(device_status[oi].qid);
+ dom = AP_QID_QUEUE(device_status[oi].qid);
}
}
- if (i < MAX_ZDEV_ENTRIES || oi >= 0) {
+ if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) {
if (pcardnr)
*pcardnr = card;
if (pdomain)
@@ -962,7 +963,7 @@ int pkey_findcard(const struct pkey_seckey *seckey,
} else
rc = -ENODEV;
- kfree(device_matrix);
+ kfree(device_status);
return rc;
}
EXPORT_SYMBOL(pkey_findcard);
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index ce15f101ee28..5efd84862ccb 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -18,8 +18,6 @@
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
#include <linux/compat.h>
#include <linux/slab.h>
#include <linux/atomic.h>
@@ -607,19 +605,24 @@ out:
return rc;
}
-void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix)
+static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
struct zcrypt_device_status *stat;
+ int card, queue;
+
+ memset(devstatus, 0, MAX_ZDEV_ENTRIES
+ * sizeof(struct zcrypt_device_status));
- memset(matrix, 0, sizeof(*matrix));
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
- stat = matrix->device;
- stat += AP_QID_CARD(zq->queue->qid) * MAX_ZDEV_DOMAINS;
- stat += AP_QID_QUEUE(zq->queue->qid);
+ card = AP_QID_CARD(zq->queue->qid);
+ if (card >= MAX_ZDEV_CARDIDS)
+ continue;
+ queue = AP_QID_QUEUE(zq->queue->qid);
+ stat = &devstatus[card * AP_DOMAINS + queue];
stat->hwtype = zc->card->ap_dev.device_type;
stat->functions = zc->card->functions >> 26;
stat->qid = zq->queue->qid;
@@ -628,40 +631,70 @@ void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix)
}
spin_unlock(&zcrypt_list_lock);
}
-EXPORT_SYMBOL(zcrypt_device_status_mask);
-static void zcrypt_status_mask(char status[AP_DEVICES])
+void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
+ struct zcrypt_device_status_ext *stat;
+ int card, queue;
+
+ memset(devstatus, 0, MAX_ZDEV_ENTRIES_EXT
+ * sizeof(struct zcrypt_device_status_ext));
- memset(status, 0, sizeof(char) * AP_DEVICES);
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
- if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
+ card = AP_QID_CARD(zq->queue->qid);
+ queue = AP_QID_QUEUE(zq->queue->qid);
+ stat = &devstatus[card * AP_DOMAINS + queue];
+ stat->hwtype = zc->card->ap_dev.device_type;
+ stat->functions = zc->card->functions >> 26;
+ stat->qid = zq->queue->qid;
+ stat->online = zq->online ? 0x01 : 0x00;
+ }
+ }
+ spin_unlock(&zcrypt_list_lock);
+}
+EXPORT_SYMBOL(zcrypt_device_status_mask_ext);
+
+static void zcrypt_status_mask(char status[], size_t max_adapters)
+{
+ struct zcrypt_card *zc;
+ struct zcrypt_queue *zq;
+ int card;
+
+ memset(status, 0, max_adapters);
+ spin_lock(&zcrypt_list_lock);
+ for_each_zcrypt_card(zc) {
+ for_each_zcrypt_queue(zq, zc) {
+ card = AP_QID_CARD(zq->queue->qid);
+ if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index
+ || card >= max_adapters)
continue;
- status[AP_QID_CARD(zq->queue->qid)] =
- zc->online ? zc->user_space_type : 0x0d;
+ status[card] = zc->online ? zc->user_space_type : 0x0d;
}
}
spin_unlock(&zcrypt_list_lock);
}
-static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
+static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
+ int card;
- memset(qdepth, 0, sizeof(char) * AP_DEVICES);
+ memset(qdepth, 0, max_adapters);
spin_lock(&zcrypt_list_lock);
local_bh_disable();
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
- if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
+ card = AP_QID_CARD(zq->queue->qid);
+ if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index
+ || card >= max_adapters)
continue;
spin_lock(&zq->queue->lock);
- qdepth[AP_QID_CARD(zq->queue->qid)] =
+ qdepth[card] =
zq->queue->pendingq_count +
zq->queue->requestq_count;
spin_unlock(&zq->queue->lock);
@@ -671,21 +704,23 @@ static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
spin_unlock(&zcrypt_list_lock);
}
-static void zcrypt_perdev_reqcnt(int reqcnt[AP_DEVICES])
+static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
+ int card;
- memset(reqcnt, 0, sizeof(int) * AP_DEVICES);
+ memset(reqcnt, 0, sizeof(int) * max_adapters);
spin_lock(&zcrypt_list_lock);
local_bh_disable();
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
- if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
+ card = AP_QID_CARD(zq->queue->qid);
+ if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index
+ || card >= max_adapters)
continue;
spin_lock(&zq->queue->lock);
- reqcnt[AP_QID_CARD(zq->queue->qid)] =
- zq->queue->total_request_count;
+ reqcnt[card] = zq->queue->total_request_count;
spin_unlock(&zq->queue->lock);
}
}
@@ -739,60 +774,10 @@ static int zcrypt_requestq_count(void)
return requestq_count;
}
-static int zcrypt_count_type(int type)
-{
- struct zcrypt_card *zc;
- struct zcrypt_queue *zq;
- int device_count;
-
- device_count = 0;
- spin_lock(&zcrypt_list_lock);
- for_each_zcrypt_card(zc) {
- if (zc->card->id != type)
- continue;
- for_each_zcrypt_queue(zq, zc) {
- if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
- continue;
- device_count++;
- }
- }
- spin_unlock(&zcrypt_list_lock);
- return device_count;
-}
-
-/**
- * zcrypt_ica_status(): Old, depracted combi status call.
- *
- * Old, deprecated combi status call.
- */
-static long zcrypt_ica_status(struct file *filp, unsigned long arg)
-{
- struct ica_z90_status *pstat;
- int ret;
-
- pstat = kzalloc(sizeof(*pstat), GFP_KERNEL);
- if (!pstat)
- return -ENOMEM;
- pstat->totalcount = zcrypt_device_count;
- pstat->leedslitecount = zcrypt_count_type(ZCRYPT_PCICA);
- pstat->leeds2count = zcrypt_count_type(ZCRYPT_PCICC);
- pstat->requestqWaitCount = zcrypt_requestq_count();
- pstat->pendingqWaitCount = zcrypt_pendingq_count();
- pstat->totalOpenCount = atomic_read(&zcrypt_open_count);
- pstat->cryptoDomain = ap_domain_index;
- zcrypt_status_mask(pstat->status);
- zcrypt_qdepth_mask(pstat->qdepth);
- ret = 0;
- if (copy_to_user((void __user *) arg, pstat, sizeof(*pstat)))
- ret = -EFAULT;
- kfree(pstat);
- return ret;
-}
-
static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg)
{
- int rc;
+ int rc = 0;
switch (cmd) {
case ICARSAMODEXPO: {
@@ -871,48 +856,48 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
return -EFAULT;
return rc;
}
- case ZDEVICESTATUS: {
- struct zcrypt_device_matrix *device_status;
+ case ZCRYPT_DEVICE_STATUS: {
+ struct zcrypt_device_status_ext *device_status;
+ size_t total_size = MAX_ZDEV_ENTRIES_EXT
+ * sizeof(struct zcrypt_device_status_ext);
- device_status = kzalloc(sizeof(struct zcrypt_device_matrix),
- GFP_KERNEL);
+ device_status = kzalloc(total_size, GFP_KERNEL);
if (!device_status)
return -ENOMEM;
-
- zcrypt_device_status_mask(device_status);
-
+ zcrypt_device_status_mask_ext(device_status);
if (copy_to_user((char __user *) arg, device_status,
- sizeof(struct zcrypt_device_matrix))) {
- kfree(device_status);
- return -EFAULT;
- }
-
+ total_size))
+ rc = -EFAULT;
kfree(device_status);
- return 0;
+ return rc;
}
- case Z90STAT_STATUS_MASK: {
+ case ZCRYPT_STATUS_MASK: {
char status[AP_DEVICES];
- zcrypt_status_mask(status);
- if (copy_to_user((char __user *) arg, status,
- sizeof(char) * AP_DEVICES))
+
+ zcrypt_status_mask(status, AP_DEVICES);
+ if (copy_to_user((char __user *) arg, status, sizeof(status)))
return -EFAULT;
return 0;
}
- case Z90STAT_QDEPTH_MASK: {
+ case ZCRYPT_QDEPTH_MASK: {
char qdepth[AP_DEVICES];
- zcrypt_qdepth_mask(qdepth);
- if (copy_to_user((char __user *) arg, qdepth,
- sizeof(char) * AP_DEVICES))
+
+ zcrypt_qdepth_mask(qdepth, AP_DEVICES);
+ if (copy_to_user((char __user *) arg, qdepth, sizeof(qdepth)))
return -EFAULT;
return 0;
}
- case Z90STAT_PERDEV_REQCNT: {
- int reqcnt[AP_DEVICES];
- zcrypt_perdev_reqcnt(reqcnt);
- if (copy_to_user((int __user *) arg, reqcnt,
- sizeof(int) * AP_DEVICES))
- return -EFAULT;
- return 0;
+ case ZCRYPT_PERDEV_REQCNT: {
+ int *reqcnt;
+
+ reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL);
+ if (!reqcnt)
+ return -ENOMEM;
+ zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES);
+ if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt)))
+ rc = -EFAULT;
+ kfree(reqcnt);
+ return rc;
}
case Z90STAT_REQUESTQ_COUNT:
return put_user(zcrypt_requestq_count(), (int __user *) arg);
@@ -924,38 +909,54 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
case Z90STAT_DOMAIN_INDEX:
return put_user(ap_domain_index, (int __user *) arg);
/*
- * Deprecated ioctls. Don't add another device count ioctl,
- * you can count them yourself in the user space with the
- * output of the Z90STAT_STATUS_MASK ioctl.
+ * Deprecated ioctls
*/
- case ICAZ90STATUS:
- return zcrypt_ica_status(filp, arg);
- case Z90STAT_TOTALCOUNT:
- return put_user(zcrypt_device_count, (int __user *) arg);
- case Z90STAT_PCICACOUNT:
- return put_user(zcrypt_count_type(ZCRYPT_PCICA),
- (int __user *) arg);
- case Z90STAT_PCICCCOUNT:
- return put_user(zcrypt_count_type(ZCRYPT_PCICC),
- (int __user *) arg);
- case Z90STAT_PCIXCCMCL2COUNT:
- return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL2),
- (int __user *) arg);
- case Z90STAT_PCIXCCMCL3COUNT:
- return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL3),
- (int __user *) arg);
- case Z90STAT_PCIXCCCOUNT:
- return put_user(zcrypt_count_type(ZCRYPT_PCIXCC_MCL2) +
- zcrypt_count_type(ZCRYPT_PCIXCC_MCL3),
- (int __user *) arg);
- case Z90STAT_CEX2CCOUNT:
- return put_user(zcrypt_count_type(ZCRYPT_CEX2C),
- (int __user *) arg);
- case Z90STAT_CEX2ACOUNT:
- return put_user(zcrypt_count_type(ZCRYPT_CEX2A),
- (int __user *) arg);
+ case ZDEVICESTATUS: {
+ /* the old ioctl supports only 64 adapters */
+ struct zcrypt_device_status *device_status;
+ size_t total_size = MAX_ZDEV_ENTRIES
+ * sizeof(struct zcrypt_device_status);
+
+ device_status = kzalloc(total_size, GFP_KERNEL);
+ if (!device_status)
+ return -ENOMEM;
+ zcrypt_device_status_mask(device_status);
+ if (copy_to_user((char __user *) arg, device_status,
+ total_size))
+ rc = -EFAULT;
+ kfree(device_status);
+ return rc;
+ }
+ case Z90STAT_STATUS_MASK: {
+ /* the old ioctl supports only 64 adapters */
+ char status[MAX_ZDEV_CARDIDS];
+
+ zcrypt_status_mask(status, MAX_ZDEV_CARDIDS);
+ if (copy_to_user((char __user *) arg, status, sizeof(status)))
+ return -EFAULT;
+ return 0;
+ }
+ case Z90STAT_QDEPTH_MASK: {
+ /* the old ioctl supports only 64 adapters */
+ char qdepth[MAX_ZDEV_CARDIDS];
+
+ zcrypt_qdepth_mask(qdepth, MAX_ZDEV_CARDIDS);
+ if (copy_to_user((char __user *) arg, qdepth, sizeof(qdepth)))
+ return -EFAULT;
+ return 0;
+ }
+ case Z90STAT_PERDEV_REQCNT: {
+ /* the old ioctl supports only 64 adapters */
+ int reqcnt[MAX_ZDEV_CARDIDS];
+
+ zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS);
+ if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt)))
+ return -EFAULT;
+ return 0;
+ }
+ /* unknown ioctl number */
default:
- /* unknown ioctl number */
+ ZCRYPT_DBF(DBF_DEBUG, "unknown ioctl 0x%08x\n", cmd);
return -ENOIOCTLCMD;
}
}
@@ -1152,201 +1153,6 @@ static struct miscdevice zcrypt_misc_device = {
.fops = &zcrypt_fops,
};
-/*
- * Deprecated /proc entry support.
- */
-static struct proc_dir_entry *zcrypt_entry;
-
-static void sprintcl(struct seq_file *m, unsigned char *addr, unsigned int len)
-{
- int i;
-
- for (i = 0; i < len; i++)
- seq_printf(m, "%01x", (unsigned int) addr[i]);
- seq_putc(m, ' ');
-}
-
-static void sprintrw(struct seq_file *m, unsigned char *addr, unsigned int len)
-{
- int inl, c, cx;
-
- seq_printf(m, " ");
- inl = 0;
- for (c = 0; c < (len / 16); c++) {
- sprintcl(m, addr+inl, 16);
- inl += 16;
- }
- cx = len%16;
- if (cx) {
- sprintcl(m, addr+inl, cx);
- inl += cx;
- }
- seq_putc(m, '\n');
-}
-
-static void sprinthx(unsigned char *title, struct seq_file *m,
- unsigned char *addr, unsigned int len)
-{
- int inl, r, rx;
-
- seq_printf(m, "\n%s\n", title);
- inl = 0;
- for (r = 0; r < (len / 64); r++) {
- sprintrw(m, addr+inl, 64);
- inl += 64;
- }
- rx = len % 64;
- if (rx) {
- sprintrw(m, addr+inl, rx);
- inl += rx;
- }
- seq_putc(m, '\n');
-}
-
-static void sprinthx4(unsigned char *title, struct seq_file *m,
- unsigned int *array, unsigned int len)
-{
- seq_printf(m, "\n%s\n", title);
- seq_hex_dump(m, " ", DUMP_PREFIX_NONE, 32, 4, array, len, false);
- seq_putc(m, '\n');
-}
-
-static int zcrypt_proc_show(struct seq_file *m, void *v)
-{
- char workarea[sizeof(int) * AP_DEVICES];
-
- seq_printf(m, "\nzcrypt version: %d.%d.%d\n",
- ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT);
- seq_printf(m, "Cryptographic domain: %d\n", ap_domain_index);
- seq_printf(m, "Total device count: %d\n", zcrypt_device_count);
- seq_printf(m, "PCICA count: %d\n", zcrypt_count_type(ZCRYPT_PCICA));
- seq_printf(m, "PCICC count: %d\n", zcrypt_count_type(ZCRYPT_PCICC));
- seq_printf(m, "PCIXCC MCL2 count: %d\n",
- zcrypt_count_type(ZCRYPT_PCIXCC_MCL2));
- seq_printf(m, "PCIXCC MCL3 count: %d\n",
- zcrypt_count_type(ZCRYPT_PCIXCC_MCL3));
- seq_printf(m, "CEX2C count: %d\n", zcrypt_count_type(ZCRYPT_CEX2C));
- seq_printf(m, "CEX2A count: %d\n", zcrypt_count_type(ZCRYPT_CEX2A));
- seq_printf(m, "CEX3C count: %d\n", zcrypt_count_type(ZCRYPT_CEX3C));
- seq_printf(m, "CEX3A count: %d\n", zcrypt_count_type(ZCRYPT_CEX3A));
- seq_printf(m, "requestq count: %d\n", zcrypt_requestq_count());
- seq_printf(m, "pendingq count: %d\n", zcrypt_pendingq_count());
- seq_printf(m, "Total open handles: %d\n\n",
- atomic_read(&zcrypt_open_count));
- zcrypt_status_mask(workarea);
- sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) "
- "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A",
- m, workarea, AP_DEVICES);
- zcrypt_qdepth_mask(workarea);
- sprinthx("Waiting work element counts", m, workarea, AP_DEVICES);
- zcrypt_perdev_reqcnt((int *) workarea);
- sprinthx4("Per-device successfully completed request counts",
- m, (unsigned int *) workarea, AP_DEVICES);
- return 0;
-}
-
-static int zcrypt_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, zcrypt_proc_show, NULL);
-}
-
-static void zcrypt_disable_card(int index)
-{
- struct zcrypt_card *zc;
- struct zcrypt_queue *zq;
-
- spin_lock(&zcrypt_list_lock);
- for_each_zcrypt_card(zc) {
- for_each_zcrypt_queue(zq, zc) {
- if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
- continue;
- zq->online = 0;
- ap_flush_queue(zq->queue);
- }
- }
- spin_unlock(&zcrypt_list_lock);
-}
-
-static void zcrypt_enable_card(int index)
-{
- struct zcrypt_card *zc;
- struct zcrypt_queue *zq;
-
- spin_lock(&zcrypt_list_lock);
- for_each_zcrypt_card(zc) {
- for_each_zcrypt_queue(zq, zc) {
- if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
- continue;
- zq->online = 1;
- ap_flush_queue(zq->queue);
- }
- }
- spin_unlock(&zcrypt_list_lock);
-}
-
-static ssize_t zcrypt_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *pos)
-{
- unsigned char *lbuf, *ptr;
- size_t local_count;
- int j;
-
- if (count <= 0)
- return 0;
-
-#define LBUFSIZE 1200UL
- lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);
- if (!lbuf)
- return 0;
-
- local_count = min(LBUFSIZE - 1, count);
- if (copy_from_user(lbuf, buffer, local_count) != 0) {
- kfree(lbuf);
- return -EFAULT;
- }
- lbuf[local_count] = '\0';
-
- ptr = strstr(lbuf, "Online devices");
- if (!ptr)
- goto out;
- ptr = strstr(ptr, "\n");
- if (!ptr)
- goto out;
- ptr++;
-
- if (strstr(ptr, "Waiting work element counts") == NULL)
- goto out;
-
- for (j = 0; j < 64 && *ptr; ptr++) {
- /*
- * '0' for no device, '1' for PCICA, '2' for PCICC,
- * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3,
- * '5' for CEX2C and '6' for CEX2A'
- * '7' for CEX3C and '8' for CEX3A
- */
- if (*ptr >= '0' && *ptr <= '8')
- j++;
- else if (*ptr == 'd' || *ptr == 'D')
- zcrypt_disable_card(j++);
- else if (*ptr == 'e' || *ptr == 'E')
- zcrypt_enable_card(j++);
- else if (*ptr != ' ' && *ptr != '\t')
- break;
- }
-out:
- kfree(lbuf);
- return count;
-}
-
-static const struct file_operations zcrypt_proc_fops = {
- .owner = THIS_MODULE,
- .open = zcrypt_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = zcrypt_proc_write,
-};
-
static int zcrypt_rng_device_count;
static u32 *zcrypt_rng_buffer;
static int zcrypt_rng_buffer_index;
@@ -1448,27 +1254,15 @@ int __init zcrypt_api_init(void)
if (rc)
goto out;
- atomic_set(&zcrypt_rescan_req, 0);
-
/* Register the request sprayer. */
rc = misc_register(&zcrypt_misc_device);
if (rc < 0)
goto out;
- /* Set up the proc file system */
- zcrypt_entry = proc_create("driver/z90crypt", 0644, NULL,
- &zcrypt_proc_fops);
- if (!zcrypt_entry) {
- rc = -ENOMEM;
- goto out_misc;
- }
-
zcrypt_msgtype6_init();
zcrypt_msgtype50_init();
return 0;
-out_misc:
- misc_deregister(&zcrypt_misc_device);
out:
return rc;
}
@@ -1480,7 +1274,6 @@ out:
*/
void __exit zcrypt_api_exit(void)
{
- remove_proc_entry("driver/z90crypt", NULL);
misc_deregister(&zcrypt_misc_device);
zcrypt_msgtype6_exit();
zcrypt_msgtype50_exit();
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h
index 9fff8912f6e3..f149a8fee60d 100644
--- a/drivers/s390/crypto/zcrypt_api.h
+++ b/drivers/s390/crypto/zcrypt_api.h
@@ -21,30 +21,6 @@
#include <asm/zcrypt.h>
#include "ap_bus.h"
-/* deprecated status calls */
-#define ICAZ90STATUS _IOR(ZCRYPT_IOCTL_MAGIC, 0x10, struct ica_z90_status)
-#define Z90STAT_PCIXCCCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x43, int)
-
-/**
- * This structure is deprecated and the corresponding ioctl() has been
- * replaced with individual ioctl()s for each piece of data!
- */
-struct ica_z90_status {
- int totalcount;
- int leedslitecount; // PCICA
- int leeds2count; // PCICC
- // int PCIXCCCount; is not in struct for backward compatibility
- int requestqWaitCount;
- int pendingqWaitCount;
- int totalOpenCount;
- int cryptoDomain;
- // status: 0=not there, 1=PCICA, 2=PCICC, 3=PCIXCC_MCL2, 4=PCIXCC_MCL3,
- // 5=CEX2C
- unsigned char status[64];
- // qdepth: # work elements waiting for each device
- unsigned char qdepth[64];
-};
-
/**
* device type for an actual device is either PCICA, PCICC, PCIXCC_MCL2,
* PCIXCC_MCL3, CEX2C, or CEX2A
@@ -179,6 +155,6 @@ struct zcrypt_ops *zcrypt_msgtype(unsigned char *, int);
int zcrypt_api_init(void);
void zcrypt_api_exit(void);
long zcrypt_send_cprb(struct ica_xcRB *xcRB);
-void zcrypt_device_status_mask(struct zcrypt_device_matrix *devstatus);
+void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
#endif /* _ZCRYPT_API_H_ */