remove generic linux 2.4 support
[openwrt/svn-archive/archive.git] / target / linux / generic-2.4 / files / crypto / ocf / talitos / talitos.c
diff --git a/target/linux/generic-2.4/files/crypto/ocf/talitos/talitos.c b/target/linux/generic-2.4/files/crypto/ocf/talitos/talitos.c
deleted file mode 100644 (file)
index 9404634..0000000
+++ /dev/null
@@ -1,1359 +0,0 @@
-/*
- * crypto/ocf/talitos/talitos.c
- *
- * An OCF-Linux module that uses Freescale's SEC to do the crypto.
- * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
- *
- * Copyright (c) 2006 Freescale Semiconductor, Inc.
- *
- * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
- * some code copied from files with the following:
- * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ---------------------------------------------------------------------------
- *
- * NOTES:
- *
- * The Freescale SEC (also known as 'talitos') resides on the
- * internal bus, and runs asynchronous to the processor core.  It has
- * a wide gamut of cryptographic acceleration features, including single-
- * pass IPsec (also known as algorithm chaining).  To properly utilize 
- * all of the SEC's performance enhancing features, further reworking 
- * of higher level code (framework, applications) will be necessary.
- *
- * The following table shows which SEC version is present in which devices:
- * 
- * Devices       SEC version
- *
- * 8272, 8248    SEC 1.0
- * 885, 875      SEC 1.2
- * 8555E, 8541E  SEC 2.0
- * 8349E         SEC 2.01
- * 8548E         SEC 2.1
- *
- * The following table shows the features offered by each SEC version:
- *
- *                            Max.   chan-
- * version  Bus I/F       Clock  nels  DEU AESU AFEU MDEU PKEU RNG KEU
- *
- * SEC 1.0  internal 64b  100MHz   4     1    1    1    1    1   1   0
- * SEC 1.2  internal 32b   66MHz   1     1    1    0    1    0   0   0
- * SEC 2.0  internal 64b  166MHz   4     1    1    1    1    1   1   0
- * SEC 2.01 internal 64b  166MHz   4     1    1    1    1    1   1   0
- * SEC 2.1  internal 64b  333MHz   4     1    1    1    1    1   1   1
- *
- * Each execution unit in the SEC has two modes of execution; channel and
- * slave/debug.  This driver employs the channel infrastructure in the
- * device for convenience.  Only the RNG is directly accessed due to the
- * convenience of its random fifo pool.  The relationship between the
- * channels and execution units is depicted in the following diagram:
- *
- *    -------   ------------
- * ---| ch0 |---|          |
- *    -------   |          |
- *              |          |------+-------+-------+-------+------------
- *    -------   |          |      |       |       |       |           |
- * ---| ch1 |---|          |      |       |       |       |           |
- *    -------   |          |   ------  ------  ------  ------      ------
- *              |controller|   |DEU |  |AESU|  |MDEU|  |PKEU| ...  |RNG |
- *    -------   |          |   ------  ------  ------  ------      ------
- * ---| ch2 |---|          |      |       |       |       |           |
- *    -------   |          |      |       |       |       |           |
- *              |          |------+-------+-------+-------+------------
- *    -------   |          |
- * ---| ch3 |---|          |
- *    -------   ------------
- *
- * Channel ch0 may drive an aes operation to the aes unit (AESU),
- * and, at the same time, ch1 may drive a message digest operation
- * to the mdeu. Each channel has an input descriptor FIFO, and the 
- * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
- * a buffer overrun error is triggered. The controller is responsible
- * for fetching the data from descriptor pointers, and passing the 
- * data to the appropriate EUs. The controller also writes the 
- * cryptographic operation's result to memory. The SEC notifies 
- * completion by triggering an interrupt and/or setting the 1st byte 
- * of the hdr field to 0xff.
- *
- * TODO:
- * o support more algorithms
- * o support more versions of the SEC
- * o add support for linux 2.4
- * o scatter-gather (sg) support
- * o add support for public key ops (PKEU)
- * o add statistics
- */
-
-#ifndef AUTOCONF_INCLUDED
-#include <linux/config.h>
-#endif
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <asm/scatterlist.h>
-#include <linux/dma-mapping.h>  /* dma_map_single() */
-#include <linux/moduleparam.h>
-
-#include <linux/version.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
-#include <linux/platform_device.h>
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-#include <linux/of_platform.h>
-#endif
-
-#include <cryptodev.h>
-#include <uio.h>
-
-#define DRV_NAME "talitos" 
-
-#include "talitos_dev.h"
-#include "talitos_soft.h"
-
-#define read_random(p,l) get_random_bytes(p,l)
-
-const char talitos_driver_name[] = "Talitos OCF";
-const char talitos_driver_version[] = "0.2";
-
-static int talitos_newsession(device_t dev, u_int32_t *sidp,
-                                                               struct cryptoini *cri);
-static int talitos_freesession(device_t dev, u_int64_t tid);
-static int talitos_process(device_t dev, struct cryptop *crp, int hint);
-static void dump_talitos_status(struct talitos_softc *sc);
-static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td, 
-                                                               int chsel);
-static void talitos_doneprocessing(struct talitos_softc *sc);
-static void talitos_init_device(struct talitos_softc *sc);
-static void talitos_reset_device_master(struct talitos_softc *sc);
-static void talitos_reset_device(struct talitos_softc *sc);
-static void talitos_errorprocessing(struct talitos_softc *sc);
-#ifdef CONFIG_PPC_MERGE
-static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
-static int talitos_remove(struct of_device *ofdev);
-#else
-static int talitos_probe(struct platform_device *pdev);
-static int talitos_remove(struct platform_device *pdev);
-#endif
-#ifdef CONFIG_OCF_RANDOMHARVEST
-static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
-static void talitos_rng_init(struct talitos_softc *sc);
-#endif
-
-static device_method_t talitos_methods = {
-       /* crypto device methods */
-       DEVMETHOD(cryptodev_newsession, talitos_newsession),
-       DEVMETHOD(cryptodev_freesession,talitos_freesession),
-       DEVMETHOD(cryptodev_process,    talitos_process),
-};
-
-#define debug talitos_debug
-int talitos_debug = 0;
-module_param(talitos_debug, int, 0644);
-MODULE_PARM_DESC(talitos_debug, "Enable debug");
-
-static inline void talitos_write(volatile unsigned *addr, u32 val)
-{
-        out_be32(addr, val);
-}
-
-static inline u32 talitos_read(volatile unsigned *addr)
-{
-        u32 val;
-        val = in_be32(addr);
-        return val;
-}
-
-static void dump_talitos_status(struct talitos_softc *sc)
-{
-       unsigned int v, v_hi, i, *ptr;
-       v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
-       v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
-       printk(KERN_INFO "%s: MCR          0x%08x_%08x\n",
-                       device_get_nameunit(sc->sc_cdev), v, v_hi);
-       v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
-       v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
-       printk(KERN_INFO "%s: IMR          0x%08x_%08x\n",
-                       device_get_nameunit(sc->sc_cdev), v, v_hi);
-       v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
-       v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
-       printk(KERN_INFO "%s: ISR          0x%08x_%08x\n",
-                       device_get_nameunit(sc->sc_cdev), v, v_hi);
-       for (i = 0; i < sc->sc_num_channels; i++) { 
-               v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + 
-                       TALITOS_CH_CDPR);
-               v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + 
-                       TALITOS_CH_CDPR_HI);
-               printk(KERN_INFO "%s: CDPR     ch%d 0x%08x_%08x\n", 
-                               device_get_nameunit(sc->sc_cdev), i, v, v_hi);
-       }
-       for (i = 0; i < sc->sc_num_channels; i++) { 
-               v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + 
-                       TALITOS_CH_CCPSR);
-               v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET + 
-                       TALITOS_CH_CCPSR_HI);
-               printk(KERN_INFO "%s: CCPSR    ch%d 0x%08x_%08x\n", 
-                               device_get_nameunit(sc->sc_cdev), i, v, v_hi);
-       }
-       ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
-       for (i = 0; i < 16; i++) { 
-               v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
-               printk(KERN_INFO "%s: DESCBUF  ch0 0x%08x_%08x (tdp%02d)\n", 
-                               device_get_nameunit(sc->sc_cdev), v, v_hi, i);
-       }
-       return;
-}
-
-
-#ifdef CONFIG_OCF_RANDOMHARVEST
-/* 
- * pull random numbers off the RNG FIFO, not exceeding amount available
- */
-static int
-talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
-{
-       struct talitos_softc *sc = (struct talitos_softc *) arg;
-       int rc;
-       u_int32_t v;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-
-       /* check for things like FIFO underflow */
-       v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
-       if (unlikely(v)) {
-               printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
-                               device_get_nameunit(sc->sc_cdev), v);
-               return 0;
-       }
-       /*
-        * OFL is number of available 64-bit words, 
-        * shift and convert to a 32-bit word count
-        */
-       v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
-       v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
-       if (maxwords > v)
-               maxwords = v;
-       for (rc = 0; rc < maxwords; rc++) {
-               buf[rc] = talitos_read(sc->sc_base_addr + 
-                       TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
-       }
-       if (maxwords & 1) {
-               /* 
-                * RNG will complain with an AE in the RNGISR
-                * if we don't complete the pairs of 32-bit reads
-                * to its 64-bit register based FIFO
-                */
-               v = talitos_read(sc->sc_base_addr + 
-                       TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
-       }
-
-       return rc;
-}
-
-static void
-talitos_rng_init(struct talitos_softc *sc)
-{
-       u_int32_t v;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-       /* reset RNG EU */
-       v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
-       v |= TALITOS_RNGRCR_HI_SR;
-       talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
-       while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI) 
-               & TALITOS_RNGSR_HI_RD) == 0)
-                       cpu_relax();
-       /*
-        * we tell the RNG to start filling the RNG FIFO
-        * by writing the RNGDSR 
-        */
-       v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
-       talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
-       /*
-        * 64 bits of data will be pushed onto the FIFO every 
-        * 256 SEC cycles until the FIFO is full.  The RNG then 
-        * attempts to keep the FIFO full.
-        */
-       v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
-       if (v) {
-               printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
-                       device_get_nameunit(sc->sc_cdev), v);
-               return;
-       }
-       /*
-        * n.b. we need to add a FIPS test here - if the RNG is going 
-        * to fail, it's going to fail at reset time
-        */
-       return;
-}
-#endif /* CONFIG_OCF_RANDOMHARVEST */
-
-/*
- * Generate a new software session.
- */
-static int
-talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
-{
-       struct cryptoini *c, *encini = NULL, *macini = NULL;
-       struct talitos_softc *sc = device_get_softc(dev);
-       struct talitos_session *ses = NULL;
-       int sesn;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-       if (sidp == NULL || cri == NULL || sc == NULL) {
-               DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
-               return EINVAL;
-       }
-       for (c = cri; c != NULL; c = c->cri_next) {
-               if (c->cri_alg == CRYPTO_MD5 ||
-                   c->cri_alg == CRYPTO_MD5_HMAC ||
-                   c->cri_alg == CRYPTO_SHA1 ||
-                   c->cri_alg == CRYPTO_SHA1_HMAC ||
-                   c->cri_alg == CRYPTO_NULL_HMAC) {
-                       if (macini)
-                               return EINVAL;
-                       macini = c;
-               } else if (c->cri_alg == CRYPTO_DES_CBC ||
-                   c->cri_alg == CRYPTO_3DES_CBC ||
-                   c->cri_alg == CRYPTO_AES_CBC ||
-                   c->cri_alg == CRYPTO_NULL_CBC) {
-                       if (encini)
-                               return EINVAL;
-                       encini = c;
-               } else {
-                       DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
-                       return EINVAL;
-               }
-       }
-       if (encini == NULL && macini == NULL)
-               return EINVAL;
-       if (encini) {   
-               /* validate key length */
-               switch (encini->cri_alg) {
-               case CRYPTO_DES_CBC:
-                       if (encini->cri_klen != 64)
-                               return EINVAL;
-                       break;
-               case CRYPTO_3DES_CBC:
-                       if (encini->cri_klen != 192) {
-                               return EINVAL;
-                       }
-                       break;
-               case CRYPTO_AES_CBC:
-                       if (encini->cri_klen != 128 &&
-                           encini->cri_klen != 192 &&
-                           encini->cri_klen != 256)
-                               return EINVAL;
-                       break;
-               default:
-                       DPRINTF("UNKNOWN encini->cri_alg %d\n", 
-                               encini->cri_alg);
-                       return EINVAL;
-               }
-       }
-
-       if (sc->sc_sessions == NULL) {
-               ses = sc->sc_sessions = (struct talitos_session *)
-                       kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
-               if (ses == NULL)
-                       return ENOMEM;
-               memset(ses, 0, sizeof(struct talitos_session));
-               sesn = 0;
-               sc->sc_nsessions = 1;
-       } else {
-               for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
-                       if (sc->sc_sessions[sesn].ses_used == 0) {
-                               ses = &sc->sc_sessions[sesn];
-                               break;
-                       }
-               }
-
-               if (ses == NULL) {
-                       /* allocating session */
-                       sesn = sc->sc_nsessions;
-                       ses = (struct talitos_session *) kmalloc(
-                               (sesn + 1) * sizeof(struct talitos_session), 
-                               SLAB_ATOMIC);
-                       if (ses == NULL)
-                               return ENOMEM;
-                       memset(ses, 0,
-                               (sesn + 1) * sizeof(struct talitos_session));
-                       memcpy(ses, sc->sc_sessions, 
-                               sesn * sizeof(struct talitos_session));
-                       memset(sc->sc_sessions, 0,
-                               sesn * sizeof(struct talitos_session));
-                       kfree(sc->sc_sessions);
-                       sc->sc_sessions = ses;
-                       ses = &sc->sc_sessions[sesn];
-                       sc->sc_nsessions++;
-               }
-       }
-
-       ses->ses_used = 1;
-
-       if (encini) {
-               /* get an IV */
-               /* XXX may read fewer than requested */
-               read_random(ses->ses_iv, sizeof(ses->ses_iv));
-
-               ses->ses_klen = (encini->cri_klen + 7) / 8;
-               memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
-               if (macini) {
-                       /* doing hash on top of cipher */
-                       ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
-                       memcpy(ses->ses_hmac, macini->cri_key,
-                               ses->ses_hmac_len);
-               }
-       } else if (macini) {
-               /* doing hash */
-               ses->ses_klen = (macini->cri_klen + 7) / 8;
-               memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
-       }
-
-       /* back compat way of determining MSC result len */
-       if (macini) {
-               ses->ses_mlen = macini->cri_mlen;
-               if (ses->ses_mlen == 0) {
-                       if (macini->cri_alg == CRYPTO_MD5_HMAC)
-                               ses->ses_mlen = MD5_HASH_LEN;
-                       else
-                               ses->ses_mlen = SHA1_HASH_LEN;
-               }
-       }
-
-       /* really should make up a template td here, 
-        * and only fill things like i/o and direction in process() */
-
-       /* assign session ID */
-       *sidp = TALITOS_SID(sc->sc_num, sesn);
-       return 0;
-}
-
-/*
- * Deallocate a session.
- */
-static int
-talitos_freesession(device_t dev, u_int64_t tid)
-{
-       struct talitos_softc *sc = device_get_softc(dev);
-       int session, ret;
-       u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
-
-       if (sc == NULL)
-               return EINVAL;
-       session = TALITOS_SESSION(sid);
-       if (session < sc->sc_nsessions) {
-               memset(&sc->sc_sessions[session], 0,
-                       sizeof(sc->sc_sessions[session]));
-               ret = 0;
-       } else
-               ret = EINVAL;
-       return ret;
-}
-
-/*
- * launch device processing - it will come back with done notification 
- * in the form of an interrupt and/or HDR_DONE_BITS in header 
- */
-static int 
-talitos_submit(
-       struct talitos_softc *sc,
-       struct talitos_desc *td,
-       int chsel)
-{
-       u_int32_t v;
-
-       v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
-       talitos_write(sc->sc_base_addr + 
-               chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
-       talitos_write(sc->sc_base_addr + 
-               chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
-       return 0;
-}
-
-static int
-talitos_process(device_t dev, struct cryptop *crp, int hint)
-{
-       int i, err = 0, ivsize;
-       struct talitos_softc *sc = device_get_softc(dev);
-       struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
-       caddr_t iv;
-       struct talitos_session *ses;
-       struct talitos_desc *td;
-       unsigned long flags;
-       /* descriptor mappings */
-       int hmac_key, hmac_data, cipher_iv, cipher_key, 
-               in_fifo, out_fifo, cipher_iv_out;
-       static int chsel = -1;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-
-       if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
-               return EINVAL;
-       }
-       crp->crp_etype = 0;
-       if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
-               return EINVAL;
-       }
-
-       ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
-
-        /* enter the channel scheduler */ 
-       spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
-
-       /* reuse channel that already had/has requests for the required EU */
-       for (i = 0; i < sc->sc_num_channels; i++) {
-               if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
-                       break;
-       }
-       if (i == sc->sc_num_channels) {
-               /*
-                * haven't seen this algo the last sc_num_channels or more
-                * use round robin in this case
-                * nb: sc->sc_num_channels must be power of 2 
-                */
-               chsel = (chsel + 1) & (sc->sc_num_channels - 1);
-       } else {
-               /*
-                * matches channel with same target execution unit; 
-                * use same channel in this case
-                */
-               chsel = i;
-       }
-       sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
-
-        /* release the channel scheduler lock */ 
-       spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
-
-       /* acquire the selected channel fifo lock */
-       spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
-
-       /* find and reserve next available descriptor-cryptop pair */
-       for (i = 0; i < sc->sc_chfifo_len; i++) {
-               if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
-                       /* 
-                        * ensure correct descriptor formation by
-                        * avoiding inadvertently setting "optional" entries
-                        * e.g. not using "optional" dptr2 for MD/HMAC descs
-                        */
-                       memset(&sc->sc_chnfifo[chsel][i].cf_desc,
-                               0, sizeof(*td));
-                       /* reserve it with done notification request bit */
-                       sc->sc_chnfifo[chsel][i].cf_desc.hdr |= 
-                               TALITOS_DONE_NOTIFY;
-                       break;
-               }
-       }
-       spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
-
-       if (i == sc->sc_chfifo_len) {
-               /* fifo full */
-               err = ERESTART;
-               goto errout;
-       }
-       
-       td = &sc->sc_chnfifo[chsel][i].cf_desc;
-       sc->sc_chnfifo[chsel][i].cf_crp = crp;
-
-       crd1 = crp->crp_desc;
-       if (crd1 == NULL) {
-               err = EINVAL;
-               goto errout;
-       }
-       crd2 = crd1->crd_next;
-       /* prevent compiler warning */
-       hmac_key = 0;
-       hmac_data = 0;
-       if (crd2 == NULL) {
-               td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
-               /* assign descriptor dword ptr mappings for this desc. type */
-               cipher_iv = 1;
-               cipher_key = 2;
-               in_fifo = 3;
-               cipher_iv_out = 5;
-               if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
-                   crd1->crd_alg == CRYPTO_SHA1_HMAC ||
-                   crd1->crd_alg == CRYPTO_SHA1 ||
-                   crd1->crd_alg == CRYPTO_MD5) {
-                       out_fifo = 5;
-                       maccrd = crd1;
-                       enccrd = NULL;
-               } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
-                   crd1->crd_alg == CRYPTO_3DES_CBC ||
-                   crd1->crd_alg == CRYPTO_AES_CBC ||
-                   crd1->crd_alg == CRYPTO_ARC4) {
-                       out_fifo = 4;
-                       maccrd = NULL;
-                       enccrd = crd1;
-               } else {
-                       DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
-                       err = EINVAL;
-                       goto errout;
-               }
-       } else {
-               if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
-                       td->hdr |= TD_TYPE_IPSEC_ESP;
-               } else {
-                       DPRINTF("unimplemented: multiple descriptor ipsec\n");
-                       err = EINVAL;
-                       goto errout;
-               }
-               /* assign descriptor dword ptr mappings for this desc. type */
-               hmac_key = 0;
-               hmac_data = 1;
-               cipher_iv = 2;
-               cipher_key = 3;
-               in_fifo = 4;
-               out_fifo = 5;
-               cipher_iv_out = 6;
-               if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
-                     crd1->crd_alg == CRYPTO_SHA1_HMAC ||
-                     crd1->crd_alg == CRYPTO_MD5 ||
-                     crd1->crd_alg == CRYPTO_SHA1) &&
-                   (crd2->crd_alg == CRYPTO_DES_CBC ||
-                    crd2->crd_alg == CRYPTO_3DES_CBC ||
-                    crd2->crd_alg == CRYPTO_AES_CBC ||
-                    crd2->crd_alg == CRYPTO_ARC4) &&
-                   ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
-                       maccrd = crd1;
-                       enccrd = crd2;
-               } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
-                    crd1->crd_alg == CRYPTO_ARC4 ||
-                    crd1->crd_alg == CRYPTO_3DES_CBC ||
-                    crd1->crd_alg == CRYPTO_AES_CBC) &&
-                   (crd2->crd_alg == CRYPTO_MD5_HMAC ||
-                     crd2->crd_alg == CRYPTO_SHA1_HMAC ||
-                     crd2->crd_alg == CRYPTO_MD5 ||
-                     crd2->crd_alg == CRYPTO_SHA1) &&
-                   (crd1->crd_flags & CRD_F_ENCRYPT)) {
-                       enccrd = crd1;
-                       maccrd = crd2;
-               } else {
-                       /* We cannot order the SEC as requested */
-                       printk("%s: cannot do the order\n",
-                                       device_get_nameunit(sc->sc_cdev));
-                       err = EINVAL;
-                       goto errout;
-               }
-       }
-       /* assign in_fifo and out_fifo based on input/output struct type */
-       if (crp->crp_flags & CRYPTO_F_SKBUF) {
-               /* using SKB buffers */
-               struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
-               if (skb_shinfo(skb)->nr_frags) {
-                       printk("%s: skb frags unimplemented\n",
-                                       device_get_nameunit(sc->sc_cdev));
-                       err = EINVAL;
-                       goto errout;
-               }
-               td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data, 
-                       skb->len, DMA_TO_DEVICE);
-               td->ptr[in_fifo].len = skb->len;
-               td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data, 
-                       skb->len, DMA_TO_DEVICE);
-               td->ptr[out_fifo].len = skb->len;
-               td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
-                       skb->len, DMA_TO_DEVICE);
-       } else if (crp->crp_flags & CRYPTO_F_IOV) {
-               /* using IOV buffers */
-               struct uio *uiop = (struct uio *)crp->crp_buf;
-               if (uiop->uio_iovcnt > 1) {
-                       printk("%s: iov frags unimplemented\n",
-                                       device_get_nameunit(sc->sc_cdev));
-                       err = EINVAL;
-                       goto errout;
-               }
-               td->ptr[in_fifo].ptr = dma_map_single(NULL,
-                       uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
-               td->ptr[in_fifo].len = crp->crp_ilen;
-               /* crp_olen is never set; always use crp_ilen */
-               td->ptr[out_fifo].ptr = dma_map_single(NULL,
-                       uiop->uio_iov->iov_base,
-                       crp->crp_ilen, DMA_TO_DEVICE);
-               td->ptr[out_fifo].len = crp->crp_ilen;
-       } else {
-               /* using contig buffers */
-               td->ptr[in_fifo].ptr = dma_map_single(NULL,
-                       crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
-               td->ptr[in_fifo].len = crp->crp_ilen;
-               td->ptr[out_fifo].ptr = dma_map_single(NULL,
-                       crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
-               td->ptr[out_fifo].len = crp->crp_ilen;
-       }
-       if (enccrd) {
-               switch (enccrd->crd_alg) {
-               case CRYPTO_3DES_CBC:
-                       td->hdr |= TALITOS_MODE0_DEU_3DES;
-                       /* FALLTHROUGH */
-               case CRYPTO_DES_CBC:
-                       td->hdr |= TALITOS_SEL0_DEU
-                               |  TALITOS_MODE0_DEU_CBC;
-                       if (enccrd->crd_flags & CRD_F_ENCRYPT)
-                               td->hdr |= TALITOS_MODE0_DEU_ENC;
-                       ivsize = 2*sizeof(u_int32_t);
-                       DPRINTF("%cDES ses %d ch %d len %d\n",
-                               (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
-                               (u32)TALITOS_SESSION(crp->crp_sid),
-                               chsel, td->ptr[in_fifo].len);
-                       break;
-               case CRYPTO_AES_CBC:
-                       td->hdr |= TALITOS_SEL0_AESU
-                               |  TALITOS_MODE0_AESU_CBC;
-                       if (enccrd->crd_flags & CRD_F_ENCRYPT)
-                               td->hdr |= TALITOS_MODE0_AESU_ENC;
-                       ivsize = 4*sizeof(u_int32_t);
-                       DPRINTF("AES  ses %d ch %d len %d\n",
-                               (u32)TALITOS_SESSION(crp->crp_sid),
-                               chsel, td->ptr[in_fifo].len);
-                       break;
-               default:
-                       printk("%s: unimplemented enccrd->crd_alg %d\n",
-                                       device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
-                       err = EINVAL;
-                       goto errout;
-               }
-               /*
-                * Setup encrypt/decrypt state.  When using basic ops
-                * we can't use an inline IV because hash/crypt offset
-                * must be from the end of the IV to the start of the
-                * crypt data and this leaves out the preceding header
-                * from the hash calculation.  Instead we place the IV
-                * in the state record and set the hash/crypt offset to
-                * copy both the header+IV.
-                */
-               if (enccrd->crd_flags & CRD_F_ENCRYPT) {
-                       td->hdr |= TALITOS_DIR_OUTBOUND; 
-                       if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
-                               iv = enccrd->crd_iv;
-                       else
-                               iv = (caddr_t) ses->ses_iv;
-                       if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
-                               crypto_copyback(crp->crp_flags, crp->crp_buf,
-                                   enccrd->crd_inject, ivsize, iv);
-                       }
-               } else {
-                       td->hdr |= TALITOS_DIR_INBOUND; 
-                       if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
-                               iv = enccrd->crd_iv;
-                               bcopy(enccrd->crd_iv, iv, ivsize);
-                       } else {
-                               iv = (caddr_t) ses->ses_iv;
-                               crypto_copydata(crp->crp_flags, crp->crp_buf,
-                                   enccrd->crd_inject, ivsize, iv);
-                       }
-               }
-               td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize, 
-                       DMA_TO_DEVICE);
-               td->ptr[cipher_iv].len = ivsize;
-               /*
-                * we don't need the cipher iv out length/pointer
-                * field to do ESP IPsec. Therefore we set the len field as 0,
-                * which tells the SEC not to do anything with this len/ptr
-                * field. Previously, when length/pointer as pointing to iv,
-                * it gave us corruption of packets.
-                */
-               td->ptr[cipher_iv_out].len = 0;
-       }
-       if (enccrd && maccrd) {
-               /* this is ipsec only for now */
-               td->hdr |= TALITOS_SEL1_MDEU
-                       |  TALITOS_MODE1_MDEU_INIT
-                       |  TALITOS_MODE1_MDEU_PAD;
-               switch (maccrd->crd_alg) {
-                       case    CRYPTO_MD5:     
-                               td->hdr |= TALITOS_MODE1_MDEU_MD5;
-                               break;
-                       case    CRYPTO_MD5_HMAC:        
-                               td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
-                               break;
-                       case    CRYPTO_SHA1:    
-                               td->hdr |= TALITOS_MODE1_MDEU_SHA1;
-                               break;
-                       case    CRYPTO_SHA1_HMAC:       
-                               td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
-                               break;
-                       default:
-                               /* We cannot order the SEC as requested */
-                               printk("%s: cannot do the order\n",
-                                               device_get_nameunit(sc->sc_cdev));
-                               err = EINVAL;
-                               goto errout;
-               }
-               if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
-                  (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
-                       /*
-                        * The offset from hash data to the start of
-                        * crypt data is the difference in the skips.
-                        */
-                       /* ipsec only for now */
-                       td->ptr[hmac_key].ptr = dma_map_single(NULL, 
-                               ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
-                       td->ptr[hmac_key].len = ses->ses_hmac_len;
-                       td->ptr[in_fifo].ptr  += enccrd->crd_skip;
-                       td->ptr[in_fifo].len  =  enccrd->crd_len;
-                       td->ptr[out_fifo].ptr += enccrd->crd_skip;
-                       td->ptr[out_fifo].len =  enccrd->crd_len;
-                       /* bytes of HMAC to postpend to ciphertext */
-                       td->ptr[out_fifo].extent =  ses->ses_mlen;
-                       td->ptr[hmac_data].ptr += maccrd->crd_skip; 
-                       td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
-               }
-               if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
-                       printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
-                                       device_get_nameunit(sc->sc_cdev));
-               }
-       }
-       if (!enccrd && maccrd) {
-               /* single MD5 or SHA */
-               td->hdr |= TALITOS_SEL0_MDEU
-                               |  TALITOS_MODE0_MDEU_INIT
-                               |  TALITOS_MODE0_MDEU_PAD;
-               switch (maccrd->crd_alg) {
-                       case    CRYPTO_MD5:     
-                               td->hdr |= TALITOS_MODE0_MDEU_MD5;
-                               DPRINTF("MD5  ses %d ch %d len %d\n",
-                                       (u32)TALITOS_SESSION(crp->crp_sid), 
-                                       chsel, td->ptr[in_fifo].len);
-                               break;
-                       case    CRYPTO_MD5_HMAC:        
-                               td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
-                               break;
-                       case    CRYPTO_SHA1:    
-                               td->hdr |= TALITOS_MODE0_MDEU_SHA1;
-                               DPRINTF("SHA1 ses %d ch %d len %d\n",
-                                       (u32)TALITOS_SESSION(crp->crp_sid), 
-                                       chsel, td->ptr[in_fifo].len);
-                               break;
-                       case    CRYPTO_SHA1_HMAC:       
-                               td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
-                               break;
-                       default:
-                               /* We cannot order the SEC as requested */
-                               DPRINTF("cannot do the order\n");
-                               err = EINVAL;
-                               goto errout;
-               }
-
-               if (crp->crp_flags & CRYPTO_F_IOV)
-                       td->ptr[out_fifo].ptr += maccrd->crd_inject;
-
-               if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
-                  (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
-                       td->ptr[hmac_key].ptr = dma_map_single(NULL, 
-                               ses->ses_hmac, ses->ses_hmac_len, 
-                               DMA_TO_DEVICE);
-                       td->ptr[hmac_key].len = ses->ses_hmac_len;
-               }
-       } 
-       else {
-               /* using process key (session data has duplicate) */
-               td->ptr[cipher_key].ptr = dma_map_single(NULL, 
-                       enccrd->crd_key, (enccrd->crd_klen + 7) / 8, 
-                       DMA_TO_DEVICE);
-               td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
-       }
-       /* descriptor complete - GO! */
-       return talitos_submit(sc, td, chsel);
-
-errout:
-       if (err != ERESTART) {
-               crp->crp_etype = err;
-               crypto_done(crp);
-       }
-       return err;
-}
-
-/* go through all channels descriptors, notifying OCF what has 
- * _and_hasn't_ successfully completed and reset the device 
- * (otherwise it's up to decoding desc hdrs!)
- */
-static void talitos_errorprocessing(struct talitos_softc *sc)
-{
-       unsigned long flags;
-       int i, j;
-
-       /* disable further scheduling until under control */
-       spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
-
-       if (debug) dump_talitos_status(sc);
-       /* go through descriptors, try and salvage those successfully done, 
-        * and EIO those that weren't
-        */
-       for (i = 0; i < sc->sc_num_channels; i++) {
-               spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
-               for (j = 0; j < sc->sc_chfifo_len; j++) {
-                       if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
-                               if ((sc->sc_chnfifo[i][j].cf_desc.hdr 
-                                       & TALITOS_HDR_DONE_BITS) 
-                                       != TALITOS_HDR_DONE_BITS) {
-                                       /* this one didn't finish */
-                                       /* signify in crp->etype */
-                                       sc->sc_chnfifo[i][j].cf_crp->crp_etype 
-                                               = EIO;
-                               }
-                       } else
-                               continue; /* free entry */
-                       /* either way, notify ocf */
-                       crypto_done(sc->sc_chnfifo[i][j].cf_crp);
-                       /* and tag it available again
-                        *
-                        * memset to ensure correct descriptor formation by
-                        * avoiding inadvertently setting "optional" entries
-                        * e.g. not using "optional" dptr2 MD/HMAC processing
-                        */
-                       memset(&sc->sc_chnfifo[i][j].cf_desc,
-                               0, sizeof(struct talitos_desc));
-               }
-               spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
-       }
-       /* reset and initialize the SEC h/w device */
-       talitos_reset_device(sc);
-       talitos_init_device(sc);
-#ifdef CONFIG_OCF_RANDOMHARVEST
-       if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
-               talitos_rng_init(sc);
-#endif
-
-       /* Okay. Stand by. */
-       spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
-
-       return;
-}
-
-/* go through all channels descriptors, notifying OCF what's been done */
-static void talitos_doneprocessing(struct talitos_softc *sc)
-{
-       unsigned long flags;
-       int i, j;
-
-       /* go through descriptors looking for done bits */
-       for (i = 0; i < sc->sc_num_channels; i++) {
-               spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
-               for (j = 0; j < sc->sc_chfifo_len; j++) {
-                       /* descriptor has done bits set? */
-                       if ((sc->sc_chnfifo[i][j].cf_desc.hdr 
-                               & TALITOS_HDR_DONE_BITS) 
-                               == TALITOS_HDR_DONE_BITS) {
-                               /* notify ocf */
-                               crypto_done(sc->sc_chnfifo[i][j].cf_crp);
-                               /* and tag it available again
-                                *
-                                * memset to ensure correct descriptor formation by
-                                * avoiding inadvertently setting "optional" entries
-                                * e.g. not using "optional" dptr2 MD/HMAC processing
-                                */
-                               memset(&sc->sc_chnfifo[i][j].cf_desc,
-                                       0, sizeof(struct talitos_desc));
-                       }
-               }
-               spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
-       }
-       return;
-}
-
-static irqreturn_t
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
-talitos_intr(int irq, void *arg)
-#else
-talitos_intr(int irq, void *arg, struct pt_regs *regs)
-#endif
-{
-       struct talitos_softc *sc = arg;
-       u_int32_t v, v_hi;
-       
-       /* ack */
-       v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
-       v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
-       talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
-       talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
-
-       if (unlikely(v & TALITOS_ISR_ERROR)) {
-               /* Okay, Houston, we've had a problem here. */
-               printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
-                               device_get_nameunit(sc->sc_cdev), v, v_hi);
-               talitos_errorprocessing(sc);
-       } else
-       if (likely(v & TALITOS_ISR_DONE)) {
-               talitos_doneprocessing(sc);
-       }
-       return IRQ_HANDLED;
-}
-
-/*
- * Initialize registers we need to touch only once.
- */
-static void
-talitos_init_device(struct talitos_softc *sc)
-{
-       u_int32_t v;
-       int i;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-
-       /* init all channels */
-       for (i = 0; i < sc->sc_num_channels; i++) {
-               v = talitos_read(sc->sc_base_addr + 
-                       i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
-               v |= TALITOS_CH_CCCR_HI_CDWE
-                 |  TALITOS_CH_CCCR_HI_CDIE;  /* invoke interrupt if done */
-               talitos_write(sc->sc_base_addr + 
-                       i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
-       }
-       /* enable all interrupts */
-       v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
-       v |= TALITOS_IMR_ALL;
-       talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
-       v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
-       v |= TALITOS_IMR_HI_ERRONLY;
-       talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
-       return;
-}
-
-/*
- * set the master reset bit on the device.
- */
-static void
-talitos_reset_device_master(struct talitos_softc *sc)
-{
-       u_int32_t v;
-
-       /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
-       v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
-       talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
-
-       while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
-               cpu_relax();
-
-       return;
-}
-
-/*
- * Resets the device.  Values in the registers are left as is
- * from the reset (i.e. initial values are assigned elsewhere).
- */
-static void
-talitos_reset_device(struct talitos_softc *sc)
-{
-       u_int32_t v;
-       int i;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-
-       /*
-        * Master reset
-        * errata documentation: warning: certain SEC interrupts 
-        * are not fully cleared by writing the MCR:SWR bit, 
-        * set bit twice to completely reset 
-        */
-       talitos_reset_device_master(sc);        /* once */
-       talitos_reset_device_master(sc);        /* and once again */
-       
-       /* reset all channels */
-       for (i = 0; i < sc->sc_num_channels; i++) {
-               v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
-                       TALITOS_CH_CCCR);
-               talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
-                       TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
-       }
-}
-
-/* Set up the crypto device structure, private data,
- * and anything else we need before we start */
-#ifdef CONFIG_PPC_MERGE
-static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
-#else
-static int talitos_probe(struct platform_device *pdev)
-#endif
-{
-       struct talitos_softc *sc = NULL;
-       struct resource *r;
-#ifdef CONFIG_PPC_MERGE
-       struct device *device = &ofdev->dev;
-       struct device_node *np = ofdev->node;
-       const unsigned int *prop;
-       int err;
-       struct resource res;
-#endif
-       static int num_chips = 0;
-       int rc;
-       int i;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-
-       sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
-       if (!sc)
-               return -ENOMEM;
-       memset(sc, 0, sizeof(*sc));
-
-       softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
-
-       sc->sc_irq = -1;
-       sc->sc_cid = -1;
-#ifndef CONFIG_PPC_MERGE
-       sc->sc_dev = pdev;
-#endif
-       sc->sc_num = num_chips++;
-
-#ifdef CONFIG_PPC_MERGE
-       dev_set_drvdata(device, sc);
-#else
-       platform_set_drvdata(sc->sc_dev, sc);
-#endif
-
-       /* get the irq line */
-#ifdef CONFIG_PPC_MERGE
-       err = of_address_to_resource(np, 0, &res);
-       if (err)
-               return -EINVAL;
-       r = &res;
-
-       sc->sc_irq = irq_of_parse_and_map(np, 0);
-#else
-       /* get a pointer to the register memory */
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-       sc->sc_irq = platform_get_irq(pdev, 0);
-#endif
-       rc = request_irq(sc->sc_irq, talitos_intr, 0,
-                       device_get_nameunit(sc->sc_cdev), sc);
-       if (rc) {
-               printk(KERN_ERR "%s: failed to hook irq %d\n", 
-                               device_get_nameunit(sc->sc_cdev), sc->sc_irq);
-               sc->sc_irq = -1;
-               goto out;
-       }
-
-       sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
-       if (!sc->sc_base_addr) {
-               printk(KERN_ERR "%s: failed to ioremap\n",
-                               device_get_nameunit(sc->sc_cdev));
-               goto out;
-       }
-
-       /* figure out our SEC's properties and capabilities */
-       sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
-                | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
-       DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
-
-#ifdef CONFIG_PPC_MERGE
-       /* get SEC properties from device tree, defaulting to SEC 2.0 */
-
-       prop = of_get_property(np, "num-channels", NULL);
-       sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
-
-       prop = of_get_property(np, "channel-fifo-len", NULL);
-       sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
-
-       prop = of_get_property(np, "exec-units-mask", NULL);
-       sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
-
-       prop = of_get_property(np, "descriptor-types-mask", NULL);
-       sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
-#else
-       /* bulk should go away with openfirmware flat device tree support */
-       if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
-               sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
-               sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
-               sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
-               sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
-       } else {
-               printk(KERN_ERR "%s: failed to id device\n",
-                               device_get_nameunit(sc->sc_cdev));
-               goto out;
-       }
-#endif
-
-       /* + 1 is for the meta-channel lock used by the channel scheduler */
-       sc->sc_chnfifolock = (spinlock_t *) kmalloc(
-               (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
-       if (!sc->sc_chnfifolock)
-               goto out;
-       for (i = 0; i < sc->sc_num_channels + 1; i++) {
-               spin_lock_init(&sc->sc_chnfifolock[i]);
-       }
-
-       sc->sc_chnlastalg = (int *) kmalloc(
-               sc->sc_num_channels * sizeof(int), GFP_KERNEL);
-       if (!sc->sc_chnlastalg)
-               goto out;
-       memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
-
-       sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
-               sc->sc_num_channels * sizeof(struct desc_cryptop_pair *), 
-               GFP_KERNEL);
-       if (!sc->sc_chnfifo)
-               goto out;
-       for (i = 0; i < sc->sc_num_channels; i++) {
-               sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
-                       sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair), 
-                       GFP_KERNEL);
-               if (!sc->sc_chnfifo[i])
-                       goto out;
-               memset(sc->sc_chnfifo[i], 0, 
-                       sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
-       }
-
-       /* reset and initialize the SEC h/w device */
-       talitos_reset_device(sc);
-       talitos_init_device(sc);
-
-       sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
-       if (sc->sc_cid < 0) {
-               printk(KERN_ERR "%s: could not get crypto driver id\n",
-                               device_get_nameunit(sc->sc_cdev));
-               goto out;
-       }
-
-       /* register algorithms with the framework */
-       printk("%s:", device_get_nameunit(sc->sc_cdev));
-
-       if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)  {
-               printk(" rng");
-#ifdef CONFIG_OCF_RANDOMHARVEST
-               talitos_rng_init(sc);
-               crypto_rregister(sc->sc_cid, talitos_read_random, sc);
-#endif
-       }
-       if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
-               printk(" des/3des");
-               crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
-               crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
-       }
-       if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
-               printk(" aes");
-               crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
-       }
-       if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
-               printk(" md5");
-               crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
-               /* HMAC support only with IPsec for now */
-               crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
-               printk(" sha1");
-               crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
-               /* HMAC support only with IPsec for now */
-               crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
-       }
-       printk("\n");
-       return 0;
-
-out:
-#ifndef CONFIG_PPC_MERGE
-       talitos_remove(pdev);
-#endif
-       return -ENOMEM;
-}
-
-#ifdef CONFIG_PPC_MERGE
-static int talitos_remove(struct of_device *ofdev)
-#else
-static int talitos_remove(struct platform_device *pdev)
-#endif
-{
-#ifdef CONFIG_PPC_MERGE
-       struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
-#else
-       struct talitos_softc *sc = platform_get_drvdata(pdev);
-#endif
-       int i;
-
-       DPRINTF("%s()\n", __FUNCTION__);
-       if (sc->sc_cid >= 0)
-               crypto_unregister_all(sc->sc_cid);
-       if (sc->sc_chnfifo) {
-               for (i = 0; i < sc->sc_num_channels; i++)
-                       if (sc->sc_chnfifo[i])
-                               kfree(sc->sc_chnfifo[i]);
-               kfree(sc->sc_chnfifo);
-       }
-       if (sc->sc_chnlastalg)
-               kfree(sc->sc_chnlastalg);
-       if (sc->sc_chnfifolock)
-               kfree(sc->sc_chnfifolock);
-       if (sc->sc_irq != -1)
-               free_irq(sc->sc_irq, sc);
-       if (sc->sc_base_addr)
-               iounmap((void *) sc->sc_base_addr);
-       kfree(sc);
-       return 0;
-}
-
-#ifdef CONFIG_PPC_MERGE
-static struct of_device_id talitos_match[] = {
-       {
-               .type = "crypto",
-               .compatible = "talitos",
-       },
-       {},
-};
-
-MODULE_DEVICE_TABLE(of, talitos_match);
-
-static struct of_platform_driver talitos_driver = {
-       .name           = DRV_NAME,
-       .match_table    = talitos_match,
-       .probe          = talitos_probe,
-       .remove         = talitos_remove,
-};
-
-static int __init talitos_init(void)
-{
-       return of_register_platform_driver(&talitos_driver);
-}
-
-static void __exit talitos_exit(void)
-{
-       of_unregister_platform_driver(&talitos_driver);
-}
-#else
-/* Structure for a platform device driver */
-static struct platform_driver talitos_driver = {
-       .probe = talitos_probe,
-       .remove = talitos_remove,
-       .driver = {
-               .name = "fsl-sec2",
-       }
-};
-
-static int __init talitos_init(void)
-{
-       return platform_driver_register(&talitos_driver);
-}
-
-static void __exit talitos_exit(void)
-{
-       platform_driver_unregister(&talitos_driver);
-}
-#endif
-
-module_init(talitos_init);
-module_exit(talitos_exit);
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("kim.phillips@freescale.com");
-MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");