[generic-2.6] update OCF framework to version 20100325
[openwrt/svn-archive/archive.git] / target / linux / generic-2.6 / files / crypto / ocf / ep80579 / icp_common.c
index 461370c2c7c83c6170bf5b5a1b2d662930f048aa..5d46c0adc671a8f8ba3d2cc1afb9d6a046838076 100644 (file)
@@ -1,11 +1,11 @@
-/***************************************************************************
+/*************************************************************************
  *
  * This file is provided under a dual BSD/GPLv2 license.  When using or 
  *   redistributing this file, you may do so under either license.
  * 
  *   GPL LICENSE SUMMARY
  * 
- *   Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  * 
  *   This program is free software; you can redistribute it and/or modify 
  *   it under the terms of version 2 of the GNU General Public License as
@@ -27,7 +27,7 @@
  * 
  *   BSD LICENSE 
  * 
- *   Copyright(c) 2007,2008 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without 
@@ -57,7 +57,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * 
  * 
- *  version: Security.L.1.0.130
+ *  version: Security.L.1.0.2-229
  *
  ***************************************************************************/
 
 
 #include "icp_ocf.h"
 
-#define ICP_OCF_COMP_NAME                      "ICP_OCF"
-#define ICP_OCF_VER_MAIN                       (2)
-#define ICP_OCF_VER_MJR                                (0)
-#define ICP_OCF_VER_MNR                        (0)
+#define ICP_OCF_COMP_NAME                       "ICP_OCF"
+#define ICP_OCF_VER_MAIN                        (2)
+#define ICP_OCF_VER_MJR                         (1)
+#define ICP_OCF_VER_MNR                         (0)
 
-#define MAX_DEREG_RETRIES                      (100)
+#define MAX_DEREG_RETRIES                       (100)
 #define DEFAULT_DEREG_RETRIES                  (10)
 #define DEFAULT_DEREG_DELAY_IN_JIFFIES         (10)
 
 /* This defines the maximum number of sessions possible between OCF
-   and the OCF Tolapai Driver. If set to zero, there is no limit. */
-#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT   (0)
-#define NUM_SUPPORTED_CAPABILITIES             (21)
+   and the OCF EP80579 Driver. If set to zero, there is no limit. */
+#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT    (0)
+#define NUM_SUPPORTED_CAPABILITIES              (21)
+
+/*Slab zone names*/
+#define ICP_SESSION_DATA_NAME   "icp_ocf.SesDat"
+#define ICP_OP_DATA_NAME        "icp_ocf.OpDat"
+#define ICP_DH_NAME             "icp_ocf.DH"
+#define ICP_MODEXP_NAME         "icp_ocf.ModExp"
+#define ICP_RSA_DECRYPT_NAME    "icp_ocf.RSAdec"
+#define ICP_RSA_PKEY_NAME       "icp_ocf.RSApk"
+#define ICP_DSA_SIGN_NAME       "icp_ocf.DSAsg"
+#define ICP_DSA_VER_NAME        "icp_ocf.DSAver"
+#define ICP_RAND_VAL_NAME       "icp_ocf.DSArnd"
+#define ICP_FLAT_BUFF_NAME      "icp_ocf.FB"
 
 /*Slabs zones*/
-struct kmem_cache *drvSessionData_zone = NULL;
-struct kmem_cache *drvOpData_zone = NULL;
-struct kmem_cache *drvDH_zone = NULL;
-struct kmem_cache *drvLnModExp_zone = NULL;
-struct kmem_cache *drvRSADecrypt_zone = NULL;
-struct kmem_cache *drvRSAPrivateKey_zone = NULL;
-struct kmem_cache *drvDSARSSign_zone = NULL;
-struct kmem_cache *drvDSARSSignKValue_zone = NULL;
-struct kmem_cache *drvDSAVerify_zone = NULL;
+icp_kmem_cache drvSessionData_zone = NULL;
+icp_kmem_cache drvOpData_zone = NULL;
+icp_kmem_cache drvDH_zone = NULL;
+icp_kmem_cache drvLnModExp_zone = NULL;
+icp_kmem_cache drvRSADecrypt_zone = NULL;
+icp_kmem_cache drvRSAPrivateKey_zone = NULL;
+icp_kmem_cache drvDSARSSign_zone = NULL;
+icp_kmem_cache drvDSARSSignKValue_zone = NULL;
+icp_kmem_cache drvDSAVerify_zone = NULL;
 
 /*Slab zones for flatbuffers and bufferlist*/
