⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z90main.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  linux/drivers/s390/misc/z90main.c * *  z90crypt 1.3.1 * *  Copyright (C)  2001, 2004 IBM Corporation *  Author(s): Robert Burroughs (burrough@us.ibm.com) *	       Eric Rossman (edrossma@us.ibm.com) * *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.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. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <asm/uaccess.h>       // copy_(from|to)_user#include <linux/compat.h>#include <linux/compiler.h>#include <linux/delay.h>       // mdelay#include <linux/init.h>#include <linux/interrupt.h>   // for tasklets#include <linux/ioctl32.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/proc_fs.h>#include <linux/syscalls.h>#include <linux/version.h>#include "z90crypt.h"#include "z90common.h"#ifndef Z90CRYPT_USE_HOTPLUG#include <linux/miscdevice.h>#endif#define VERSION_CODE(vers, rel, seq) (((vers)<<16) | ((rel)<<8) | (seq))#if LINUX_VERSION_CODE < VERSION_CODE(2,4,0) /* version < 2.4 */#  error "This kernel is too old: not supported"#endif#if LINUX_VERSION_CODE > VERSION_CODE(2,7,0) /* version > 2.6 */#  error "This kernel is too recent: not supported by this file"#endif#define VERSION_Z90MAIN_C "$Revision: 1.31 $"static char z90cmain_version[] __initdata =	"z90main.o (" VERSION_Z90MAIN_C "/"                      VERSION_Z90COMMON_H "/" VERSION_Z90CRYPT_H ")";extern char z90chardware_version[];/** * Defaults that may be modified. */#ifndef Z90CRYPT_USE_HOTPLUG/** * You can specify a different minor at compile time. */#ifndef Z90CRYPT_MINOR#define Z90CRYPT_MINOR	MISC_DYNAMIC_MINOR#endif#else/** * You can specify a different major at compile time. */#ifndef Z90CRYPT_MAJOR#define Z90CRYPT_MAJOR	0#endif#endif/** * You can specify a different domain at compile time or on the insmod * command line. */#ifndef DOMAIN_INDEX#define DOMAIN_INDEX	-1#endif/** * This is the name under which the device is registered in /proc/modules. */#define REG_NAME	"z90crypt"/** * Cleanup should run every CLEANUPTIME seconds and should clean up requests * older than CLEANUPTIME seconds in the past. */#ifndef CLEANUPTIME#define CLEANUPTIME 15#endif/** * Config should run every CONFIGTIME seconds */#ifndef CONFIGTIME#define CONFIGTIME 30#endif/** * The first execution of the config task should take place * immediately after initialization */#ifndef INITIAL_CONFIGTIME#define INITIAL_CONFIGTIME 1#endif/** * Reader should run every READERTIME milliseconds */#ifndef READERTIME#define READERTIME 2#endif/** * turn long device array index into device pointer */#define LONG2DEVPTR(ndx) (z90crypt.device_p[(ndx)])/** * turn short device array index into long device array index */#define SHRT2LONG(ndx) (z90crypt.overall_device_x.device_index[(ndx)])/** * turn short device array index into device pointer */#define SHRT2DEVPTR(ndx) LONG2DEVPTR(SHRT2LONG(ndx))/** * Status for a work-element */#define STAT_DEFAULT	0x00 // request has not been processed#define STAT_ROUTED	0x80 // bit 7: requests get routed to specific device			     //	       else, device is determined each write#define STAT_FAILED	0x40 // bit 6: this bit is set if the request failed			     //	       before being sent to the hardware.#define STAT_WRITTEN	0x30 // bits 5-4: work to be done, not sent to device//			0x20 // UNUSED state#define STAT_READPEND	0x10 // bits 5-4: work done, we're returning data now#define STAT_NOWORK	0x00 // bits off: no work on any queue#define STAT_RDWRMASK	0x30 // mask for bits 5-4/** * Macros to check the status RDWRMASK */#define CHK_RDWRMASK(statbyte) ((statbyte) & STAT_RDWRMASK)#define SET_RDWRMASK(statbyte, newval) \	{(statbyte) &= ~STAT_RDWRMASK; (statbyte) |= newval;}/** * Audit Trail.	 Progress of a Work element * audit[0]: Unless noted otherwise, these bits are all set by the process */#define FP_COPYFROM	0x80 // Caller's buffer has been copied to work element#define FP_BUFFREQ	0x40 // Low Level buffer requested#define FP_BUFFGOT	0x20 // Low Level buffer obtained#define FP_SENT		0x10 // Work element sent to a crypto device			     // (may be set by process or by reader task)#define FP_PENDING	0x08 // Work element placed on pending queue			     // (may be set by process or by reader task)#define FP_REQUEST	0x04 // Work element placed on request queue#define FP_ASLEEP	0x02 // Work element about to sleep#define FP_AWAKE	0x01 // Work element has been awakened/** * audit[1]: These bits are set by the reader task and/or the cleanup task */#define FP_NOTPENDING	  0x80 // Work element removed from pending queue#define FP_AWAKENING	  0x40 // Caller about to be awakened#define FP_TIMEDOUT	  0x20 // Caller timed out#define FP_RESPSIZESET	  0x10 // Response size copied to work element#define FP_RESPADDRCOPIED 0x08 // Response address copied to work element#define FP_RESPBUFFCOPIED 0x04 // Response buffer copied to work element#define FP_REMREQUEST	  0x02 // Work element removed from request queue#define FP_SIGNALED	  0x01 // Work element was awakened by a signal/** * audit[2]: unused *//** * state of the file handle in private_data.status */#define STAT_OPEN 0#define STAT_CLOSED 1/** * PID() expands to the process ID of the current process */#define PID() (current->pid)/** * Selected Constants.	The number of APs and the number of devices */#ifndef Z90CRYPT_NUM_APS#define Z90CRYPT_NUM_APS 64#endif#ifndef Z90CRYPT_NUM_DEVS#define Z90CRYPT_NUM_DEVS Z90CRYPT_NUM_APS#endif#ifndef Z90CRYPT_NUM_TYPES#define Z90CRYPT_NUM_TYPES 3#endif/** * Buffer size for receiving responses. The maximum Response Size * is actually the maximum request size, since in an error condition * the request itself may be returned unchanged. */#ifndef MAX_RESPONSE_SIZE#define MAX_RESPONSE_SIZE 0x0000077C#endif/** * A count and status-byte mask */struct status {	int	      st_count;		    // # of enabled devices	int	      disabled_count;	    // # of disabled devices	int	      user_disabled_count;  // # of devices disabled via proc fs	unsigned char st_mask[Z90CRYPT_NUM_APS]; // current status mask};/** * The array of device indexes is a mechanism for fast indexing into * a long (and sparse) array.  For instance, if APs 3, 9 and 47 are * installed, z90CDeviceIndex[0] is 3, z90CDeviceIndex[1] is 9, and * z90CDeviceIndex[2] is 47. */struct device_x {	int device_index[Z90CRYPT_NUM_DEVS];};/** * All devices are arranged in a single array: 64 APs */struct device {	int		 dev_type;	    // PCICA, PCICC, or PCIXCC	enum devstat	 dev_stat;	    // current device status	int		 dev_self_x;	    // Index in array	int		 disabled;	    // Set when device is in error	int		 user_disabled;	    // Set when device is disabled by user	int		 dev_q_depth;	    // q depth	unsigned char *	 dev_resp_p;	    // Response buffer address	int		 dev_resp_l;	    // Response Buffer length	int		 dev_caller_count;  // Number of callers	int		 dev_total_req_cnt; // # requests for device since load	struct list_head dev_caller_list;   // List of callers};/** * There's a struct status and a struct device_x for each device type. */struct hdware_block {	struct status	hdware_mask;	struct status	type_mask[Z90CRYPT_NUM_TYPES];	struct device_x type_x_addr[Z90CRYPT_NUM_TYPES];	unsigned char	device_type_array[Z90CRYPT_NUM_APS];};/** * z90crypt is the topmost data structure in the hierarchy. */struct z90crypt {	int		     max_count;		// Nr of possible crypto devices	struct status	     mask;	int		     q_depth_array[Z90CRYPT_NUM_DEVS];	int		     dev_type_array[Z90CRYPT_NUM_DEVS];	struct device_x	     overall_device_x;	// array device indexes	struct device *	     device_p[Z90CRYPT_NUM_DEVS];	int		     terminating;	int		     domain_established;// TRUE:  domain has been found	int		     cdx;		// Crypto Domain Index	int		     len;		// Length of this data structure	struct hdware_block *hdware_info;};/** * An array of these structures is pointed to from dev_caller * The length of the array depends on the device type. For APs, * there are 8. * * The caller buffer is allocated to the user at OPEN. At WRITE, * it contains the request; at READ, the response. The function * send_to_crypto_device converts the request to device-dependent * form and use the caller's OPEN-allocated buffer for the response. */struct caller {	int		 caller_buf_l;		 // length of original request	unsigned char *	 caller_buf_p;		 // Original request on WRITE	int		 caller_dev_dep_req_l;	 // len device dependent request	unsigned char *	 caller_dev_dep_req_p;	 // Device dependent form	unsigned char	 caller_id[8];		 // caller-supplied message id	struct list_head caller_liste;	unsigned char	 caller_dev_dep_req[MAX_RESPONSE_SIZE];};/** * Function prototypes from z90hardware.c */enum hdstat query_online(int, int, int, int *, int *);enum devstat reset_device(int, int, int);enum devstat send_to_AP(int, int, int, unsigned char *);enum devstat receive_from_AP(int, int, int, unsigned char *, unsigned char *);int convert_request(unsigned char *, int, short, int, int, int *,		    unsigned char *);int convert_response(unsigned char *, unsigned char *, int *, unsigned char *);/** * Low level function prototypes */static int create_z90crypt(int *);static int refresh_z90crypt(int *);static int find_crypto_devices(struct status *);static int create_crypto_device(int);static int destroy_crypto_device(int);static void destroy_z90crypt(void);static int refresh_index_array(struct status *, struct device_x *);static int probe_device_type(struct device *);/** * proc fs definitions */static struct proc_dir_entry *z90crypt_entry;/** * data structures *//** * work_element.opener points back to this structure */struct priv_data {	pid_t	opener_pid;	unsigned char	status;		// 0: open  1: closed};/** * A work element is allocated for each request */struct work_element {	struct priv_data *priv_data;	pid_t		  pid;	int		  devindex;	  // index of device processing this w_e					  // (If request did not specify device,					  // -1 until placed onto a queue)	int		  devtype;	struct list_head  liste;	  // used for requestq and pendingq	char		  buffer[128];	  // local copy of user request	int		  buff_size;	  // size of the buffer for the request	char		  resp_buff[RESPBUFFSIZE];	int		  resp_buff_size;	char __user *	  resp_addr;	  // address of response in user space	unsigned int	  funccode;	  // function code of request	wait_queue_head_t waitq;	unsigned long	  requestsent;	  // time at which the request was sent	atomic_t	  alarmrung;	  // wake-up signal	unsigned char	  caller_id[8];	  // pid + counter, for this w_e	unsigned char	  status[1];	  // bits to mark status of the request	unsigned char	  audit[3];	  // record of work element's progress	unsigned char *	  requestptr;	  // address of request buffer	int		  retcode;	  // return code of request};/** * High level function prototypes */static int z90crypt_open(struct inode *, struct file *);static int z90crypt_release(struct inode *, struct file *);static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *);static ssize_t z90crypt_write(struct file *, const char __user *,							size_t, loff_t *);static int z90crypt_ioctl(struct inode *, struct file *,			  unsigned int, unsigned long);static void z90crypt_reader_task(unsigned long);static void z90crypt_schedule_reader_task(unsigned long);static void z90crypt_config_task(unsigned long);static void z90crypt_cleanup_task(unsigned long);static int z90crypt_status(char *, char **, off_t, int, int *, void *);static int z90crypt_status_write(struct file *, const char __user *,				 unsigned long, void *);/** * Hotplug support */#ifdef Z90CRYPT_USE_HOTPLUG#define Z90CRYPT_HOTPLUG_ADD	 1#define Z90CRYPT_HOTPLUG_REMOVE	 2static void z90crypt_hotplug_event(int, int, int);#endif/** * Storage allocated at initialization and used throughout the life of * this insmod */#ifdef Z90CRYPT_USE_HOTPLUGstatic int z90crypt_major = Z90CRYPT_MAJOR;#endifstatic int domain = DOMAIN_INDEX;static struct z90crypt z90crypt;static int quiesce_z90crypt;static spinlock_t queuespinlock;static struct list_head request_list;static int requestq_count;static struct list_head pending_list;static int pendingq_count;static struct tasklet_struct reader_tasklet;static struct timer_list reader_timer;static struct timer_list config_timer;static struct timer_list cleanup_timer;static atomic_t total_open;static atomic_t z90crypt_step;static struct file_operations z90crypt_fops = {	.owner	 = THIS_MODULE,	.read	 = z90crypt_read,	.write	 = z90crypt_write,	.ioctl	 = z90crypt_ioctl,	.open	 = z90crypt_open,	.release = z90crypt_release};#ifndef Z90CRYPT_USE_HOTPLUGstatic struct miscdevice z90crypt_misc_device = {	.minor	    = Z90CRYPT_MINOR,	.name	    = DEV_NAME,	.fops	    = &z90crypt_fops,	.devfs_name = DEV_NAME};#endif/** * Documentation values. */MODULE_AUTHOR("zLinux Crypto Team: Robert H. Burroughs, Eric D. Rossman"	      "and Jochen Roehrig");MODULE_DESCRIPTION("zLinux Cryptographic Coprocessor device driver, "		   "Copyright 2001, 2004 IBM Corporation");MODULE_LICENSE("GPL");module_param(domain, int, 0);MODULE_PARM_DESC(domain, "domain index for device");#ifdef CONFIG_COMPAT/** * ioctl32 conversion routines */struct ica_rsa_modexpo_32 { // For 32-bit callers	compat_uptr_t	inputdata;	unsigned int	inputdatalength;	compat_uptr_t	outputdata;	unsigned int	outputdatalength;	compat_uptr_t	b_key;	compat_uptr_t	n_modulus;};static inttrans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg,		struct file *file){	struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg);	struct ica_rsa_modexpo_32  mex32k;	struct ica_rsa_modexpo __user *mex64;	int ret = 0;	unsigned int i;	if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32)))		return -EFAULT;	mex64 = compat_alloc_user_space(sizeof(struct ica_rsa_modexpo));	if (!access_ok(VERIFY_WRITE, mex64, sizeof(struct ica_rsa_modexpo)))		return -EFAULT;	if (copy_from_user(&mex32k, mex32u, sizeof(struct ica_rsa_modexpo_32)))		return -EFAULT;	if (__put_user(compat_ptr(mex32k.inputdata), &mex64->inputdata)   ||	    __put_user(mex32k.inputdatalength, &mex64->inputdatalength)   ||	    __put_user(compat_ptr(mex32k.outputdata), &mex64->outputdata) ||	    __put_user(mex32k.outputdatalength, &mex64->outputdatalength) ||	    __put_user(compat_ptr(mex32k.b_key), &mex64->b_key)           ||	    __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus))		return -EFAULT;	ret = sys_ioctl(fd, cmd, (unsigned long)mex64);	if (!ret)		if (__get_user(i, &mex64->outputdatalength) ||		    __put_user(i, &mex32u->outputdatalength))			ret = -EFAULT;	return ret;}struct ica_rsa_modexpo_crt_32 { // For 32-bit callers	compat_uptr_t	inputdata;	unsigned int	inputdatalength;	compat_uptr_t	outputdata;	unsigned int	outputdatalength;	compat_uptr_t	bp_key;	compat_uptr_t	bq_key;	compat_uptr_t	np_prime;	compat_uptr_t	nq_prime;	compat_uptr_t	u_mult_inv;};static int

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -