📄 sci_osd.c
字号:
/* reset pointers to start of buffer if equal */ /* this will prevent buffer overruns for extensive */ /* waiting time extensions in T=0 */ if(sci_cb[sci_id].p_read == sci_cb[sci_id].p_write) { sci_cb[sci_id].p_read = sci_cb[sci_id].buffer; sci_cb[sci_id].p_write = sci_cb[sci_id].buffer; } /* read any pending data into private buffer */ sci_atom_read_fifo(sci_id, &sci_cb[sci_id].p_write); } if((isr & RFTHI) == RFTHI) { if((isr & REI) != REI) { /* REI will wakeup read, if it is present */ if(sci_cb[sci_id].waiting == 1) { if((sci_cb[sci_id].read_flags & SCI_DATA_ANY) == SCI_DATA_ANY) { sci_cb[sci_id].waiting = 0; wake_up_interruptible(sci_wait_q[sci_id]); } else if(sci_cb[sci_id].bytes_expected == 0) { sci_cb[sci_id].bytes_expected = -1; sci_cb[sci_id].waiting = 0; wake_up_interruptible(sci_wait_q[sci_id]); } } } sci_atom_clear_interrupt_status(sci_id, RFTHI); } if((isr & REI) == REI) { if(sci_cb[sci_id].rx_complete == 0) { if(sci_cb[sci_id].sci_parameters.T == 0) { sci_cb[sci_id].error = SCI_ERROR_WWT_TIMEOUT; } else { /* T=1 */ if((isr & RXLEN) == RXLEN) { if(sci_cb[sci_id].first_rx == 1) { /* we have received some data */ sci_cb[sci_id].error = SCI_ERROR_CWT_TIMEOUT; } else { /* no data received since Tx */ sci_cb[sci_id].error = SCI_ERROR_BWT_TIMEOUT; } } else if((isr & CHI) == CHI) { /* checks error */ if(sci_cb[sci_id].sci_parameters.check == 1) { sci_cb[sci_id].error = SCI_ERROR_LRC_FAIL; } else { sci_cb[sci_id].error = SCI_ERROR_CRC_FAIL; } } } sci_cb[sci_id].rx_complete = 1; } sci_atom_clear_interrupt_status(sci_id, REI|RXLEN); } if(sci_cb[sci_id].rx_complete == 1) { if(sci_cb[sci_id].waiting == 1) { sci_cb[sci_id].waiting = 0; wake_up_interruptible(sci_wait_q[sci_id]); } } break; case SCI_STATE_TX: if((isr & TFHI) == TFHI) { /* ensure fifo stat indicates fifo has dropped below half full */ if(sci_atom_check_tx_fifo_half_full(sci_id) == 0) { bytes_left = (sci_cb[sci_id].p_write - sci_cb[sci_id].p_read); /* the transmitter is less than 1/2 full- it can accept 16 bytes */ if(bytes_left > 16) { /* more than 16 bytes left to transmit */ sci_atom_write_fifo(sci_id, 16, &sci_cb[sci_id].p_read); } else { /* transmit rest of the bytes */ sci_atom_write_fifo(sci_id, bytes_left, &sci_cb[sci_id].p_read); sci_atom_disable_tx_threshold_interrupts(sci_id); } } sci_atom_clear_interrupt_status(sci_id, TFHI); } if((isr & PARI) == PARI) { sci_cb[sci_id].error = SCI_ERROR_PARITY_FAIL; sci_atom_clear_interrupt_status(sci_id, PARI); } if((isr & BOI) == BOI) { sci_cb[sci_id].error = SCI_ERROR_TX_OVERFLOW_FAIL; sci_atom_clear_interrupt_status(sci_id, BOI); } if((isr & TUI) == TUI) {#ifdef ERROR_ON_TUI sci_cb[sci_id].error = SCI_ERROR_TX_UNDERRUN_FAIL;#endif sci_atom_clear_interrupt_status(sci_id, TUI); } if((sci_cb[sci_id].error != SCI_ERROR_OK) || ((isr & LTXI) == LTXI)) { if(sci_cb[sci_id].waiting == 1) { sci_cb[sci_id].waiting = 0; wake_up_interruptible(sci_wait_q[sci_id]); } /* start rx state */ sci_osi_rx_start(sci_id); } break; default: break; } } } sci_atom_clear_UICSR(sci_id); os_leave_critical_section(state); }}/******************************************************************************* Function: sci_osd_write**** Purpose: Write data to the Smart Card (enter tx state).**** Parameters: sci_id: zero-based number to identify smart card controller** p_buffer: input pointer to write buffer** num_bytes: number of bytes to write from p_buffer** mode_flags: flags to indicate behavior of write**** Returns: SCI_ERROR_OK: if successful** SCI_ERROR_DRIVER_NOT_INITIALIZED: if no successful call to** sci_init() has been made** SCI_ERROR_PARAMETER_OUT_OF_RANGE: if sci_id is invalid or** p_buffer is zero or** num_bytes is zero** SCI_ERROR_CARD_NOT_ACTIVATED: if card is not activated** SCI_ERROR_TX_PENDING: if a transmission is already pending*****************************************************************************/SCI_ERROR sci_osd_write (ULONG sci_id, UCHAR *p_buffer, ULONG num_bytes, ULONG mode_flags){ SCI_ERROR rc = SCI_ERROR_OK; ULONG k_state; PDEBUG("card[%d] enter\n", (UINT) sci_id); if (sci_driver_init != 1) { rc = SCI_ERROR_DRIVER_NOT_INITIALIZED; } else if (sci_osi_is_card_activated(sci_id) != 1) { rc = SCI_ERROR_CARD_NOT_ACTIVATED; } else if (sci_cb[sci_id].atr_status != SCI_ATR_READY) { rc = SCI_ERROR_NO_ATR; } else if(sci_cb[sci_id].state == SCI_STATE_TX) { rc = SCI_ERROR_TX_PENDING; } else if((num_bytes == 0) || (p_buffer == 0) || (sci_id >= SCI_NUMBER_OF_CONTROLLERS)) { rc = SCI_ERROR_PARAMETER_OUT_OF_RANGE; } else { sci_osi_tx_start(sci_id, num_bytes); if(num_bytes > 32) { /* write up to 32 bytes directly to the FIFO */ sci_atom_write_fifo(sci_id, 32, &p_buffer); num_bytes -= 32; } else { sci_atom_write_fifo(sci_id, num_bytes, &p_buffer); num_bytes = 0; } /* enable Tx interrupts */ sci_atom_enable_tx_interrupts(sci_id); k_state = os_enter_critical_section(); if((mode_flags & SCI_SYNC) == SCI_SYNC) { if(num_bytes > 0) { /* copy buffer pointers and transmit from user buffer */ sci_cb[sci_id].p_read = p_buffer; sci_cb[sci_id].p_write = (p_buffer + num_bytes); /* enable Tx threshold interrupts */ sci_atom_enable_tx_threshold_interrupts(sci_id); } /* block here- syncronous mode */ if(sci_cb[sci_id].state == SCI_STATE_TX) { sci_cb[sci_id].waiting = 1; if(interruptible_sleep_on_timeout(sci_wait_q[sci_id], SCI_TIMEOUT_MS / 10) == 0) { if(sci_cb[sci_id].waiting == 0) { /* suspend timed-out, but resume was called- OS problem */ sci_cb[sci_id].error = SCI_ERROR_KERNEL_FAIL; } else { /* suspend timed-out, resume was not called- SCI problem */ sci_cb[sci_id].error = SCI_ERROR_TRANSACTION_ABORTED; } } rc = sci_cb[sci_id].error; sci_cb[sci_id].error = SCI_ERROR_OK; } } else if(num_bytes > 0) { /* copy data into private buffer */ memcpy((void *)sci_cb[sci_id].buffer, (const void *)p_buffer, num_bytes); sci_cb[sci_id].p_read = sci_cb[sci_id].buffer; sci_cb[sci_id].p_write = (sci_cb[sci_id].buffer + num_bytes); /* enable Tx threshold interrupts */ sci_atom_enable_tx_threshold_interrupts(sci_id); } os_leave_critical_section(k_state); } if(rc != SCI_ERROR_OK) { PDEBUG("card[%d] error=%d\n", (UINT) sci_id, rc); } PDEBUG("card[%d] exit\n", (UINT) sci_id); return(rc);}/******************************************************************************* Function: sci_osd_read**** Purpose: Read data from the Smart Card.**** Parameters: sci_id: zero-based number to identify smart card controller** p_buffer: input pointer to read buffer** num_bytes: number of bytes to read into p_buffer** p_bytes_read: number of bytes actually read into p_buffer** mode_flags: flags to indicate behavior of read**** Returns: SCI_ERROR_OK: if successful** SCI_ERROR_DRIVER_NOT_INITIALIZED: if no successful call to** sci_init() has been made** SCI_ERROR_PARAMETER_OUT_OF_RANGE: if sci_id is invalid or** p_buffer is zero or** num_bytes is zero or** p_bytes_read is zero** SCI_ERROR_CARD_NOT_ACTIVATED: if card is not activated*****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -