2016-08-25 11:16:03 +02:00
/*
* zcrypt 2.1 .0
*
* Copyright IBM Corp . 2001 , 2012
* Author ( s ) : Robert Burroughs
* Eric Rossman ( edrossma @ us . ibm . com )
* Cornelia Huck < cornelia . huck @ de . ibm . com >
*
* Hotplug & misc device support : Jochen Roehrig ( roehrig @ de . ibm . com )
* Major cleanup & driver split : Martin Schwidefsky < schwidefsky @ de . ibm . com >
* Ralph Wuerthner < rwuerthn @ de . ibm . com >
* MSGTYPE restruct : Holger Dengler < hd @ linux . vnet . ibm . com >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/interrupt.h>
# include <linux/miscdevice.h>
# include <linux/fs.h>
# include <linux/proc_fs.h>
# include <linux/seq_file.h>
# include <linux/compat.h>
# include <linux/slab.h>
# include <linux/atomic.h>
# include <linux/uaccess.h>
# include <linux/hw_random.h>
# include <linux/debugfs.h>
# include <asm/debug.h>
# include "zcrypt_debug.h"
# include "zcrypt_api.h"
# include "zcrypt_msgtype6.h"
# include "zcrypt_msgtype50.h"
/*
* Device attributes common for all crypto card devices .
*/
static ssize_t zcrypt_card_type_show ( struct device * dev ,
struct device_attribute * attr , char * buf )
{
struct zcrypt_card * zc = to_ap_card ( dev ) - > private ;
return snprintf ( buf , PAGE_SIZE , " %s \n " , zc - > type_string ) ;
}
static DEVICE_ATTR ( type , 0444 , zcrypt_card_type_show , NULL ) ;
static ssize_t zcrypt_card_online_show ( struct device * dev ,
struct device_attribute * attr ,
char * buf )
{
struct zcrypt_card * zc = to_ap_card ( dev ) - > private ;
return snprintf ( buf , PAGE_SIZE , " %d \n " , zc - > online ) ;
}
static ssize_t zcrypt_card_online_store ( struct device * dev ,
struct device_attribute * attr ,
const char * buf , size_t count )
{
struct zcrypt_card * zc = to_ap_card ( dev ) - > private ;
struct zcrypt_queue * zq ;
int online , id ;
if ( sscanf ( buf , " %d \n " , & online ) ! = 1 | | online < 0 | | online > 1 )
return - EINVAL ;
zc - > online = online ;
id = zc - > card - > id ;
2016-11-24 06:45:21 +01:00
ZCRYPT_DBF ( DBF_INFO , " card=%02x online=%d \n " , id , online ) ;
2016-08-25 11:16:03 +02:00
spin_lock ( & zcrypt_list_lock ) ;
list_for_each_entry ( zq , & zc - > zqueues , list )
zcrypt_queue_force_online ( zq , online ) ;
spin_unlock ( & zcrypt_list_lock ) ;
return count ;
}
static DEVICE_ATTR ( online , 0644 , zcrypt_card_online_show ,
zcrypt_card_online_store ) ;
static struct attribute * zcrypt_card_attrs [ ] = {
& dev_attr_type . attr ,
& dev_attr_online . attr ,
NULL ,
} ;
static struct attribute_group zcrypt_card_attr_group = {
. attrs = zcrypt_card_attrs ,
} ;
struct zcrypt_card * zcrypt_card_alloc ( void )
{
struct zcrypt_card * zc ;
zc = kzalloc ( sizeof ( struct zcrypt_card ) , GFP_KERNEL ) ;
if ( ! zc )
return NULL ;
INIT_LIST_HEAD ( & zc - > list ) ;
INIT_LIST_HEAD ( & zc - > zqueues ) ;
kref_init ( & zc - > refcount ) ;
return zc ;
}
EXPORT_SYMBOL ( zcrypt_card_alloc ) ;
void zcrypt_card_free ( struct zcrypt_card * zc )
{
kfree ( zc ) ;
}
EXPORT_SYMBOL ( zcrypt_card_free ) ;
static void zcrypt_card_release ( struct kref * kref )
{
struct zcrypt_card * zdev =
container_of ( kref , struct zcrypt_card , refcount ) ;
zcrypt_card_free ( zdev ) ;
}
void zcrypt_card_get ( struct zcrypt_card * zc )
{
kref_get ( & zc - > refcount ) ;
}
EXPORT_SYMBOL ( zcrypt_card_get ) ;
int zcrypt_card_put ( struct zcrypt_card * zc )
{
return kref_put ( & zc - > refcount , zcrypt_card_release ) ;
}
EXPORT_SYMBOL ( zcrypt_card_put ) ;
/**
* zcrypt_card_register ( ) - Register a crypto card device .
* @ zc : Pointer to a crypto card device
*
* Register a crypto card device . Returns 0 if successful .
*/
int zcrypt_card_register ( struct zcrypt_card * zc )
{
int rc ;
rc = sysfs_create_group ( & zc - > card - > ap_dev . device . kobj ,
& zcrypt_card_attr_group ) ;
if ( rc )
return rc ;
spin_lock ( & zcrypt_list_lock ) ;
list_add_tail ( & zc - > list , & zcrypt_card_list ) ;
spin_unlock ( & zcrypt_list_lock ) ;
zc - > online = 1 ;
2016-11-24 06:45:21 +01:00
ZCRYPT_DBF ( DBF_INFO , " card=%02x register online=1 \n " , zc - > card - > id ) ;
2016-08-25 11:16:03 +02:00
return rc ;
}
EXPORT_SYMBOL ( zcrypt_card_register ) ;
/**
* zcrypt_card_unregister ( ) : Unregister a crypto card device .
* @ zc : Pointer to crypto card device
*
* Unregister a crypto card device .
*/
void zcrypt_card_unregister ( struct zcrypt_card * zc )
{
2016-11-24 06:45:21 +01:00
ZCRYPT_DBF ( DBF_INFO , " card=%02x unregister \n " , zc - > card - > id ) ;
2016-08-25 11:16:03 +02:00
spin_lock ( & zcrypt_list_lock ) ;
list_del_init ( & zc - > list ) ;
spin_unlock ( & zcrypt_list_lock ) ;
sysfs_remove_group ( & zc - > card - > ap_dev . device . kobj ,
& zcrypt_card_attr_group ) ;
}
EXPORT_SYMBOL ( zcrypt_card_unregister ) ;