-struct kmem_cache *drvFlatBuffer_zone = NULL;
+icp_kmem_cache drvFlatBuffer_zone = NULL;
 
-static int icp_ocfDrvInit(void);
-static void icp_ocfDrvExit(void);
+static inline int icp_cache_null_check(void)
+{
+       return (drvSessionData_zone && drvOpData_zone
+               && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
+               && drvRSAPrivateKey_zone && drvDSARSSign_zone
+               && drvDSARSSign_zone && drvDSARSSignKValue_zone
+               && drvDSAVerify_zone && drvFlatBuffer_zone);
+}
+
+/*Function to free all allocated slab caches before exiting the module*/
 static void icp_ocfDrvFreeCaches(void);
-static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
 
 int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
 
@@ -115,66 +134,42 @@ int num_dereg_retries = DEFAULT_DEREG_RETRIES;
 int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
 
 /* Module parameter - gives the maximum number of sessions possible between
-   OCF and the OCF Tolapai Driver. If set to zero, there is no limit.*/
+   OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
 int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
 
 /* This is set when the module is removed from the system, no further
    processing can take place if this is set */
-atomic_t icp_ocfDrvIsExiting = ATOMIC_INIT(0);
+icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
 
 /* This is used to show how many lac sessions were not deregistered*/
-atomic_t lac_session_failed_dereg_count = ATOMIC_INIT(0);
+icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
 
 /* This is used to track the number of registered sessions between OCF and
- * and the OCF Tolapai driver, when max_session is set to value other than
+ * and the OCF EP80579 driver, when max_session is set to value other than
  * zero. This ensures that the max_session set for the OCF and the driver
  * is equal to the LAC registered sessions */
-atomic_t num_ocf_to_drv_registered_sessions = ATOMIC_INIT(0);
+icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
 
 /* Head of linked list used to store session data */
-struct list_head icp_ocfDrvGlobalSymListHead;
-struct list_head icp_ocfDrvGlobalSymListHead_FreeMemList;
+icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
+icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
 
-spinlock_t icp_ocfDrvSymSessInfoListSpinlock = SPIN_LOCK_UNLOCKED;
-rwlock_t icp_kmem_cache_destroy_alloc_lock = RW_LOCK_UNLOCKED;
+icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
 
-struct workqueue_struct *icp_ocfDrvFreeLacSessionWorkQ;
+/*Below pointer is only used in linux, FreeBSD uses the name to
+create its own variable name*/
+icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
+ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
 
 struct icp_drvBuffListInfo defBuffListInfo;
 
-static struct {
-       softc_device_decl sc_dev;
-} icpDev;
-
-static device_method_t icp_methods = {
-       /* crypto device methods */
-       DEVMETHOD(cryptodev_newsession, icp_ocfDrvNewSession),
-       DEVMETHOD(cryptodev_freesession, icp_ocfDrvFreeLACSession),
-       DEVMETHOD(cryptodev_process, icp_ocfDrvSymProcess),
-       DEVMETHOD(cryptodev_kprocess, icp_ocfDrvPkeProcess),
-};
-
-module_param(num_dereg_retries, int, S_IRUGO);
-module_param(dereg_retry_delay_in_jiffies, int, S_IRUGO);
-module_param(max_sessions, int, S_IRUGO);
-
-MODULE_PARM_DESC(num_dereg_retries,
-                "Number of times to retry LAC Sym Session Deregistration. "
-                "Default 10, Max 100");
-MODULE_PARM_DESC(dereg_retry_delay_in_jiffies, "Delay in jiffies "
-                "(added to a schedule() function call) before a LAC Sym "
-                "Session Dereg is retried. Default 10");
-MODULE_PARM_DESC(max_sessions, "This sets the maximum number of sessions "
-                "between OCF and this driver. If this value is set to zero, "
-                "max session count checking is disabled. Default is zero(0)");
-
 /* Name        : icp_ocfDrvInit
  *
  * Description : This function will register all the symmetric and asymmetric
  * functionality that will be accelerated by the hardware. It will also
  * get a unique driver ID from the OCF and initialise all slab caches
  */
-static int __init icp_ocfDrvInit(void)
+ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
 {
        int ocfStatus = 0;
 
@@ -184,7 +179,7 @@ static int __init icp_ocfDrvInit(void)
        if (MAX_DEREG_RETRIES < num_dereg_retries) {
                EPRINTK("Session deregistration retry count set to greater "
                        "than %d", MAX_DEREG_RETRIES);
-               return -1;
+               icp_module_return_code(EINVAL);
        }
 
        /* Initialize and Start the Cryptographic component */
@@ -192,130 +187,133 @@ static int __init icp_ocfDrvInit(void)
            cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
                EPRINTK("Failed to initialize and start the instance "
                        "of the Cryptographic component.\n");
-               return -1;
+               return icp_module_return_code(EINVAL);
        }
 
+       icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
+
        /* Set the default size of BufferList to allocate */
        memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
        if (ICP_OCF_DRV_STATUS_SUCCESS !=
            icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
                                        &defBuffListInfo)) {
                EPRINTK("Failed to get bufferlist memory info.\n");
-               return -1;
+               return icp_module_return_code(ENOMEM);
        }
 
-       /*Register OCF Tolapai Driver with OCF */
-       memset(&icpDev, 0, sizeof(icpDev));
-       softc_device_init(&icpDev, "icp", 0, icp_methods);
-
-       icp_ocfDrvDriverId = crypto_get_driverid(softc_get_device(&icpDev),
-                                                CRYPTOCAP_F_HARDWARE);
+       /*Register OCF EP80579 Driver with OCF */
+       icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
 
        if (icp_ocfDrvDriverId < 0) {
                EPRINTK("%s : ICP driver failed to register with OCF!\n",
                        __FUNCTION__);
-               return -ENODEV;
+               return icp_module_return_code(ENODEV);
        }
 
-       /*Create all the slab caches used by the OCF Tolapai Driver */
+       /*Create all the slab caches used by the OCF EP80579 Driver */
        drvSessionData_zone =
-           ICP_CACHE_CREATE("ICP Session Data", struct icp_drvSessionData);
-       ICP_CACHE_NULL_CHECK(drvSessionData_zone);
+           ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
 
        /* 
         * Allocation of the OpData includes the allocation space for meta data.
         * The memory after the opData structure is reserved for this meta data.
         */
        drvOpData_zone =
-           kmem_cache_create("ICP Op Data", sizeof(struct icp_drvOpData) +
-                   defBuffListInfo.metaSize ,0, SLAB_HWCACHE_ALIGN, NULL, NULL);
+           icp_kmem_cache_create(ICP_OP_DATA_NAME,
+                                 sizeof(struct icp_drvOpData) +
+                                 defBuffListInfo.metaSize,
+                                 ICP_KERNEL_CACHE_ALIGN,
+                                 ICP_KERNEL_CACHE_NOINIT);
 
-
-       ICP_CACHE_NULL_CHECK(drvOpData_zone);
-
-       drvDH_zone = ICP_CACHE_CREATE("ICP DH data", CpaCyDhPhase1KeyGenOpData);
-       ICP_CACHE_NULL_CHECK(drvDH_zone);
+       drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
 
        drvLnModExp_zone =
-           ICP_CACHE_CREATE("ICP ModExp data", CpaCyLnModExpOpData);
-       ICP_CACHE_NULL_CHECK(drvLnModExp_zone);
+           ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
 
        drvRSADecrypt_zone =
-           ICP_CACHE_CREATE("ICP RSA decrypt data", CpaCyRsaDecryptOpData);
-       ICP_CACHE_NULL_CHECK(drvRSADecrypt_zone);
+           ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
 
        drvRSAPrivateKey_zone =
-           ICP_CACHE_CREATE("ICP RSA private key data", CpaCyRsaPrivateKey);
-       ICP_CACHE_NULL_CHECK(drvRSAPrivateKey_zone);
+           ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
 
        drvDSARSSign_zone =
-           ICP_CACHE_CREATE("ICP DSA Sign", CpaCyDsaRSSignOpData);
-       ICP_CACHE_NULL_CHECK(drvDSARSSign_zone);
+           ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
 
        /*too awkward to use a macro here */
        drvDSARSSignKValue_zone =
-           kmem_cache_create("ICP DSA Sign Rand Val",
-                             DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES, 0,
-                             SLAB_HWCACHE_ALIGN, NULL, NULL);
-       ICP_CACHE_NULL_CHECK(drvDSARSSignKValue_zone);
+           ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
+                            DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
 
        drvDSAVerify_zone =
-           ICP_CACHE_CREATE("ICP DSA Verify", CpaCyDsaVerifyOpData);
-       ICP_CACHE_NULL_CHECK(drvDSAVerify_zone);
+           ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
 
        drvFlatBuffer_zone =
