📄 sci_inf.c
字号:
/*---------------------------------------------------------------------------+| This source code has been made available to you by IBM on an AS-IS| basis. Anyone receiving this source is licensed under IBM| copyrights to use it in any way he or she deems fit, including| copying it, modifying it, compiling it, and redistributing it either| with or without modifications. No license under IBM patents or| patent applications is to be implied by the copyright license.|| Any user of this software should understand that IBM cannot provide| technical support for this software and will not be responsible for| any consequences resulting from the use of this software.|| Any person who transfers this source code or any derivative work| must include the IBM copyright notice, this paragraph, and the| preceding two paragraphs in the transferred software.|| COPYRIGHT I B M CORPORATION 2001| LICENSED MATERIAL - PROGRAM PROPERTY OF I B M+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Author: Zongwei Liu| Component: sci| File: sci_inf.c| Purpose: POSIX interface of Smart Card Interface device driver| Changes:|| Date: Author Comment:| ---------- ---------------- -----------------------------------------------| 03/26/2001 Zongwei Liu Initial check-in.| 09/26/2001 Zongwei Liu Port to pallas| 10/10/2001 Zongwei Liu Port to OS-Adaption layer| 12/13/2001 MAL, Zongwei Liu Added sci_osd_init() parameters to set detect | and Vcc enable active polarities | (which are board dependent).| 12/13/2001 MAL, Zongwei Liu Added EMV2000 support and made several changes | to improve PIO efficiency.| 01/11/2002 MAL, zongwei Liu Add timeout to read/write function+----------------------------------------------------------------------------*//* The necessary header files */#include <linux/config.h>#include <linux/version.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/stddef.h>#include <linux/devfs_fs_kernel.h>#include <asm/system.h>#include <linux/ioctl.h>#include <asm/uaccess.h>#include "os/drv_debug.h"#include "os/os-types.h"/* local includes */#include "sci/sci_inf.h"#include "sci_osi.h"#include "sci_osd.h"MODULE_AUTHOR("Mike Lepore, Zongwei Liu");MODULE_DESCRIPTION("Driver for Smart Card Interface of IBM Redwood5");EXPORT_NO_SYMBOLS;#ifdef MODULEMODULE_PARM(detect_p, "i");MODULE_PARM_DESC(detect_p, "Select the detect polarity of smart card: 0 - ACTIVE_LOW, 1 - ACTIVE_HIGH");MODULE_PARM(vcc_p, "i");MODULE_PARM_DESC(vcc_p, "Select the VCC polarity of smart card: 0 - ACTIVE_LOW, 1 - ACTIVE_HIGH");#endifstatic INT detect_p = ACTIVE_LOW;static INT vcc_p = ACTIVE_LOW;/* allocate device control blocks */SCI_CONTROL_BLOCK sci_cb[SCI_NUMBER_OF_CONTROLLERS];/* Public API function prototypes */static int sci_inf_open(struct inode *inode, struct file *filp);static int sci_inf_release(struct inode *inode, struct file *filp);static ssize_t sci_inf_read(struct file *file, char *buffer, size_t length, loff_t * offset);static ssize_t sci_inf_write(struct file *file, const char *buffer, size_t length, loff_t * offset);static int sci_inf_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param);static struct file_operations Fops = { open: sci_inf_open, release: sci_inf_release, read: sci_inf_read, write: sci_inf_write, ioctl: sci_inf_ioctl};void sci_dump_regs(ULONG sci_id);/****************************************************************************** Name: sci_inf_open**** Purpose: POSIX device open**** Parameters: inode:** filp:**** Returns =0: success** <0: if any error occur****************************************************************************/static int sci_inf_open(struct inode *inode, struct file *filp){ ULONG sci_id; int rc; if ((sci_id = MINOR(inode->i_rdev)) <= SCI_NUMBER_OF_CONTROLLERS) { if (sci_cb[sci_id].driver_inuse == 0) { if (sci_osi_is_card_present(sci_id) == 1) { sci_cb[sci_id].driver_inuse ++; rc = 0; MOD_INC_USE_COUNT; } else { PDEBUG("num %d card not present\n", (UINT) sci_id); rc = -EINVAL; } } else { PDEBUG("num %d card is busy\n", (UINT) sci_id); rc = -EBUSY; } } else { PDEBUG("error card num: %d\n", (UINT) sci_id); rc = -ENODEV; } return (rc);}/****************************************************************************** Name: sci_inf_release**** Purpose: POSIX device close**** Parameters: inode:** filp:**** Returns =0: success** <0: if any error occur****************************************************************************/static int sci_inf_release(struct inode *inode, struct file *filp){ ULONG sci_id; int rc; if ((sci_id = MINOR(inode->i_rdev)) <= SCI_NUMBER_OF_CONTROLLERS) { if (sci_cb[sci_id].driver_inuse != 0) { sci_osd_deactivate(sci_id); sci_cb[sci_id].driver_inuse = 0; rc = 0; } else { PDEBUG("driver of num%d card is not opend\n", (UINT) sci_id); rc = -EINVAL; } } else { PDEBUG("error card num: %d\n", (UINT) sci_id); rc = -ENODEV; } if (rc == 0) { MOD_DEC_USE_COUNT; } return rc;}/****************************************************************************** Name: sci_inf_read**** Purpose: POSIX smart card read **** Parameters: file: input pointer to the file handle** buffer: output pointer to the output data buffer** length: the expect characters number** offset: offset of the file**** Returns >=0: the actually number of read characters** <0: if any error occur****************************************************************************/static ssize_t sci_inf_read(struct file *file, char *buffer, size_t length, loff_t * offset){ ULONG sci_id; UCHAR *p_buffer; ULONG *p_bytes_read; ULONG count; ssize_t rc; SCI_ERROR sci_rc; /* sci_id is the Minor Num of this device */ sci_id = MINOR(file->f_dentry->d_inode->i_rdev); p_bytes_read = &count; if (length <= SCI_BUFFER_SIZE) { p_buffer = sci_cb[sci_id].read_buf; sci_rc = sci_osd_read(sci_id, p_buffer, (ULONG) length, p_bytes_read, sci_cb[sci_id].sci_modes.rw_mode); if ((count = *p_bytes_read) > 0) { copy_to_user((void *)buffer, (const void *)p_buffer, count); rc = (ssize_t) count; } else { PDEBUG("card %d error=%d\n", (UINT) sci_id, sci_rc); rc = sci_rc; } } else { PDEBUG("error buffer size\n"); rc = -EINVAL; } return (rc);}/****************************************************************************** Name: sci_inf_write**** Purpose: POSIX smart card write**** Parameters: file: input pointer to the file handle** buffer: input pointer to the input data buffer** length: the characters number of input buffer** offset: offset of the file**** Returns >=0: the actually number of writen characters** <0: if any error occur****************************************************************************/static ssize_t sci_inf_write(struct file *file, const char *buffer, size_t length, loff_t * offset){ ssize_t rc; ULONG sci_id; UCHAR *p_buffer; SCI_ERROR sci_rc; /* sci_id is the Minor Num of this device */ sci_id = MINOR(file->f_dentry->d_inode->i_rdev); if (length <= SCI_BUFFER_SIZE) { p_buffer = sci_cb[sci_id].write_buf; copy_from_user((void *)p_buffer, (const void *)buffer, length); sci_rc = sci_osd_write(sci_id, p_buffer, (ULONG) length, sci_cb[sci_id].sci_modes.rw_mode); if (sci_rc == SCI_ERROR_OK) { rc = (ssize_t) length; } else { PDEBUG("card%d error=%d\n", (UINT) sci_id, sci_rc); rc = sci_rc; } } else { PDEBUG("error buffer size\n"); rc = -EINVAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -