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

📄 sci_osd.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-----------------------------------------------------------------------------+|       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:    Mike Lepore, Zongwei Liu| Component: sci| File:      sci_osd.c| Purpose:   The OS-dependency functions of Smart Card Interface| Changes:|| Date:       Author            Comment:| ----------  ----------------  -----------------------------------------------| 03/22/2001  MAL               Initial check-in.| 03/26/2001  Zongwei Liu       Port to Linux| 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+----------------------------------------------------------------------------*/#include "os/os-sync.h"#include "os/os-interrupt.h"#include "os/os-types.h"#include "os/drv_debug.h"#include <asm/io.h>#include <linux/sched.h>#include "sci_osd.h"#include "sci_atom.h"#include "sci_osi.h"extern SCI_CONTROL_BLOCK sci_cb[SCI_NUMBER_OF_CONTROLLERS];ULONG sci_driver_init;SCI_DRV_MODES sci_drv_modes;static DECLARE_WAIT_QUEUE_HEAD(_SCI_WAIT_Q_0);static DECLARE_WAIT_QUEUE_HEAD(_SCI_WAIT_Q_1);static wait_queue_head_t *sci_wait_q[2];static void sci_osd_irq_handler(UINT uIrq, void *v);/****************************************************************************** Function:    sci_osd_init**** Purpose:     Initialize the Smart Card interface controller(s) and driver**                  and enter deac state.**** Parameters:  detect_polarity: active polarity of the card detect signal**               0: active low  - detect line is low  when card is inserted**               1: active high - detect line is high when card is inserted**              vcc_polarity: active polarity of the Vcc enable signal**               0: active low  - Vcc enable is  low to apply power to card**               1: active high - Vcc enable is high to apply power to card**** Returns:     SCI_ERROR_OK: if successful**              SCI_ERROR_KERNEL_FAIL: if interrupt handler install fails or**                  reader demon task creation fails****************************************************************************/SCI_ERROR sci_osd_init(ULONG detect_polarity, ULONG vcc_polarity){    SCI_ERROR rc = SCI_ERROR_OK;    ULONG sci_id;    ULONG sci_interrupt_masks[] =     {        SCI_INTERRUPT_MASK_0,        SCI_INTERRUPT_MASK_1    };    ULONG sci_interrupt_levels[] =     {        SCI_INTERRUPT_LEVEL_0,        SCI_INTERRUPT_LEVEL_1    };    ULONG sci_base_addresses[] =     {        SCI_BASE_ADDRESS_0,        SCI_BASE_ADDRESS_1    };    PDEBUG("enter\n");    if(((detect_polarity != ACTIVE_LOW) && (detect_polarity != ACTIVE_HIGH)) ||       ((vcc_polarity != ACTIVE_LOW) && (vcc_polarity != ACTIVE_HIGH)))    {        rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE;    }    if((sci_driver_init == 0) && (rc == SCI_ERROR_OK))    {        /* configure the chip internal connection register */        sci_atom_set_chip_connection();        /* initialize globals driver mode */        sci_drv_modes.detect_polarity = detect_polarity;        sci_drv_modes.vcc_polarity    = vcc_polarity;        sci_drv_modes.emv_supported   = sci_atom_emv_check();        /* initialize the wait queue */        sci_wait_q[0] = &(_SCI_WAIT_Q_0);        sci_wait_q[1] = &(_SCI_WAIT_Q_1);        /* initialize global device structure for each smart card controller */        for(sci_id=0; sci_id<SCI_NUMBER_OF_CONTROLLERS; sci_id++)        {            /* initialize control block values */            sci_cb[sci_id].sci_interrupt_mask  = sci_interrupt_masks [sci_id];            sci_cb[sci_id].sci_interrupt_level = sci_interrupt_levels[sci_id];            sci_cb[sci_id].sci_base_address    =                      (ULONG) ioremap(sci_base_addresses[sci_id], SCI_IO_SIZE);            /* assign the register addresses */            sci_atom_assign_reg_address(sci_id);            sci_cb[sci_id].state             = SCI_STATE_INIT;            sci_cb[sci_id].driver_inuse      = 0;            sci_cb[sci_id].atr_status        = SCI_WITHOUT_ATR;            sci_cb[sci_id].waiting           = 0;            sci_cb[sci_id].sci_modes.emv2000 = 0;            sci_cb[sci_id].sci_modes.dma     = 0;            sci_cb[sci_id].sci_modes.man_act = 0;            //sci_cb[sci_id].sci_modes.rw_mode = SCI_SYNC | SCI_DATA_ANY;            sci_cb[sci_id].sci_modes.rw_mode = SCI_SYNC;            sci_cb[sci_id].bytes_expected    = -1;            /* initialize registers */            sci_atom_reg_init(sci_id);            if(os_install_irq(sci_cb[sci_id].sci_interrupt_level,                              IRQ_LEVEL_TRIG | IRQ_POSITIVE_TRIG,                              sci_osd_irq_handler,                              NULL) == 0)            {                sci_driver_init = 1;                rc = sci_osd_deactivate(sci_id);            }            else            {                PDEBUG("unable to request interrupt %d\n",                       (UINT) sci_cb[sci_id].sci_interrupt_level);                rc = SCI_ERROR_KERNEL_FAIL;            }        }    }    if(rc != SCI_ERROR_OK)    {        PDEBUG("error\n");    }    PDEBUG("exit\n");    return(rc);}/****************************************************************************** Function:    scd_osd_uninit**** Purpose:     Uninitialize the Smart Card interface controllers and driver**                  and enter deac state.****************************************************************************/void sci_osd_uninit (void){    ULONG sci_id;    PDEBUG("enter\n");    for (sci_id = 0; sci_id < SCI_NUMBER_OF_CONTROLLERS; sci_id++)    {        sci_osd_deactivate(sci_id);        /* free the IRQ */        os_disable_irq(sci_cb[sci_id].sci_interrupt_level);        os_uninstall_irq(sci_cb[sci_id].sci_interrupt_level);        /* unmap IO */        iounmap((void *) sci_cb[sci_id].sci_base_address);    }    PDEBUG("exit\n");}/****************************************************************************** Function:    sci_osd_irq_handler**** Purpose:     Smart Card Interface interrupt handler****************************************************************************/static void sci_osd_irq_handler (UINT uIrq, void *v){    ULONG state  = 0;    ULONG sci_id;    USHORT isr;    INT bytes_left;    if(uIrq==sci_cb[0].sci_interrupt_level)    {        sci_id = 0;    }    else if(uIrq==sci_cb[1].sci_interrupt_level)    {        sci_id = 1;    }    else    {        sci_id = 2;    }    if(sci_id < 2)    {        state = os_enter_critical_section();        isr = sci_atom_get_interrupt_status(sci_id);        if(isr != 0)        {            /* check for card being inserted or removed */            if((isr & CDI) == CDI)            {                if(sci_cb[sci_id].waiting == 1)                {                    sci_cb[sci_id].waiting = 0;                    wake_up_interruptible(sci_wait_q[sci_id]);                    //os_release_mutex(sci_cb[sci_id].mutex);                    sci_cb[sci_id].rx_complete = 1;                }                sci_cb[sci_id].atr_status = SCI_WITHOUT_ATR;                sci_cb[sci_id].state = SCI_STATE_DEAC;                sci_atom_clear_interrupt_status(sci_id, isr);            }            else            {                switch(sci_cb[sci_id].state)                {                case SCI_STATE_RX:                    if((isr & TSI) == TSI)                    {                        sci_cb[sci_id].error = SCI_ERROR_TS_CHARACTER_INVALID;                        sci_cb[sci_id].rx_complete = 1;                        sci_atom_clear_interrupt_status(sci_id, TSI);                    }                    if((isr & RFI) == RFI)                    {                        if(sci_cb[sci_id].first_rx == 1)                        {                            /* we have received some data */                            sci_cb[sci_id].error = SCI_ERROR_AWT_TIMEOUT;                        }                        else                        {                            /* no data received */                            sci_cb[sci_id].error = SCI_ERROR_NO_ATR;                        }                        sci_cb[sci_id].rx_complete = 1;                        sci_atom_clear_interrupt_status(sci_id, RFI);                    }                    if((isr & FRXI) == FRXI)                    {                        sci_cb[sci_id].first_rx = 1;                        sci_atom_clear_interrupt_status(sci_id, FRXI);                    }                    if((isr & BOI) == BOI)                    {                        sci_cb[sci_id].error = SCI_ERROR_RX_OVERFLOW_FAIL;                        sci_cb[sci_id].rx_complete = 1;                        sci_atom_clear_interrupt_status(sci_id, BOI);                    }                    if((isr & PARI) == PARI)                    {                        sci_cb[sci_id].error = SCI_ERROR_PARITY_FAIL;                        sci_cb[sci_id].rx_complete = 1;                        sci_atom_clear_interrupt_status(sci_id, PARI);                    }                    if(((isr & RFTHI) == RFTHI) || ((isr & REI) == REI))                    {                        /* in either case, read any pending data            */

⌨️ 快捷键说明

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