-           ICP_CACHE_CREATE("ICP Flat Buffers", CpaFlatBuffer);
-       ICP_CACHE_NULL_CHECK(drvFlatBuffer_zone);
+           ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
+
+       if (0 == icp_cache_null_check()) {
+               icp_ocfDrvFreeCaches();
+               EPRINTK("%s() line %d: Not enough memory!\n",
+                       __FUNCTION__, __LINE__);
+               return ENOMEM;
+       }
 
        /* Register the ICP symmetric crypto support. */
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_NULL_CBC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_DES_CBC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_3DES_CBC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_AES_CBC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_ARC4);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_MD5_HMAC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA1_HMAC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_256_HMAC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_384_HMAC);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512);
-       ICP_REGISTER_SYM_FUNCTIONALITY_WITH_OCF(CRYPTO_SHA2_512_HMAC);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
+                            ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
+                            ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
+       ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
+                            ocfStatus);
 
        /* Register the ICP asymmetric algorithm support */
-       ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DH_COMPUTE_KEY);
-       ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP);
-       ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_MOD_EXP_CRT);
-       ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_SIGN);
-       ICP_REGISTER_ASYM_FUNCTIONALITY_WITH_OCF(CRK_DSA_VERIFY);
+       ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
+                             ocfStatus);
+       ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
+       ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
+       ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
+       ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
 
        /* Register the ICP random number generator support */
-       if (OCF_REGISTRATION_STATUS_SUCCESS ==
-           crypto_rregister(icp_ocfDrvDriverId, icp_ocfDrvReadRandom, NULL)) {
-               ocfStatus++;
-       }
+       ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
+                             icp_ocfDrvReadRandom, NULL, ocfStatus);
 
        if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
                DPRINTK("%s: Failed to register any device capabilities\n",
                        __FUNCTION__);
                icp_ocfDrvFreeCaches();
                icp_ocfDrvDriverId = INVALID_DRIVER_ID;
-               return -ECANCELED;
+               return icp_module_return_code(ECANCELED);
        }
 
        DPRINTK("%s: Registered %d of %d device capabilities\n",
                __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
 
-/*Session data linked list used during module exit*/
-       INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
-       INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
+       /*Session data linked list used during module exit */
+       ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
+       ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
 
-       icp_ocfDrvFreeLacSessionWorkQ =
-           create_singlethread_workqueue("ocfLacDeregWorkQueue");
+       ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
+       if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
+               EPRINTK("%s: Failed to create single "
+                       "thread workqueue\n", __FUNCTION__);
+               icp_ocfDrvFreeCaches();
+               icp_ocfDrvDriverId = INVALID_DRIVER_ID;
+               return icp_module_return_code(ENOMEM);
+       }
 
-       return 0;
+       return icp_module_return_code(0);
 }
 
 /* Name        : icp_ocfDrvExit
@@ -325,31 +323,46 @@ static int __init icp_ocfDrvInit(void)
  * and asymmetric functionality that can be accelerated by the hardware via OCF
  * and random number generation if it is enabled.
  */
-static void icp_ocfDrvExit(void)
+ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
 {
        CpaStatus lacStatus = CPA_STATUS_SUCCESS;
        struct icp_drvSessionData *sessionData = NULL;
        struct icp_drvSessionData *tempSessionData = NULL;
        int i, remaining_delay_time_in_jiffies = 0;
+
+       /* For FreeBSD the invariant macro below makes function to return     */
+       /* with EBUSY value in the case of any session which has been regi-   */
+       /* stered with LAC not being deregistered.                            */
+       /* The Linux implementation is empty since it is purely to compensate */
+       /* for a limitation of the FreeBSD 7.1 Opencrypto framework.          */
+
+    ICP_MODULE_EXIT_INV();
+
        /* There is a possibility of a process or new session command being   */
        /* sent before this variable is incremented. The aim of this variable */
        /* is to stop a loop of calls creating a deadlock situation which     */
        /* would prevent the driver from exiting.                             */
-
-       atomic_inc(&icp_ocfDrvIsExiting);
+       icp_atomic_set(&icp_ocfDrvIsExiting, 1);
 
        /*Existing sessions will be routed to another driver after these calls */
        crypto_unregister_all(icp_ocfDrvDriverId);
        crypto_runregister_all(icp_ocfDrvDriverId);
 
+       if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
+               DPRINTK("%s: workqueue already "
+                       "destroyed, therefore module exit "
+                       " function already called. Exiting.\n", __FUNCTION__);
+               return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
+       }
        /*If any sessions are waiting to be deregistered, do that. This also 
           flushes the work queue */
-       destroy_workqueue(icp_ocfDrvFreeLacSessionWorkQ);
+       ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
 
        /*ENTER CRITICAL SECTION */
