The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/842.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Cryptographic API for the 842 compression algorithm.
    3  *
    4  * This program is free software; you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation; either version 2 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with this program; if not, write to the Free Software
   16  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   17  *
   18  * Copyright (C) IBM Corporation, 2011
   19  *
   20  * Authors: Robert Jennings <rcj@linux.vnet.ibm.com>
   21  *          Seth Jennings <sjenning@linux.vnet.ibm.com>
   22  */
   23 
   24 #include <linux/init.h>
   25 #include <linux/module.h>
   26 #include <linux/crypto.h>
   27 #include <linux/vmalloc.h>
   28 #include <linux/nx842.h>
   29 #include <linux/lzo.h>
   30 #include <linux/timer.h>
   31 
   32 static int nx842_uselzo;
   33 
   34 struct nx842_ctx {
   35         void *nx842_wmem; /* working memory for 842/lzo */
   36 };
   37 
   38 enum nx842_crypto_type {
   39         NX842_CRYPTO_TYPE_842,
   40         NX842_CRYPTO_TYPE_LZO
   41 };
   42 
   43 #define NX842_SENTINEL 0xdeadbeef
   44 
   45 struct nx842_crypto_header {
   46         unsigned int sentinel; /* debug */
   47         enum nx842_crypto_type type;
   48 };
   49 
   50 static int nx842_init(struct crypto_tfm *tfm)
   51 {
   52         struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
   53         int wmemsize;
   54 
   55         wmemsize = max_t(int, nx842_get_workmem_size(), LZO1X_MEM_COMPRESS);
   56         ctx->nx842_wmem = kmalloc(wmemsize, GFP_NOFS);
   57         if (!ctx->nx842_wmem)
   58                 return -ENOMEM;
   59 
   60         return 0;
   61 }
   62 
   63 static void nx842_exit(struct crypto_tfm *tfm)
   64 {
   65         struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
   66 
   67         kfree(ctx->nx842_wmem);
   68 }
   69 
   70 static void nx842_reset_uselzo(unsigned long data)
   71 {
   72         nx842_uselzo = 0;
   73 }
   74 
   75 static DEFINE_TIMER(failover_timer, nx842_reset_uselzo, 0, 0);
   76 
   77 static int nx842_crypto_compress(struct crypto_tfm *tfm, const u8 *src,
   78                             unsigned int slen, u8 *dst, unsigned int *dlen)
   79 {
   80         struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
   81         struct nx842_crypto_header *hdr;
   82         unsigned int tmp_len = *dlen;
   83         size_t lzodlen; /* needed for lzo */
   84         int err;
   85 
   86         *dlen = 0;
   87         hdr = (struct nx842_crypto_header *)dst;
   88         hdr->sentinel = NX842_SENTINEL; /* debug */
   89         dst += sizeof(struct nx842_crypto_header);
   90         tmp_len -= sizeof(struct nx842_crypto_header);
   91         lzodlen = tmp_len;
   92 
   93         if (likely(!nx842_uselzo)) {
   94                 err = nx842_compress(src, slen, dst, &tmp_len, ctx->nx842_wmem);
   95 
   96                 if (likely(!err)) {
   97                         hdr->type = NX842_CRYPTO_TYPE_842;
   98                         *dlen = tmp_len + sizeof(struct nx842_crypto_header);
   99                         return 0;
  100                 }
  101 
  102                 /* hardware failed */
  103                 nx842_uselzo = 1;
  104 
  105                 /* set timer to check for hardware again in 1 second */
  106                 mod_timer(&failover_timer, jiffies + msecs_to_jiffies(1000));
  107         }
  108 
  109         /* no hardware, use lzo */
  110         err = lzo1x_1_compress(src, slen, dst, &lzodlen, ctx->nx842_wmem);
  111         if (err != LZO_E_OK)
  112                 return -EINVAL;
  113 
  114         hdr->type = NX842_CRYPTO_TYPE_LZO;
  115         *dlen = lzodlen + sizeof(struct nx842_crypto_header);
  116         return 0;
  117 }
  118 
  119 static int nx842_crypto_decompress(struct crypto_tfm *tfm, const u8 *src,
  120                               unsigned int slen, u8 *dst, unsigned int *dlen)
  121 {
  122         struct nx842_ctx *ctx = crypto_tfm_ctx(tfm);
  123         struct nx842_crypto_header *hdr;
  124         unsigned int tmp_len = *dlen;
  125         size_t lzodlen; /* needed for lzo */
  126         int err;
  127 
  128         *dlen = 0;
  129         hdr = (struct nx842_crypto_header *)src;
  130 
  131         if (unlikely(hdr->sentinel != NX842_SENTINEL))
  132                 return -EINVAL;
  133 
  134         src += sizeof(struct nx842_crypto_header);
  135         slen -= sizeof(struct nx842_crypto_header);
  136 
  137         if (likely(hdr->type == NX842_CRYPTO_TYPE_842)) {
  138                 err = nx842_decompress(src, slen, dst, &tmp_len,
  139                         ctx->nx842_wmem);
  140                 if (err)
  141                         return -EINVAL;
  142                 *dlen = tmp_len;
  143         } else if (hdr->type == NX842_CRYPTO_TYPE_LZO) {
  144                 lzodlen = tmp_len;
  145                 err = lzo1x_decompress_safe(src, slen, dst, &lzodlen);
  146                 if (err != LZO_E_OK)
  147                         return -EINVAL;
  148                 *dlen = lzodlen;
  149         } else
  150                 return -EINVAL;
  151 
  152         return 0;
  153 }
  154 
  155 static struct crypto_alg alg = {
  156         .cra_name               = "842",
  157         .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
  158         .cra_ctxsize            = sizeof(struct nx842_ctx),
  159         .cra_module             = THIS_MODULE,
  160         .cra_init               = nx842_init,
  161         .cra_exit               = nx842_exit,
  162         .cra_u                  = { .compress = {
  163         .coa_compress           = nx842_crypto_compress,
  164         .coa_decompress         = nx842_crypto_decompress } }
  165 };
  166 
  167 static int __init nx842_mod_init(void)
  168 {
  169         del_timer(&failover_timer);
  170         return crypto_register_alg(&alg);
  171 }
  172 
  173 static void __exit nx842_mod_exit(void)
  174 {
  175         crypto_unregister_alg(&alg);
  176 }
  177 
  178 module_init(nx842_mod_init);
  179 module_exit(nx842_mod_exit);
  180 
  181 MODULE_LICENSE("GPL");
  182 MODULE_DESCRIPTION("842 Compression Algorithm");

Cache object: 44bffeca2ff23e66d5011258091539d7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.