^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright IBM Corp. 2001, 2012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author(s): Robert Burroughs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Eric Rossman (edrossma@us.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Ralph Wuerthner <rwuerthn@de.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/atomic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "ap_bus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "zcrypt_api.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "zcrypt_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "zcrypt_cex2a.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "zcrypt_msgtype50.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CEX3A_MAX_MOD_SIZE 512 /* 4096 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * (max outputdatalength) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * type80_hdr*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CEX2A_CLEANUP_TIME (15*HZ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) MODULE_AUTHOR("IBM Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) MODULE_DESCRIPTION("CEX2A/CEX3A Cryptographic Coprocessor device driver, " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) "Copyright IBM Corp. 2001, 2018");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static struct ap_device_id zcrypt_cex2a_card_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) { .dev_type = AP_DEVICE_TYPE_CEX2A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) { .dev_type = AP_DEVICE_TYPE_CEX3A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) .match_flags = AP_DEVICE_ID_MATCH_CARD_TYPE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) { /* end of list */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_card_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static struct ap_device_id zcrypt_cex2a_queue_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { .dev_type = AP_DEVICE_TYPE_CEX2A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { .dev_type = AP_DEVICE_TYPE_CEX3A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) .match_flags = AP_DEVICE_ID_MATCH_QUEUE_TYPE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) { /* end of list */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) MODULE_DEVICE_TABLE(ap, zcrypt_cex2a_queue_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * Probe function for CEX2A card devices. It always accepts the AP device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * since the bus_match already checked the card type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * @ap_dev: pointer to the AP device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static int zcrypt_cex2a_card_probe(struct ap_device *ap_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * Normalized speed ratings per crypto adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * MEX_1k, MEX_2k, MEX_4k, CRT_1k, CRT_2k, CRT_4k, RNG, SECKEY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static const int CEX2A_SPEED_IDX[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 800, 1000, 2000, 900, 1200, 2400, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static const int CEX3A_SPEED_IDX[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 400, 500, 1000, 450, 550, 1200, 0, 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct ap_card *ac = to_ap_card(&ap_dev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct zcrypt_card *zc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) zc = zcrypt_card_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if (!zc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) zc->card = ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ac->private = zc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX2A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) zc->speed_rating = CEX2A_SPEED_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) zc->type_string = "CEX2A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) zc->user_space_type = ZCRYPT_CEX2A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) } else if (ac->ap_dev.device_type == AP_DEVICE_TYPE_CEX3A) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) zc->min_mod_size = CEX2A_MIN_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) zc->max_mod_size = CEX2A_MAX_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) zc->max_exp_bit_length = CEX2A_MAX_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (ap_test_bit(&ac->functions, AP_FUNC_MEX4K) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ap_test_bit(&ac->functions, AP_FUNC_CRT4K)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) zc->max_mod_size = CEX3A_MAX_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) zc->max_exp_bit_length = CEX3A_MAX_MOD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) zc->speed_rating = CEX3A_SPEED_IDX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) zc->type_string = "CEX3A";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) zc->user_space_type = ZCRYPT_CEX3A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) zcrypt_card_free(zc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) zc->online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) rc = zcrypt_card_register(zc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ac->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) zcrypt_card_free(zc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * This is called to remove the CEX2A card driver information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * if an AP card device is removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void zcrypt_cex2a_card_remove(struct ap_device *ap_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct zcrypt_card *zc = to_ap_card(&ap_dev->device)->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (zc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) zcrypt_card_unregister(zc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static struct ap_driver zcrypt_cex2a_card_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .probe = zcrypt_cex2a_card_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .remove = zcrypt_cex2a_card_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .ids = zcrypt_cex2a_card_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .flags = AP_DRIVER_FLAG_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * Probe function for CEX2A queue devices. It always accepts the AP device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * since the bus_match already checked the queue type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @ap_dev: pointer to the AP device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct ap_queue *aq = to_ap_queue(&ap_dev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct zcrypt_queue *zq = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) switch (ap_dev->device_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case AP_DEVICE_TYPE_CEX2A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) zq = zcrypt_queue_alloc(CEX2A_MAX_RESPONSE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (!zq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case AP_DEVICE_TYPE_CEX3A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) zq = zcrypt_queue_alloc(CEX3A_MAX_RESPONSE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!zq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!zq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) zq->ops = zcrypt_msgtype(MSGTYPE50_NAME, MSGTYPE50_VARIANT_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) zq->queue = aq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) zq->online = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) atomic_set(&zq->load, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ap_queue_init_state(aq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ap_queue_init_reply(aq, &zq->reply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) aq->request_timeout = CEX2A_CLEANUP_TIME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) aq->private = zq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) rc = zcrypt_queue_register(zq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) aq->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) zcrypt_queue_free(zq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * This is called to remove the CEX2A queue driver information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * if an AP queue device is removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static void zcrypt_cex2a_queue_remove(struct ap_device *ap_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct ap_queue *aq = to_ap_queue(&ap_dev->device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct zcrypt_queue *zq = aq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if (zq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) zcrypt_queue_unregister(zq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static struct ap_driver zcrypt_cex2a_queue_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .probe = zcrypt_cex2a_queue_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) .remove = zcrypt_cex2a_queue_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) .ids = zcrypt_cex2a_queue_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) .flags = AP_DRIVER_FLAG_DEFAULT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int __init zcrypt_cex2a_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) rc = ap_driver_register(&zcrypt_cex2a_card_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) THIS_MODULE, "cex2acard");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rc = ap_driver_register(&zcrypt_cex2a_queue_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) THIS_MODULE, "cex2aqueue");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) ap_driver_unregister(&zcrypt_cex2a_card_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) void __exit zcrypt_cex2a_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ap_driver_unregister(&zcrypt_cex2a_queue_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ap_driver_unregister(&zcrypt_cex2a_card_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) module_init(zcrypt_cex2a_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) module_exit(zcrypt_cex2a_exit);