-       spin_lock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
-       list_for_each_entry_safe(tempSessionData, sessionData,
-                                &icp_ocfDrvGlobalSymListHead, listNode) {
+       icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
+
+       ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
+                                    &icp_ocfDrvGlobalSymListHead, listNode) {
                for (i = 0; i < num_dereg_retries; i++) {
                        /*No harm if bad input - LAC will handle error cases */
                        if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
@@ -361,7 +374,7 @@ static void icp_ocfDrvExit(void)
                                        /* Succesfully deregistered */
                                        break;
                                } else if (CPA_STATUS_RETRY != lacStatus) {
-                                       atomic_inc
+                                       icp_atomic_inc
                                            (&lac_session_failed_dereg_count);
                                        break;
                                }
@@ -372,8 +385,9 @@ static void icp_ocfDrvExit(void)
                                    dereg_retry_delay_in_jiffies;
                                while (0 > remaining_delay_time_in_jiffies) {
                                        remaining_delay_time_in_jiffies =
-                                           schedule_timeout
-                                           (remaining_delay_time_in_jiffies);
+                                           icp_schedule_timeout
+                                           (&icp_ocfDrvSymSessInfoListSpinlock,
+                                            remaining_delay_time_in_jiffies);
                                }
 
                                DPRINTK
@@ -383,44 +397,48 @@ static void icp_ocfDrvExit(void)
                }
 
                /*remove from current list */
-               list_del(&(tempSessionData->listNode));
+               ICP_LIST_DEL(tempSessionData, listNode);
                /*add to free mem linked list */
-               list_add(&(tempSessionData->listNode),
-                        &icp_ocfDrvGlobalSymListHead_FreeMemList);
+               ICP_LIST_ADD(tempSessionData,
+                            &icp_ocfDrvGlobalSymListHead_FreeMemList,
+                            listNode);
 
        }
 
        /*EXIT CRITICAL SECTION */
-       spin_unlock_bh(&icp_ocfDrvSymSessInfoListSpinlock);
+       icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
 
        /*set back to initial values */
        sessionData = NULL;
        /*still have a reference in our list! */
        tempSessionData = NULL;
        /*free memory */
-       list_for_each_entry_safe(tempSessionData, sessionData,
-                                &icp_ocfDrvGlobalSymListHead_FreeMemList,
-                                listNode) {
 
-               list_del(&(tempSessionData->listNode));
+       ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
+                                    &icp_ocfDrvGlobalSymListHead_FreeMemList,
+                                    listNode) {
+
+               ICP_LIST_DEL(tempSessionData, listNode);
                /* Free allocated CpaCySymSessionCtx */
                if (NULL != tempSessionData->sessHandle) {
-                       kfree(tempSessionData->sessHandle);
+                       icp_kfree(tempSessionData->sessHandle);
                }
                memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
-               kmem_cache_free(drvSessionData_zone, tempSessionData);
+               ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
        }
 
-       if (0 != atomic_read(&lac_session_failed_dereg_count)) {
+       if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
                DPRINTK("%s(): %d LAC sessions were not deregistered "
                        "correctly. This is not a clean exit! \n",
                        __FUNCTION__,
-                       atomic_read(&lac_session_failed_dereg_count));
+                       icp_atomic_read(&lac_session_failed_dereg_count));
        }
 
        icp_ocfDrvFreeCaches();
        icp_ocfDrvDriverId = INVALID_DRIVER_ID;
 
+       icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
+
        /* Shutdown the Cryptographic component */
        lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
        if (CPA_STATUS_SUCCESS != lacStatus) {
@@ -429,6 +447,7 @@ static void icp_ocfDrvExit(void)
                        __FUNCTION__, lacStatus);
        }
 
+       return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
 }
 
 /* Name        : icp_ocfDrvFreeCaches
@@ -437,9 +456,7 @@ static void icp_ocfDrvExit(void)
  */
 static void icp_ocfDrvFreeCaches(void)
 {
-       if (atomic_read(&icp_ocfDrvIsExiting) != CPA_TRUE) {
-               atomic_set(&icp_ocfDrvIsExiting, 1);
-       }
+       icp_atomic_set(&icp_ocfDrvIsExiting, 1);
 
        /*Sym Zones */
        ICP_CACHE_DESTROY(drvSessionData_zone);
@@ -465,7 +482,6 @@ static void icp_ocfDrvFreeCaches(void)
  * off to a work queue. If it fails, nothing more can be done and it
  * returns an error
  */
-
 int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
 {
        struct icp_ocfDrvFreeLacSession *workstore = NULL;
@@ -475,11 +491,11 @@ int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
 
        /*make sure the session is not available to be allocated during this
           process */
-       atomic_inc(&lac_session_failed_dereg_count);
+       icp_atomic_inc(&lac_session_failed_dereg_count);
 
        /*Farm off to work queue */
        workstore =
-           kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), GFP_ATOMIC);
+           icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
        if (NULL == workstore) {
                DPRINTK("%s(): unable to free session - no memory available "
                        "for work queue\n", __FUNCTION__);
@@ -488,9 +504,11 @@ int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
 
        workstore->sessionToDeregister = sessionToDeregister;
 
-       INIT_WORK(&(workstore->work), icp_ocfDrvDeferedFreeLacSessionProcess,
-                 workstore);
-       queue_work(icp_ocfDrvFreeLacSessionWorkQ, &(workstore->work));
+       icp_init_work(&(workstore->work),
+                     icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
+
+       ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
+                             &(workstore->work));
 
        return ICP_OCF_DRV_STATUS_SUCCESS;
 
@@ -503,7 +521,7 @@ int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  * CPA_STATUS_RETRY message from the LAC component. This function is run in
  * Thread context because it is called from a worker thread
  */
-static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
+void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
 {
        struct icp_ocfDrvFreeLacSession *workstore = NULL;
        CpaCySymSessionCtx sessionToDeregister = NULL;
@@ -519,10 +537,10 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
        }
 
        sessionToDeregister = workstore->sessionToDeregister;
-       kfree(workstore);
+       icp_kfree(workstore);
 
        /*if exiting, give deregistration one more blast only */
-       if (atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
+       if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
                lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
                                                  sessionToDeregister);
 
@@ -533,7 +551,7 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
                        return;
                }
 
-               atomic_dec(&lac_session_failed_dereg_count);
+               icp_atomic_dec(&lac_session_failed_dereg_count);
                return;
        }
 
