linux/drivers/s390/crypto/zcrypt_cex4.c
<<
>>
Prefs
   1/*
   2 *  Copyright IBM Corp. 2012
   3 *  Author(s): Holger Dengler <hd@linux.vnet.ibm.com>
   4 */
   5
   6#include <linux/module.h>
   7#include <linux/slab.h>
   8#include <linux/init.h>
   9#include <linux/err.h>
  10#include <linux/atomic.h>
  11#include <linux/uaccess.h>
  12
  13#include "ap_bus.h"
  14#include "zcrypt_api.h"
  15#include "zcrypt_msgtype6.h"
  16#include "zcrypt_msgtype50.h"
  17#include "zcrypt_error.h"
  18#include "zcrypt_cex4.h"
  19
  20#define CEX4A_MIN_MOD_SIZE        1     /*    8 bits    */
  21#define CEX4A_MAX_MOD_SIZE_2K   256     /* 2048 bits    */
  22#define CEX4A_MAX_MOD_SIZE_4K   512     /* 4096 bits    */
  23
  24#define CEX4C_MIN_MOD_SIZE       16     /*  256 bits    */
  25#define CEX4C_MAX_MOD_SIZE      512     /* 4096 bits    */
  26
  27#define CEX4A_SPEED_RATING      900      /* TODO new card, new speed rating */
  28#define CEX4C_SPEED_RATING      6500     /* TODO new card, new speed rating */
  29
  30#define CEX4A_MAX_MESSAGE_SIZE  MSGTYPE50_CRB3_MAX_MSG_SIZE
  31#define CEX4C_MAX_MESSAGE_SIZE  MSGTYPE06_MAX_MSG_SIZE
  32
  33#define CEX4_CLEANUP_TIME       (15*HZ)
  34
  35static struct ap_device_id zcrypt_cex4_ids[] = {
  36        { AP_DEVICE(AP_DEVICE_TYPE_CEX4)  },
  37        { /* end of list */ },
  38};
  39
  40MODULE_DEVICE_TABLE(ap, zcrypt_cex4_ids);
  41MODULE_AUTHOR("IBM Corporation");
  42MODULE_DESCRIPTION("CEX4 Cryptographic Card device driver, " \
  43                   "Copyright IBM Corp. 2012");
  44MODULE_LICENSE("GPL");
  45
  46static int zcrypt_cex4_probe(struct ap_device *ap_dev);
  47static void zcrypt_cex4_remove(struct ap_device *ap_dev);
  48
  49static struct ap_driver zcrypt_cex4_driver = {
  50        .probe = zcrypt_cex4_probe,
  51        .remove = zcrypt_cex4_remove,
  52        .ids = zcrypt_cex4_ids,
  53        .request_timeout = CEX4_CLEANUP_TIME,
  54};
  55
  56/**
  57 * Probe function for CEX4 cards. It always accepts the AP device
  58 * since the bus_match already checked the hardware type.
  59 * @ap_dev: pointer to the AP device.
  60 */
  61static int zcrypt_cex4_probe(struct ap_device *ap_dev)
  62{
  63        struct zcrypt_device *zdev = NULL;
  64        int rc = 0;
  65
  66        switch (ap_dev->device_type) {
  67        case AP_DEVICE_TYPE_CEX4:
  68                if (ap_test_bit(&ap_dev->functions, AP_FUNC_ACCEL)) {
  69                        zdev = zcrypt_device_alloc(CEX4A_MAX_MESSAGE_SIZE);
  70                        if (!zdev)
  71                                return -ENOMEM;
  72                        zdev->type_string = "CEX4A";
  73                        zdev->user_space_type = ZCRYPT_CEX3A;
  74                        zdev->min_mod_size = CEX4A_MIN_MOD_SIZE;
  75                        if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) &&
  76                            ap_test_bit(&ap_dev->functions, AP_FUNC_CRT4K)) {
  77                                zdev->max_mod_size =
  78                                        CEX4A_MAX_MOD_SIZE_4K;
  79                                zdev->max_exp_bit_length =
  80                                        CEX4A_MAX_MOD_SIZE_4K;
  81                        } else {
  82                                zdev->max_mod_size =
  83                                        CEX4A_MAX_MOD_SIZE_2K;
  84                                zdev->max_exp_bit_length =
  85                                        CEX4A_MAX_MOD_SIZE_2K;
  86                        }
  87                        zdev->short_crt = 1;
  88                        zdev->speed_rating = CEX4A_SPEED_RATING;
  89                        zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME,
  90                                                           MSGTYPE50_VARIANT_DEFAULT);
  91                } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_COPRO)) {
  92                        zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE);
  93                        if (!zdev)
  94                                return -ENOMEM;
  95                        zdev->type_string = "CEX4C";
  96                        zdev->user_space_type = ZCRYPT_CEX3C;
  97                        zdev->min_mod_size = CEX4C_MIN_MOD_SIZE;
  98                        zdev->max_mod_size = CEX4C_MAX_MOD_SIZE;
  99                        zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE;
 100                        zdev->short_crt = 0;
 101                        zdev->speed_rating = CEX4C_SPEED_RATING;
 102                        zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME,
 103                                                           MSGTYPE06_VARIANT_DEFAULT);
 104                }
 105                break;
 106        }
 107        if (!zdev)
 108                return -ENODEV;
 109        zdev->ap_dev = ap_dev;
 110        zdev->online = 1;
 111        ap_dev->reply = &zdev->reply;
 112        ap_dev->private = zdev;
 113        rc = zcrypt_device_register(zdev);
 114        if (rc) {
 115                zcrypt_msgtype_release(zdev->ops);
 116                ap_dev->private = NULL;
 117                zcrypt_device_free(zdev);
 118        }
 119        return rc;
 120}
 121
 122/**
 123 * This is called to remove the extended CEX4 driver information
 124 * if an AP device is removed.
 125 */
 126static void zcrypt_cex4_remove(struct ap_device *ap_dev)
 127{
 128        struct zcrypt_device *zdev = ap_dev->private;
 129        struct zcrypt_ops *zops;
 130
 131        if (zdev) {
 132                zops = zdev->ops;
 133                zcrypt_device_unregister(zdev);
 134                zcrypt_msgtype_release(zops);
 135        }
 136}
 137
 138int __init zcrypt_cex4_init(void)
 139{
 140        return ap_driver_register(&zcrypt_cex4_driver, THIS_MODULE, "cex4");
 141}
 142
 143void __exit zcrypt_cex4_exit(void)
 144{
 145        ap_driver_unregister(&zcrypt_cex4_driver);
 146}
 147
 148module_init(zcrypt_cex4_init);
 149module_exit(zcrypt_cex4_exit);
 150
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.