@@ -542,7 +560,7 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
                                                  sessionToDeregister);
 
                if (lacStatus == CPA_STATUS_SUCCESS) {
-                       atomic_dec(&lac_session_failed_dereg_count);
+                       icp_atomic_dec(&lac_session_failed_dereg_count);
                        return;
                }
                if (lacStatus != CPA_STATUS_RETRY) {
@@ -554,16 +572,17 @@ static void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
                /*schedule_timout returns the time left for completion if this
                   task is set to TASK_INTERRUPTIBLE */
                remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
-               while (0 > remaining_delay_time_in_jiffies) {
+               while (0 < remaining_delay_time_in_jiffies) {
                        remaining_delay_time_in_jiffies =
-                           schedule_timeout(remaining_delay_time_in_jiffies);
+                           icp_schedule_timeout(NULL,
+                                                remaining_delay_time_in_jiffies);
                }
 
        }
 
        DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
        DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
-               atomic_read(&lac_session_failed_dereg_count));
+               icp_atomic_read(&lac_session_failed_dereg_count));
 }
 
 /* Name        : icp_ocfDrvPtrAndLenToFlatBuffer 
@@ -581,131 +600,6 @@ icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
        pFlatBuffer->dataLenInBytes = len;
 }
 
-/* Name        : icp_ocfDrvSingleSkBuffToFlatBuffer 
- *
- * Description : This function converts a single socket buffer (sk_buff)
- * structure to a Fredericksburg Flat Buffer (CpaFlatBuffer) format.
- *
- * This function assumes that the data passed in are valid.
- */
-static inline void
-icp_ocfDrvSingleSkBuffToFlatBuffer(struct sk_buff *pSkb,
-                                  CpaFlatBuffer * pFlatBuffer)
-{
-       pFlatBuffer->pData = pSkb->data;
-       pFlatBuffer->dataLenInBytes = skb_headlen(pSkb);
-}
-
-/* Name        : icp_ocfDrvSkBuffToBufferList 
- *
- * Description : This function converts a socket buffer (sk_buff) structure to
- * Fredericksburg Scatter/Gather (CpaBufferList) buffer format.
- *
- * This function assumes that the bufferlist has been allocated with the correct
- * number of buffer arrays.
- * 
- */
-inline int
-icp_ocfDrvSkBuffToBufferList(struct sk_buff *pSkb, CpaBufferList * bufferList)
-{
-       CpaFlatBuffer *curFlatBuffer = NULL;
-       char *skbuffPageAddr = NULL;
-       struct sk_buff *pCurFrag = NULL;
-       struct skb_shared_info *pShInfo = NULL;
-       uint32_t page_offset = 0, i = 0;
-
-       DPRINTK("%s(): Entry Point\n", __FUNCTION__);
-
-       /*
-        * In all cases, the first skb needs to be translated to FlatBuffer.
-        * Perform a buffer translation for the first skbuff
-        */
-       curFlatBuffer = bufferList->pBuffers;
-       icp_ocfDrvSingleSkBuffToFlatBuffer(pSkb, curFlatBuffer);
-
-       /* Set the userData to point to the original sk_buff */
-       bufferList->pUserData = (void *)pSkb;
-
-       /* We now know we'll have at least one element in the SGL */
-       bufferList->numBuffers = 1;
-
-       if (0 == skb_is_nonlinear(pSkb)) {
-               /* Is a linear buffer - therefore it's a single skbuff */
-               DPRINTK("%s(): Exit Point\n", __FUNCTION__);
-               return ICP_OCF_DRV_STATUS_SUCCESS;
-       }
-
-       curFlatBuffer++;
-       pShInfo = skb_shinfo(pSkb);
-       if (pShInfo->frag_list != NULL && pShInfo->nr_frags != 0) {
-               EPRINTK("%s():"
-                       "Translation for a combination of frag_list "
-                       "and frags[] array not supported!\n", __FUNCTION__);
-               return ICP_OCF_DRV_STATUS_FAIL;
-       } else if (pShInfo->frag_list != NULL) {
-               /*
-                * Non linear skbuff supported through frag_list 
-                * Perform translation for each fragment (sk_buff)
-                * in the frag_list of the first sk_buff.
-                */
-               for (pCurFrag = pShInfo->frag_list;
-                    pCurFrag != NULL; pCurFrag = pCurFrag->next) {
-                       icp_ocfDrvSingleSkBuffToFlatBuffer(pCurFrag,
-                                                          curFlatBuffer);
-                       curFlatBuffer++;
-                       bufferList->numBuffers++;
-               }
-       } else if (pShInfo->nr_frags != 0) {
-               /*
-                * Perform translation for each fragment in frags array
-                * and add to the BufferList
-                */
-               for (i = 0; i < pShInfo->nr_frags; i++) {
-                       /* Get the page address and offset of this frag */
-                       skbuffPageAddr = (char *)pShInfo->frags[i].page;
-                       page_offset = pShInfo->frags[i].page_offset;
-
-                       /* Convert a pointer and length to a flat buffer */
-                       icp_ocfDrvPtrAndLenToFlatBuffer(skbuffPageAddr +
-                                                       page_offset,
-                                                       pShInfo->frags[i].size,
-                                                       curFlatBuffer);
-                       curFlatBuffer++;
-                       bufferList->numBuffers++;
-               }
-       } else {
-               EPRINTK("%s():" "Could not recognize skbuff fragments!\n",
-                       __FUNCTION__);
-               return ICP_OCF_DRV_STATUS_FAIL;
-       }
-
-       DPRINTK("%s(): Exit Point\n", __FUNCTION__);
-       return ICP_OCF_DRV_STATUS_SUCCESS;
-}
-
-/* Name        : icp_ocfDrvBufferListToSkBuff 
- *
- * Description : This function converts a Fredericksburg Scatter/Gather 
- * (CpaBufferList) buffer format to socket buffer structure.
- */
-inline int
-icp_ocfDrvBufferListToSkBuff(CpaBufferList * bufferList, struct sk_buff **skb)
-{
-       DPRINTK("%s(): Entry Point\n", __FUNCTION__);
-
-       /* Retrieve the orignal skbuff */
-       *skb = (struct sk_buff *)bufferList->pUserData;
-       if (NULL == *skb) {
-               EPRINTK("%s():"
-                       "Error on converting from a BufferList. "
-                       "The BufferList does not contain an sk_buff.\n",
-                       __FUNCTION__);
-               return ICP_OCF_DRV_STATUS_FAIL;
-       }
-       DPRINTK("%s(): Exit Point\n", __FUNCTION__);
-       return ICP_OCF_DRV_STATUS_SUCCESS;
-}
-
 /* Name        : icp_ocfDrvPtrAndLenToBufferList
  *
  * Description : This function converts a "pointer and length" buffer
@@ -761,45 +655,6 @@ icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
        return ICP_OCF_DRV_STATUS_SUCCESS;
 }
 
-/* Name        : icp_ocfDrvGetSkBuffFrags
- *
- * Description : This function will determine the number of 
- * fragments in a socket buffer(sk_buff).
- */
-inline uint16_t icp_ocfDrvGetSkBuffFrags(struct sk_buff * pSkb)
-{
-       uint16_t numFrags = 0;
-       struct sk_buff *pCurFrag = NULL;
-       struct skb_shared_info *pShInfo = NULL;
-
-       if (NULL == pSkb)
-               return 0;
-
-       numFrags = 1;
-       if (0 == skb_is_nonlinear(pSkb)) {
-               /* Linear buffer - it's a single skbuff */
-               return numFrags;
-       }
-
-       pShInfo = skb_shinfo(pSkb);
-       if (NULL != pShInfo->frag_list && 0 != pShInfo->nr_frags) {
-               EPRINTK("%s(): Combination of frag_list "
-                       "and frags[] array not supported!\n", __FUNCTION__);
-               return 0;
-       } else if (0 != pShInfo->nr_frags) {
-               numFrags += pShInfo->nr_frags;
-               return numFrags;
-       } else if (NULL != pShInfo->frag_list) {
-               for (pCurFrag = pShInfo->frag_list;
-                    pCurFrag != NULL; pCurFrag = pCurFrag->next) {
-                       numFrags++;
-               }
-               return numFrags;
-       } else {
-               return 0;
-       }
-}
-
 /* Name        : icp_ocfDrvFreeFlatBuffer
  *
  * Description : This function will deallocate flat buffer.
@@ -808,7 +663,7 @@ inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
 {
        if (pFlatBuffer != NULL) {
                memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
-               kmem_cache_free(drvFlatBuffer_zone, pFlatBuffer);
+               ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
        }
 }
 
@@ -819,14 +674,14 @@ inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  */
 inline int
 icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
-        const struct icp_drvOpData *pOpData)
+                       struct icp_drvOpData *pOpData)
 {
        Cpa32U metaSize = 0;
 
-       if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS){
-           void *pOpDataStartAddr = (void *)pOpData;
+       if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
+               uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
 
-           if (0 == defBuffListInfo.metaSize) {
+               if (0 == defBuffListInfo.metaSize) {
                        pBufferList->pPrivateMetaData = NULL;
                        return ICP_OCF_DRV_STATUS_SUCCESS;
                }
@@ -835,8 +690,9 @@ icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
                 * op data.  It has been pre-allocated in memory just after the
                 * icp_drvOpData structure.
                 */
-               pBufferList->pPrivateMetaData = pOpDataStartAddr +
-                       sizeof(struct icp_drvOpData);
+               pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
+                                                        sizeof(struct
+                                                               icp_drvOpData));
        } else {
                if (CPA_STATUS_SUCCESS !=
                    cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
@@ -852,7 +708,8 @@ icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
                        return ICP_OCF_DRV_STATUS_SUCCESS;
                }
 
-               pBufferList->pPrivateMetaData = kmalloc(metaSize, GFP_ATOMIC);
+               pBufferList->pPrivateMetaData =
+                   icp_kmalloc(metaSize, ICP_M_NOWAIT);
        }
        if (NULL == pBufferList->pPrivateMetaData) {
                EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
@@ -879,13 +736,38 @@ inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
         * Otherwise, the meta data shall be freed when the icp_drvOpData is
         * freed.
         */
-       if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers){
-               kfree(pBufferList->pPrivateMetaData);
+       if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
+               icp_kfree(pBufferList->pPrivateMetaData);
        }
 }
 
-module_init(icp_ocfDrvInit);
-module_exit(icp_ocfDrvExit);
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Intel");
-MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
+/* Module declaration, init and exit functions */
+ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
+ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
+ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
+ICP_MODULE_LICENSE("Dual BSD/GPL");
+ICP_MODULE_AUTHOR("Intel");
+
+/* Module parameters */
+ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
+                    "Number of times to retry LAC Sym Session Deregistration. "
+                    "Default 10, Max 100");
+ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
+                    "(added to a schedule() function call) before a LAC Sym "
+                    "Session Dereg is retried. Default 10");
+ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
+                    "This sets the maximum number of sessions "
+                    "between OCF and this driver. If this value is set to zero,"
+                    "max session count checking is disabled. Default is zero(0)");
+
+/* Module dependencies */
+#define MODULE_MIN_VER 1
+#define CRYPTO_MAX_VER 3
+#define LAC_MAX_VER    2
+
+ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
+                 CRYPTO_MAX_VER);
+ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
+                 CRYPTO_MAX_VER);
+ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
+                 LAC_MAX_VER);