st16c554

/* 

  1.  * st16c554.c 
  2.  * 
  3.  * TWO ST16C554 driver for AMCC PPC405EP 
  4.  * 
  5.  * Author: Li Zhi You/Zhu jiang <godiscrazy@163.com> 
  6.  * Date  : $Date: 2007/11/27 11:07:04 $ 
  7.  * 
  8.  * $Revision: 1.1V $ 
  9.  * 
  10. ST16C554APN 
  11. 7.3728mhz 
  12. 扩展芯片:2*ST16C554 
  13. 可为系统增加8个串口,直接与PPC405EP总线连接,8位数据宽度 
  14. 地址空间:占用系统PC3 
  15. 地址从前到后分别对应每个UART0-7个寄存器 
  16. UART0A:0xf0200020---0xf020027 
  17.                         A2A1A0(ST16C554) 
  18.         0xf0200020     0 0 0 
  19.         0xf0200021     0 0 1 
  20.         0xf0200022     0 1 0 
  21.         0xf0200023     0 1 1 
  22.         0xf0200024     1 0 0 
  23.         0xf0200025     1 0 1 
  24.         0xf0200026     1 1 0 
  25.         0xf0200027     1 1 1 
  26. UART0B:0xf0200028---0xf020002f 
  27. UART0C:0xf0200030---0xf0200037 
  28. UART0D:0xf0200038---0xf020003f 
  29.  
  30. UART0E:0xf0200040---0xf020047 
  31.                         A2A1A0(ST16C554) 
  32.         0xf0200040     0 0 0 
  33.         0xf0200041     0 0 1 
  34.         0xf0200042     0 1 0 
  35.         0xf0200043     0 1 1 
  36.         0xf0200044     1 0 0 
  37.         0xf0200045     1 0 1 
  38.         0xf0200046     1 1 0 
  39.         0xf0200047     1 1 1 
  40. UART0F:0xf0200048---0xf020004f 
  41. UART0G:0xf0200050---0xf0200057 
  42. UART0H:0xf0200058---0xf020005f 
  43.  
  44. 控制寄存器 
  45. Line-control register(LCR) 
  46. 0x03 
  47. FIFO-control register(FCR) 
  48. 0x02 
  49. Modem-control register(MCR) 
  50. 0x04 
  51. Divisor-latch LSB(DLL) 
  52. LCR(bit7=1)0x00 
  53. Divisor-latch MSB(DLM) 
  54. LCR(bit7=1)0x01 
  55. Interrupt enable register(IER) 
  56. 0x01 
  57.  
  58. 状态寄存器 
  59. Line-status register(LSR) 
  60. 0x05 
  61. Modem-status register(MSR) 
  62. 0x06 
  63.  
  64. 数据寄存器 
  65. Receiver-buffer register(RBR) 
  66. 0x00 
  67. Transmitter-holding register(THR) 
  68. 0x00 
  69.  */  
  70.   
  71. #include <linux/config.h>  
  72. #include <linux/module.h>  
  73. #include <linux/kernel.h>  
  74. #include <linux/init.h>  
  75.   
  76. #include <linux/miscdevice.h>  
  77. #include <linux/sched.h>  
  78. #include <linux/delay.h>  
  79. #include <linux/poll.h>  
  80. #include <linux/spinlock.h>  
  81. #include <linux/irq.h>  
  82. #include <asm/processor.h>  
  83. #include <platforms/ibm405ep.h>  
  84. #include <platforms/ibm405lp.h>  
  85. #include <linux/devfs_fs_kernel.h>  
  86.   
  87. #include <asm/io.h>  
  88.   
  89.   
  90. #define ST0_A_READ  0  
  91. #define ST0_B_READ  1  
  92. #define ST0_C_READ  2  
  93. #define ST0_D_READ  3  
  94. #define ST1_A_READ  4  
  95. #define ST1_B_READ  5  
  96. #define ST1_C_READ  6  
  97. #define ST1_D_READ  7  
  98. #define ST0_A_WRITE 8  
  99. #define ST0_B_WRITE 9  
  100. #define ST0_C_WRITE 10  
  101. #define ST0_D_WRITE 11  
  102. #define ST1_A_WRITE 12  
  103. #define ST1_B_WRITE 13  
  104. #define ST1_C_WRITE 14  
  105. #define ST1_D_WRITE 15  
  106. #define ST_INIT 32  
  107.   
  108.   
  109.   
  110. typedef struct tagST_INIT{  
  111.     int nChn;  
  112.     int nBaud;  
  113.     unsigned char byMode;  
  114. } myST_INIT;  
  115. myST_INIT st0A_init;  
  116. myST_INIT st0B_init;  
  117. myST_INIT st0C_init;  
  118. myST_INIT st0D_init;  
  119. myST_INIT st0E_init;  
  120. myST_INIT st0F_init;  
  121. myST_INIT st0G_init;  
  122. myST_INIT st0H_init;  
  123.   
  124. #define NONEPARITY  0x00  
  125. #define ODDPARITY   0x08  
  126. #define EVENPARITY  0x18  
  127. #define DATA7BIT    0x80  
  128.   
  129. #define BAUDBASE    0x30                    /***4800bps->hex***/  
  130. #define ST_COM_CNT  8  
  131.   
  132. #define ST_RECV_LEN 1600  
  133. #define ST_SEND_LEN 160  
  134.   
  135. //以下定义与系统地址相关(与CPLD有关系)  
  136. /*   68 mode interface       
  137.     HOW TO Select CHannel    
  138.     CS    A4     A3      CHANNEL    
  139.     1      0/1   0/1       None    
  140.     0       0      0           A    
  141.     0       0      1           B    
  142.     0       1      0           C   
  143.     0       1      1           D       
  144.     Internal Register is Decoded by A2 A1 A0; 
  145.     具体定义见程序开头的宏定义         
  146.     两片ST16C554都接在405EP的PCS3上, 
  147.     用A6和A5来区分ST16C554   */  
  148.       
  149. /*这里采用D、C、B、A及H、G、F、E的方式编号主要是为了满足板子 
  150.    上串口定死的从左到右1——8顺序,并没有其它特殊含义*/  
  151. #define  YC_PHY_BASE_ADRR           0xf0200000      //映射基地址空间  
  152. #define  UcsAnd                     0xffffff07      // addr(7)='0',addr(6)='0',addr(5)='0',addr(4)='0',addr(3)='0'  
  153. #define  Ucs_DChannel_Or            0x20            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='0',addr(3)='0'  
  154. #define  Ucs_CChannel_Or            0x28            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='0',addr(3)='1'  
  155. #define  Ucs_BChannel_Or            0x30            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='1',addr(3)='0'  
  156. #define  Ucs_AChannel_Or            0x38            // addr(7)='0',addr(6)='0',addr(5)='1',addr(4)='1',addr(3)='1'  
  157. #define  Ucs_HChannel_Or            0x40            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='0',addr(3)='0'  
  158. #define  Ucs_GChannel_Or            0x48            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='0',addr(3)='1'  
  159. #define  Ucs_FChannel_Or            0x50            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='1',addr(3)='0'  
  160. #define  Ucs_EChannel_Or            0x58            // addr(7)='0',addr(6)='1',addr(5)='0',addr(4)='1',addr(3)='1'  
  161.   
  162. #define  YC_mul232_IRQ0   26  //中断号 IRQ1  
  163. #define  YC_mul232_IRQ1   30  //中断号 IRQ5  
  164.   
  165. #define delay_counter 100000  //用于写函数,写入一个字符寄存器先延时,然后再写下一个字符  
  166.   
  167. typedef struct {  
  168.     int nAddress0;  
  169.     int nAddress1;  
  170.     int sInited;  
  171.     unsigned char *pbyBase0;  
  172.       
  173.     //数据寄存器  
  174.     int RBR;//Receiver-buffer register              0  
  175.     int THR;//Transmitter-holding register          0  
  176.       
  177.     //状态寄存器  
  178.     int LSR;//Line-status register                  5  
  179.     int MSR;//Modem-status register                 6  
  180.       
  181.     //控制寄存器  
  182.     int LCR;//Line-control register                 3  
  183.     int FCR;//FIFO-control register                 2  
  184.     int MCR;//Modem-control register                4  
  185.     int DLL;//Divisor-latch LSB                     0  
  186.     int DLM;//Divisor-latch MSB                     1  
  187.     int IER;//Interrupt enable register             1  
  188.       
  189.     //其它寄存器  
  190.     int SPR;//Scratchpad register                   7  
  191.     int IIR;//Interrupt identification register     2  
  192.       
  193.     //串口数据接收缓冲区  
  194.     volatile short sRecvHead;  
  195.     volatile short sRecvTail;  
  196.     volatile unsigned char abyRecvData[ST_RECV_LEN];  
  197.       
  198.     //串口数据发送缓冲区  
  199.     volatile short sSendHead;  
  200.     volatile short sSendTail;  
  201.     volatile unsigned char abySendData[ST_SEND_LEN];  
  202.       
  203. } ST_COM;  
  204.   
  205. static ST_COM st0A = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_AChannel_Or), 0};  
  206. static ST_COM st0B = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_BChannel_Or), 0};  
  207. static ST_COM st0C = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_CChannel_Or), 0};  
  208. static ST_COM st0D = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_DChannel_Or), 0};  
  209.   
  210. static ST_COM st0E = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_EChannel_Or), 0};  
  211. static ST_COM st0F = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_FChannel_Or), 0};  
  212. static ST_COM st0G = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_GChannel_Or), 0};  
  213. static ST_COM st0H = { ( (YC_PHY_BASE_ADRR& UcsAnd) | Ucs_HChannel_Or), 0};  
  214.   
  215. #define DEVICE_NAME "ST16C554"  
  216. #define DEVICE_MAJOR 233  
  217. #define ST0A    0  
  218. #define ST0B    1  
  219. #define ST0C    2  
  220. #define ST0D    3  
  221. #define ST0E    4  
  222. #define ST0F    5  
  223. #define ST0G    6  
  224. #define ST0H    7  
  225. static int stMajor = 233;  
  226.   
  227.   
  228. inline int get_ST0A_rxLen(void){  
  229.     if(st0A.sRecvHead==st0A.sRecvTail){  
  230.         return 0;  
  231.     }  
  232.     else if(st0A.sRecvTail>st0A.sRecvHead){  
  233.         return (st0A.sRecvTail-st0A.sRecvHead);  
  234.     }  
  235.     else{  
  236.         return ( ST_RECV_LEN-(st0A.sRecvHead-st0A.sRecvTail) );  
  237.     }  
  238. }  
  239. inline int get_ST0B_rxLen(void){  
  240.     if(st0B.sRecvHead==st0B.sRecvTail){  
  241.         return 0;  
  242.     }  
  243.     else if(st0B.sRecvTail>st0B.sRecvHead){  
  244.         return (st0B.sRecvTail-st0B.sRecvHead);  
  245.     }  
  246.     else{  
  247.         return ( ST_RECV_LEN-(st0B.sRecvHead-st0B.sRecvTail) );  
  248.     }  
  249. }  
  250. inline int get_ST0C_rxLen(void){  
  251.     if(st0C.sRecvHead==st0C.sRecvTail){  
  252.         return 0;  
  253.     }  
  254.     else if(st0C.sRecvTail>st0C.sRecvHead){  
  255.         return (st0C.sRecvTail-st0C.sRecvHead);  
  256.     }  
  257.     else{  
  258.         return ( ST_RECV_LEN-(st0C.sRecvHead-st0C.sRecvTail) );  
  259.     }  
  260. }  
  261. inline int get_ST0D_rxLen(void){  
  262.     if(st0D.sRecvHead==st0D.sRecvTail){  
  263.         return 0;  
  264.     }  
  265.     else if(st0D.sRecvTail>st0D.sRecvHead){  
  266.         return (st0D.sRecvTail-st0D.sRecvHead);  
  267.     }  
  268.     else{  
  269.         return ( ST_RECV_LEN-(st0D.sRecvHead-st0D.sRecvTail) );  
  270.     }  
  271. }  
  272.   
  273. inline int get_ST0E_rxLen(void){  
  274.     if(st0E.sRecvHead==st0E.sRecvTail){  
  275.         return 0;  
  276.     }  
  277.     else if(st0E.sRecvTail>st0E.sRecvHead){  
  278.         return (st0E.sRecvTail-st0E.sRecvHead);  
  279.     }  
  280.     else{  
  281.         return ( ST_RECV_LEN-(st0E.sRecvHead-st0E.sRecvTail) );  
  282.     }  
  283. }  
  284. inline int get_ST0F_rxLen(void){  
  285.     if(st0F.sRecvHead==st0F.sRecvTail){  
  286.         return 0;  
  287.     }  
  288.     else if(st0F.sRecvTail>st0F.sRecvHead){  
  289.         return (st0F.sRecvTail-st0F.sRecvHead);  
  290.     }  
  291.     else{  
  292.         return ( ST_RECV_LEN-(st0F.sRecvHead-st0F.sRecvTail) );  
  293.     }  
  294. }  
  295. inline int get_ST0G_rxLen(void){  
  296.     if(st0G.sRecvHead==st0G.sRecvTail){  
  297.         return 0;  
  298.     }  
  299.     else if(st0G.sRecvTail>st0G.sRecvHead){  
  300.         return (st0G.sRecvTail-st0G.sRecvHead);  
  301.     }  
  302.     else{  
  303.         return ( ST_RECV_LEN-(st0G.sRecvHead-st0G.sRecvTail) );  
  304.     }  
  305. }  
  306. inline int get_ST0H_rxLen(void){  
  307.     if(st0H.sRecvHead==st0H.sRecvTail){  
  308.         return 0;  
  309.     }  
  310.     else if(st0H.sRecvTail>st0H.sRecvHead){  
  311.         return (st0H.sRecvTail-st0H.sRecvHead);  
  312.     }  
  313.     else{  
  314.         return ( ST_RECV_LEN-(st0H.sRecvHead-st0H.sRecvTail) );  
  315.     }  
  316. }  
  317.   
  318. inline int get_ST0A_txLen(void){  
  319.     if(st0A.sSendHead==st0A.sSendTail){  
  320.         return 0;  
  321.     }  
  322.     else if(st0A.sSendTail>st0A.sSendHead){  
  323.         return (st0A.sSendTail-st0A.sSendHead);  
  324.     }  
  325.     else{  
  326.         return ( ST_SEND_LEN-(st0A.sSendHead-st0A.sSendTail) );  
  327.     }  
  328. }  
  329. inline int get_ST0B_txLen(void){  
  330.     if(st0B.sSendHead==st0B.sSendTail){  
  331.         return 0;  
  332.     }  
  333.     else if(st0B.sSendTail>st0B.sSendHead){  
  334.         return (st0B.sSendTail-st0B.sSendHead);  
  335.     }  
  336.     else{  
  337.         return ( ST_SEND_LEN-(st0B.sSendHead-st0B.sSendTail) );  
  338.     }  
  339. }  
  340. inline int get_ST0C_txLen(void){  
  341.     if(st0C.sSendHead==st0C.sSendTail){  
  342.         return 0;  
  343.     }  
  344.     else if(st0C.sSendTail>st0C.sSendHead){  
  345.         return (st0C.sSendTail-st0C.sSendHead);  
  346.     }  
  347.     else{  
  348.         return ( ST_SEND_LEN-(st0C.sSendHead-st0C.sSendTail) );  
  349.     }  
  350. }  
  351. inline int get_ST0D_txLen(void){  
  352.     if(st0D.sSendHead==st0D.sSendTail){  
  353.         return 0;  
  354.     }  
  355.     else if(st0D.sSendTail>st0D.sSendHead){  
  356.         return (st0D.sSendTail-st0D.sSendHead);  
  357.     }  
  358.     else{  
  359.         return ( ST_SEND_LEN-(st0D.sSendHead-st0D.sSendTail) );  
  360.     }  
  361. }  
  362.   
  363. inline int get_ST0E_txLen(void){  
  364.     if(st0E.sSendHead==st0E.sSendTail){  
  365.         return 0;  
  366.     }  
  367.     else if(st0E.sSendTail>st0E.sSendHead){  
  368.         return (st0E.sSendTail-st0E.sSendHead);  
  369.     }  
  370.     else{  
  371.         return ( ST_SEND_LEN-(st0E.sSendHead-st0E.sSendTail) );  
  372.     }  
  373. }  
  374. inline int get_ST0F_txLen(void){  
  375.     if(st0F.sSendHead==st0F.sSendTail){  
  376.         return 0;  
  377.     }  
  378.     else if(st0F.sSendTail>st0F.sSendHead){  
  379.         return (st0F.sSendTail-st0F.sSendHead);  
  380.     }  
  381.     else{  
  382.         return ( ST_SEND_LEN-(st0F.sSendHead-st0F.sSendTail) );  
  383.     }  
  384. }  
  385. inline int get_ST0G_txLen(void){  
  386.     if(st0G.sSendHead==st0G.sSendTail){  
  387.         return 0;  
  388.     }  
  389.     else if(st0G.sSendTail>st0G.sSendHead){  
  390.         return (st0G.sSendTail-st0G.sSendHead);  
  391.     }  
  392.     else{  
  393.         return ( ST_SEND_LEN-(st0G.sSendHead-st0G.sSendTail) );  
  394.     }  
  395. }  
  396. inline int get_ST0H_txLen(void){  
  397.     if(st0H.sSendHead==st0H.sSendTail){  
  398.         return 0;  
  399.     }  
  400.     else if(st0H.sSendTail>st0H.sSendHead){  
  401.         return (st0H.sSendTail-st0H.sSendHead);  
  402.     }  
  403.     else{  
  404.         return ( ST_SEND_LEN-(st0H.sSendHead-st0H.sSendTail) );  
  405.     }  
  406. }  
  407.   
  408. inline char st0aIsEmpty_rx(void){  
  409.     return (st0A.sRecvHead==st0A.sRecvTail ? 1 : 0);  
  410. }  
  411. inline char st0bIsEmpty_rx(void){  
  412.     return (st0B.sRecvHead==st0B.sRecvTail ? 1 : 0);  
  413. }  
  414. inline char st0cIsEmpty_rx(void){  
  415.     return (st0C.sRecvHead==st0C.sRecvTail ? 1 : 0);  
  416. }  
  417. inline char st0dIsEmpty_rx(void){  
  418.     return (st0D.sRecvHead==st0D.sRecvTail ? 1 : 0);  
  419. }  
  420.   
  421. inline char st0eIsEmpty_rx(void){  
  422.     return (st0E.sRecvHead==st0E.sRecvTail ? 1 : 0);  
  423. }  
  424. inline char st0fIsEmpty_rx(void){  
  425.     return (st0F.sRecvHead==st0F.sRecvTail ? 1 : 0);  
  426. }  
  427. inline char st0gIsEmpty_rx(void){  
  428.     return (st0G.sRecvHead==st0G.sRecvTail ? 1 : 0);  
  429. }  
  430. inline char st0hIsEmpty_rx(void){  
  431.     return (st0H.sRecvHead==st0H.sRecvTail ? 1 : 0);  
  432. }  
  433.   
  434.   
  435. inline char st0aIsFull_rx(void){  
  436.     return (st0A.sRecvHead==(st0A.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  437. }  
  438. inline char st0bIsFull_rx(void){  
  439.     return (st0B.sRecvHead==(st0B.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  440. }  
  441. inline char st0cIsFull_rx(void){  
  442.     return (st0C.sRecvHead==(st0C.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  443. }  
  444. inline char st0dIsFull_rx(void){  
  445.     return (st0D.sRecvHead==(st0D.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  446. }  
  447.   
  448. inline char st0eIsFull_rx(void){  
  449.     return (st0E.sRecvHead==(st0E.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  450. }  
  451. inline char st0fIsFull_rx(void){  
  452.     return (st0F.sRecvHead==(st0F.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  453. }  
  454. inline char st0gIsFull_rx(void){  
  455.     return (st0G.sRecvHead==(st0G.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  456. }  
  457. inline char st0hIsFull_rx(void){  
  458.     return (st0H.sRecvHead==(st0H.sRecvTail+1)%ST_RECV_LEN ? 1 : 0);  
  459. }  
  460.   
  461. inline char st0aIsEmpty_tx(void){  
  462.     return (st0A.sSendHead==st0A.sSendTail ? 1 : 0);  
  463. }  
  464. inline char st0bIsEmpty_tx(void){  
  465.     return (st0B.sSendHead==st0B.sSendTail ? 1 : 0);  
  466. }  
  467. inline char st0cIsEmpty_tx(void){  
  468.     return (st0C.sSendHead==st0C.sSendTail ? 1 : 0);  
  469. }  
  470. inline char st0dIsEmpty_tx(void){  
  471.     return (st0D.sSendHead==st0D.sSendTail ? 1 : 0);  
  472. }  
  473.   
  474. inline char st0eIsEmpty_tx(void){  
  475.     return (st0E.sSendHead==st0E.sSendTail ? 1 : 0);  
  476. }  
  477. inline char st0fIsEmpty_tx(void){  
  478.     return (st0F.sSendHead==st0F.sSendTail ? 1 : 0);  
  479. }  
  480. inline char st0gIsEmpty_tx(void){  
  481.     return (st0G.sSendHead==st0G.sSendTail ? 1 : 0);  
  482. }  
  483. inline char st0hIsEmpty_tx(void){  
  484.     return (st0H.sSendHead==st0H.sSendTail ? 1 : 0);  
  485. }  
  486.   
  487. inline char st0aIsFull_tx(void){  
  488.     return (st0A.sSendHead==(st0A.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  489. }  
  490. inline char st0bIsFull_tx(void){  
  491.     return (st0B.sSendHead==(st0B.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  492. }  
  493. inline char st0cIsFull_tx(void){  
  494.     return (st0C.sSendHead==(st0C.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  495. }  
  496. inline char st0dIsFull_tx(void){  
  497.     return (st0D.sSendHead==(st0D.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  498. }  
  499. inline char st0eIsFull_tx(void){  
  500.     return (st0E.sSendHead==(st0E.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  501. }  
  502. inline char st0fIsFull_tx(void){  
  503.     return (st0F.sSendHead==(st0F.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  504. }  
  505. inline char st0gIsFull_tx(void){  
  506.     return (st0G.sSendHead==(st0G.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  507. }  
  508. inline char st0hIsFull_tx(void){  
  509.     return (st0H.sSendHead==(st0H.sSendTail+1)%ST_SEND_LEN ? 1 : 0);  
  510. }  
  511.   
  512.   
  513. inline void pushST0ARX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  514.     st0A.abyRecvData[st0A.sRecvTail] = byRx;  
  515.     if(!st0aIsFull_rx()){  
  516.         st0A.sRecvTail++;  
  517.         st0A.sRecvTail %= ST_RECV_LEN;  
  518.     }  
  519. }  
  520. inline void pushST0BRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  521.     st0B.abyRecvData[st0B.sRecvTail] = byRx;  
  522.     if(!st0bIsFull_rx()){  
  523.         st0B.sRecvTail++;  
  524.         st0B.sRecvTail %= ST_RECV_LEN;  
  525.     }  
  526. }  
  527. inline void pushST0CRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  528.     st0C.abyRecvData[st0C.sRecvTail] = byRx;  
  529.     if(!st0cIsFull_rx()){  
  530.         st0C.sRecvTail++;  
  531.         st0C.sRecvTail %= ST_RECV_LEN;  
  532.     }  
  533. }  
  534. inline void pushST0DRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  535.     st0D.abyRecvData[st0D.sRecvTail] = byRx;  
  536.     if(!st0dIsFull_rx()){  
  537.         st0D.sRecvTail++;  
  538.         st0D.sRecvTail %= ST_RECV_LEN;  
  539.     }  
  540. }  
  541.   
  542. inline void pushST0ERX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  543.     st0E.abyRecvData[st0E.sRecvTail] = byRx;  
  544.     if(!st0eIsFull_rx()){  
  545.         st0E.sRecvTail++;  
  546.         st0E.sRecvTail %= ST_RECV_LEN;  
  547.     }  
  548. }  
  549. inline void pushST0FRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  550.     st0F.abyRecvData[st0F.sRecvTail] = byRx;  
  551.     if(!st0fIsFull_rx()){  
  552.         st0F.sRecvTail++;  
  553.         st0F.sRecvTail %= ST_RECV_LEN;  
  554.     }  
  555. }  
  556. inline void pushST0GRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  557.     st0G.abyRecvData[st0G.sRecvTail] = byRx;  
  558.     if(!st0gIsFull_rx()){  
  559.         st0G.sRecvTail++;  
  560.         st0G.sRecvTail %= ST_RECV_LEN;  
  561.     }  
  562. }  
  563. inline void pushST0HRX(unsigned char byRx){//缓冲区满时, 最后一个接收数据放在最后一个位置  
  564.     st0H.abyRecvData[st0H.sRecvTail] = byRx;  
  565.     if(!st0hIsFull_rx()){  
  566.         st0H.sRecvTail++;  
  567.         st0H.sRecvTail %= ST_RECV_LEN;  
  568.     }  
  569. }  
  570.   
  571.   
  572. inline unsigned char st0apopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  573.     unsigned char byRet;  
  574.     byRet = st0A.abyRecvData[st0A.sRecvHead];  
  575.     if(!st0aIsEmpty_rx()){  
  576.         st0A.sRecvHead++;  
  577.         st0A.sRecvHead %= ST_RECV_LEN;  
  578.     }  
  579.     return byRet;  
  580. }  
  581. inline unsigned char st0bpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  582.     unsigned char byRet;  
  583.     byRet = st0B.abyRecvData[st0B.sRecvHead];  
  584.     if(!st0bIsEmpty_rx()){  
  585.         st0B.sRecvHead++;  
  586.         st0B.sRecvHead %= ST_RECV_LEN;  
  587.     }  
  588.     return byRet;  
  589. }  
  590. inline unsigned char st0cpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  591.     unsigned char byRet;  
  592.     byRet = st0C.abyRecvData[st0C.sRecvHead];  
  593.     if(!st0cIsEmpty_rx()){  
  594.         st0C.sRecvHead++;  
  595.         st0C.sRecvHead %= ST_RECV_LEN;  
  596.     }  
  597.     return byRet;  
  598. }  
  599. inline unsigned char st0dpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  600.     unsigned char byRet;  
  601.     byRet = st0D.abyRecvData[st0D.sRecvHead];  
  602.     if(!st0dIsEmpty_rx()){  
  603.         st0D.sRecvHead++;  
  604.         st0D.sRecvHead %= ST_RECV_LEN;  
  605.     }  
  606.     return byRet;  
  607. }  
  608.   
  609. inline unsigned char st0epopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  610.     unsigned char byRet;  
  611.     byRet = st0E.abyRecvData[st0E.sRecvHead];  
  612.     if(!st0eIsEmpty_rx()){  
  613.         st0E.sRecvHead++;  
  614.         st0E.sRecvHead %= ST_RECV_LEN;  
  615.     }  
  616.     return byRet;  
  617. }  
  618. inline unsigned char st0fpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  619.     unsigned char byRet;  
  620.     byRet = st0F.abyRecvData[st0F.sRecvHead];  
  621.     if(!st0fIsEmpty_rx()){  
  622.         st0F.sRecvHead++;  
  623.         st0F.sRecvHead %= ST_RECV_LEN;  
  624.     }  
  625.     return byRet;  
  626. }  
  627. inline unsigned char st0gpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  628.     unsigned char byRet;  
  629.     byRet = st0G.abyRecvData[st0G.sRecvHead];  
  630.     if(!st0gIsEmpty_rx()){  
  631.         st0G.sRecvHead++;  
  632.         st0G.sRecvHead %= ST_RECV_LEN;  
  633.     }  
  634.     return byRet;  
  635. }  
  636. inline unsigned char st0hpopRX(void){//为空时返回最后接收到的一个数据,从未接收到数据时返回缓冲区第一个字节数据  
  637.     unsigned char byRet;  
  638.     byRet = st0H.abyRecvData[st0H.sRecvHead];  
  639.     if(!st0hIsEmpty_rx()){  
  640.         st0H.sRecvHead++;  
  641.         st0H.sRecvHead %= ST_RECV_LEN;  
  642.     }  
  643.     return byRet;  
  644. }  
  645.   
  646.   
  647. static void InitCommont(ST_COM *pst,int nBaud, unsigned char byMode)  
  648. {  
  649.     volatile unsigned char byRx;  
  650.     int i;  
  651.       
  652.     if(0 != pst->sInited){  
  653.         iounmap((void *) (pst->pbyBase0));  
  654.   
  655.     }  
  656.     pst->pbyBase0 = (unsigned char *)ioremap_nocache(pst->nAddress0, 8);  
  657.   
  658.     pst->RBR = (int)(pst->pbyBase0);  
  659.     pst->THR = (int)(pst->pbyBase0);    
  660.     pst->DLL = (int)(pst->pbyBase0);  
  661.     pst->DLM = (int)(pst->pbyBase0+1);  
  662.     pst->IER = (int)(pst->pbyBase0+1);  
  663.     pst->FCR = (int)(pst->pbyBase0+2);  
  664.     pst->IIR = (int)(pst->pbyBase0+2);  
  665.     pst->LCR = (int)(pst->pbyBase0+3);  
  666.     pst->MCR = (int)(pst->pbyBase0+4);  
  667.     pst->LSR = (int)(pst->pbyBase0+5);  
  668.     pst->MSR = (int)(pst->pbyBase0+6);  
  669.     pst->SPR = (int)(pst->pbyBase0+7);  
  670.       
  671.     pst->sRecvHead = 0;  
  672.     pst->sRecvTail = 0;  
  673.     pst->sSendHead = 0;  
  674.     pst->sSendTail = 0;  
  675.       
  676.     //IER  
  677.     //接收保持和中断允许  
  678.     *(volatile unsigned char *)(pst->IER) = 0x01;//0x05;  
  679.       
  680.     //FIFO控制器  
  681.     //set FCR.FIFO允许,RXD复位,TXD复位,DMAmode=1,触发为14  
  682.     *(volatile unsigned char *)(pst->FCR) = 0xcf;  
  683.     for(i=0; i<100; i++);  
  684.     //set FCR.RXD复位,TXD复位  
  685.     *(volatile unsigned char *)(pst->FCR) = 0xc9;  
  686.       
  687.     //Modem状态  
  688.     //set MCR.中断A-D开  
  689.     //*(volatile unsigned char *)(pst->MCR) = 0x08;  //change by zhujiang,our program not use this now  
  690.       
  691.     if(byMode&0x80){  
  692.         *(volatile unsigned char *)(pst->LCR) = 0x82|(byMode&0x7f);//7 bit  
  693.     }  
  694.     else{  
  695.         //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器  
  696.         *(volatile unsigned char *)(pst->LCR) = 0x83|byMode;  
  697.     }  
  698.   
  699. /***************************************************************************   
  700. **  SET st baudrate.         
  701.      BAUD RATE GENRATOR PROGRAMMING TABLE        
  702.      Output Baud Rate        DLM    DLL      
  703.      (7.3278MHz Clock)       (HEX)  (HEX)            
  704.                  200          09      00           
  705.                  1200         01     80           
  706.                  2400         00     C0           
  707.                  4800         00     60           
  708.                  9600         00     30           
  709.                  19.2K        00     18           
  710.                  38.4K        00     0C           
  711.                  76.8K        00     06           
  712.                  153.6K       00     03          
  713.                  230.4K       00     02           
  714.                  460.8K       00     01   
  715. **         
  716. ***************************************************************************/  
  717.       
  718. //  特殊寄存器已打开,设置BPS  
  719. //  *(volatile unsigned char *)(pst->DLL) = BAUDBASE/nBaud;  
  720. //  高位  
  721. //  *(volatile unsigned char *)(pst->DLM) = 0x00;  
  722.   
  723.       switch(nBaud){  
  724.            case 200:  
  725.                 *(volatile unsigned char *)(pst->DLL) = 0x00;  
  726.                  //高位  
  727.                 *(volatile unsigned char *)(pst->DLM) = 0x09;  
  728.                 break;  
  729.            case 1200:  
  730.                 *(volatile unsigned char *)(pst->DLL) = 0x80;  
  731.                  //高位  
  732.                 *(volatile unsigned char *)(pst->DLM) = 0x01;  
  733.                 break;       
  734.            case 2400:  
  735.                 *(volatile unsigned char *)(pst->DLL) = 0xC0;  
  736.                  //高位  
  737.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  738.                 break;  
  739.            case 4800:  
  740.                 *(volatile unsigned char *)(pst->DLL) = 0x60;  
  741.                  //高位  
  742.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  743.                 break;        
  744.            case 9600:  
  745.                 *(volatile unsigned char *)(pst->DLL) = 0x30;  
  746.                  //高位  
  747.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  748.                 break;    
  749.            case 19200:  
  750.                 *(volatile unsigned char *)(pst->DLL) = 0x18;  
  751.                  //高位  
  752.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  753.                 break;  
  754.            case 38400:  
  755.                 *(volatile unsigned char *)(pst->DLL) = 0x0C;  
  756.                  //高位  
  757.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  758.                 break;                
  759.            case 76800:  
  760.                 *(volatile unsigned char *)(pst->DLL) = 0x06;  
  761.                  //高位  
  762.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  763.                 break;  
  764.            case 153600:  
  765.                 *(volatile unsigned char *)(pst->DLL) = 0x03;  
  766.                  //高位  
  767.                 *(volatile unsigned char *)(pst->DLM) = 0x00;  
  768.                 break;                
  769.             default:  
  770.           break;                  
  771.       }  
  772.       
  773.     if(byMode&0x80){  
  774.         *(volatile unsigned char *)(pst->LCR) = 0x02|(byMode&0x7f);//7 bit  
  775.     }  
  776.     else{  
  777.         //set LCR.8BIT,1STOP,ODDPARITY,选择特殊寄存器  
  778.         *(volatile unsigned char *)(pst->LCR) = 0x03|byMode;  
  779.     }  
  780.       
  781.       
  782.     //空读一次  
  783.     byRx = *(volatile unsigned char *)(pst->RBR);  
  784.       
  785.     //读空  
  786.     i=0;  
  787.     while(1){  
  788.         //检查接收状态  
  789.         byRx = *(volatile unsigned char *)(pst->LSR);  
  790.         if(byRx&0x01){  
  791.             byRx = *(volatile unsigned char *)(pst->RBR);  
  792.         }  
  793.         else  
  794.             break;  
  795.           
  796.         //防止死循环  
  797.         i++;  
  798.         if(i > 4096)//每个UART最多只能缓存16个字节  
  799.             break;  
  800.     }  
  801.       
  802.     pst->sInited = 1;  
  803. }  
  804.   
  805.   
  806. //ST16C554初始化  
  807. void Init_ST0A(int nBaud, unsigned char byMode){  
  808.     InitCommont(&st0A,nBaud,byMode);  
  809. }  
  810.   
  811. void Init_ST0B(int nBaud, unsigned char byMode){  
  812.     InitCommont(&st0B,nBaud,byMode);  
  813. }  
  814.   
  815. void Init_ST0C(int nBaud, unsigned char byMode){  
  816.     InitCommont(&st0C,nBaud,byMode);  
  817. }  
  818.   
  819. void Init_ST0D(int nBaud, unsigned char byMode){  
  820.     InitCommont(&st0D,nBaud,byMode);  
  821. }  
  822. void Init_ST0E(int nBaud, unsigned char byMode){  
  823.     InitCommont(&st0E,nBaud,byMode);  
  824. }  
  825.   
  826. void Init_ST0F(int nBaud, unsigned char byMode){  
  827.     InitCommont(&st0F,nBaud,byMode);  
  828. }  
  829.   
  830. void Init_ST0G(int nBaud, unsigned char byMode){  
  831.     InitCommont(&st0G,nBaud,byMode);  
  832. }  
  833.   
  834. void Init_ST0H(int nBaud, unsigned char byMode){  
  835.     InitCommont(&st0H,nBaud,byMode);  
  836. }  
  837.   
  838. //ST16C554的接收  
  839. unsigned char ST0A_Rxd(void){  
  840.     volatile unsigned char byRx;  
  841.     volatile unsigned char bySt;  
  842.     int nRxCnt = 0;  
  843.     while(nRxCnt < 256){  
  844.         bySt = *(volatile unsigned char *)(st0A.LSR);//检查接收状态  
  845.         if(bySt&0x01){//数据就绪  
  846.             byRx = *(volatile unsigned char *)(st0A.RBR);  
  847.             pushST0ARX(byRx);  
  848.         }  
  849.         else  
  850.             break;  
  851.         nRxCnt++;  
  852.     }  
  853.     return byRx;  
  854. }  
  855.   
  856. unsigned char ST0B_Rxd(void){  
  857.     volatile unsigned char byRx;  
  858.     volatile unsigned char bySt;  
  859.     int nRxCnt = 0;  
  860.       
  861.     while(nRxCnt < 256){  
  862.         bySt = *(volatile unsigned char *)(st0B.LSR);//检查接收状态  
  863.         if(bySt&0x01){//数据就绪  
  864.             byRx = *(volatile unsigned char *)(st0B.RBR);  
  865.             pushST0BRX(byRx);  
  866.         }  
  867.         else{  
  868.             break;  
  869.         }  
  870.         nRxCnt++;  
  871.     }  
  872.       
  873.     return byRx;  
  874. }  
  875. unsigned char ST0C_Rxd(void){  
  876.     volatile unsigned char byRx;  
  877.     volatile unsigned char bySt;  
  878.     int nRxCnt = 0;  
  879.       
  880.       
  881.     while(nRxCnt < 256){  
  882.         bySt = *(volatile unsigned char *)(st0C.LSR);//检查接收状态  
  883.         if(bySt&0x01){//数据就绪  
  884.             byRx = *(volatile unsigned char *)(st0C.RBR);  
  885.             pushST0CRX(byRx);  
  886.         }  
  887.         else  
  888.             break;  
  889.         nRxCnt++;  
  890.     }  
  891.     return byRx;  
  892. }  
  893. unsigned char ST0D_Rxd(void){  
  894.     volatile unsigned char byRx;  
  895.     volatile unsigned char bySt;  
  896.     int nRxCnt = 0;  
  897.     while(nRxCnt < 256){  
  898.         bySt = *(volatile unsigned char *)(st0D.LSR);//检查接收状态  
  899.         if(bySt&0x01){//数据就绪  
  900.             byRx = *(volatile unsigned char *)(st0D.RBR);  
  901.             pushST0DRX(byRx);  
  902.         }  
  903.         else  
  904.             break;  
  905.         nRxCnt++;  
  906.     }  
  907.     return byRx;  
  908. }  
  909.   
  910. unsigned char ST0E_Rxd(void){  
  911.     volatile unsigned char byRx;  
  912.     volatile unsigned char bySt;  
  913.     int nRxCnt = 0;  
  914.     while(nRxCnt < 256){  
  915.         bySt = *(volatile unsigned char *)(st0E.LSR);//检查接收状态  
  916.         if(bySt&0x01){//数据就绪  
  917.             byRx = *(volatile unsigned char *)(st0E.RBR);  
  918.             pushST0ERX(byRx);  
  919.         }  
  920.         else  
  921.             break;  
  922.         nRxCnt++;  
  923.     }  
  924.     return byRx;  
  925. }  
  926.   
  927. unsigned char ST0F_Rxd(void){  
  928.     volatile unsigned char byRx;  
  929.     volatile unsigned char bySt;  
  930.     int nRxCnt = 0;  
  931.       
  932.     while(nRxCnt < 256){  
  933.         bySt = *(volatile unsigned char *)(st0F.LSR);//检查接收状态  
  934.         if(bySt&0x01){//数据就绪  
  935.             byRx = *(volatile unsigned char *)(st0F.RBR);  
  936.             pushST0FRX(byRx);  
  937.         }  
  938.         else{  
  939.             break;  
  940.         }  
  941.         nRxCnt++;  
  942.     }  
  943.       
  944.     return byRx;  
  945. }  
  946. unsigned char ST0G_Rxd(void){  
  947.     volatile unsigned char byRx;  
  948.     volatile unsigned char bySt;  
  949.     int nRxCnt = 0;  
  950.       
  951.       
  952.     while(nRxCnt < 256){  
  953.         bySt = *(volatile unsigned char *)(st0G.LSR);//检查接收状态  
  954.         if(bySt&0x01){//数据就绪  
  955.             byRx = *(volatile unsigned char *)(st0G.RBR);  
  956.             pushST0GRX(byRx);  
  957.         }  
  958.         else  
  959.             break;  
  960.         nRxCnt++;  
  961.     }  
  962.     return byRx;  
  963. }  
  964. unsigned char ST0H_Rxd(void){  
  965.     volatile unsigned char byRx;  
  966.     volatile unsigned char bySt;  
  967.     int nRxCnt = 0;  
  968.     while(nRxCnt < 256){  
  969.         bySt = *(volatile unsigned char *)(st0H.LSR);//检查接收状态  
  970.         if(bySt&0x01){//数据就绪  
  971.             byRx = *(volatile unsigned char *)(st0H.RBR);  
  972.             pushST0HRX(byRx);  
  973.         }  
  974.         else  
  975.             break;  
  976.         nRxCnt++;  
  977.     }  
  978.     return byRx;  
  979. }  
  980.   
  981. //ST16C554的发送  
  982. //返回:1,成功  
  983. //     0,失败  
  984. int ST_ComTxd(ST_COM *pst,unsigned char byTxd){  
  985.     unsigned char byRx;  
  986.     int nTxCnt = 0;  
  987.     while(nTxCnt < 256){  
  988.         byRx = *(volatile unsigned char *)(pst->LSR);//检查发送状态  
  989.         if(byRx&0x20){//发送就绪  
  990.             *(volatile unsigned char *)(pst->THR) = byTxd;  
  991.             return 1;  
  992.         }  
  993.         else{  
  994.             nTxCnt++;  
  995.         }  
  996.     }  
  997.     return 0;  
  998. }  
  999.   
  1000.   
  1001. static void UART0_interrupt(int irq, void *dev_id, struct pt_regs *regs)  
  1002. {  
  1003.   
  1004.     //save_flags_cli(flags);  
  1005.     if (st0A.sInited)  
  1006.         ST0A_Rxd();  
  1007. //      printk(KERN_INFO "UART0_interrupt1\n" );  
  1008.     if (st0B.sInited)  
  1009.         ST0B_Rxd();  
  1010. //      printk(KERN_INFO "UART0_interrupt2\n" );  
  1011.     if (st0C.sInited);  
  1012.         ST0C_Rxd();      
  1013. //      printk(KERN_INFO "UART0_interrupt3\n" );  
  1014.   if (st0D.sInited)  
  1015.         ST0D_Rxd();  
  1016. //      printk(KERN_INFO "UART0_interrupt4\n" );  
  1017.     //restore_flags(flags);  
  1018.   
  1019. }  
  1020.   
  1021. static void UART1_interrupt(int irq, void *dev_id, struct pt_regs *regs)  
  1022. {  
  1023.   
  1024.     if (st0E.sInited)     
  1025.         ST0E_Rxd();  
  1026. //      printk(KERN_INFO "UART1_interrupt0\n" );  
  1027.     if (st0F.sInited)  
  1028.         ST0F_Rxd();  
  1029. //      printk(KERN_INFO "UART1_interrupt1\n" );  
  1030.     if (st0G.sInited)  
  1031.         ST0G_Rxd();  
  1032. //      printk(KERN_INFO "UART1_interrupt2\n" );  
  1033.   if (st0H.sInited)  
  1034.         ST0H_Rxd();  
  1035. //      printk(KERN_INFO "UART1_interrupt3\n" );  
  1036.   
  1037. }  
  1038.   
  1039.   
  1040. static int st16c554_open(struct inode *inode, struct file *filp)  
  1041. {  
  1042.     int nRet = 0;  
  1043.     MOD_INC_USE_COUNT;  
  1044.     return nRet;  
  1045. }  
  1046.   
  1047. static int st16c554_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1048. {  
  1049.     int nRet = 0;  
  1050.     switch(cmd) {  
  1051.     default:  
  1052.         return -EINVAL;  
  1053.     }  
  1054.     return nRet;  
  1055. }  
  1056.   
  1057. static int st16c554_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)  
  1058. {  
  1059.     int nRet = 0;  
  1060.     return nRet;  
  1061. }  
  1062.   
  1063. static int st16c554_release(struct inode *inode, struct file *filp)  
  1064. {  
  1065.     int nRet = 0;  
  1066.     MOD_DEC_USE_COUNT;  
  1067.     return nRet;  
  1068. }  
  1069.   
  1070.   
  1071. static int st16c554_ComWrite(const char *buf, size_t nCount ,ST_COM *mPst)  
  1072. {  
  1073.     int i,j,nRet;  
  1074.     unsigned char abySend[ST_SEND_LEN];    
  1075.   int m,k;  
  1076.     
  1077.     m=nCount/ST_SEND_LEN;  
  1078.     k=nCount%ST_SEND_LEN;     
  1079.     for(i=0; i<m; i++){  
  1080.       
  1081.       if (copy_from_user(abySend,buf+i*ST_SEND_LEN,ST_SEND_LEN)){  
  1082.             return -EFAULT;  
  1083.       }  
  1084.       for(nRet=0; nRet<ST_SEND_LEN; nRet++){  
  1085.           ST_ComTxd(mPst,abySend[nRet]);  
  1086.             //ST0A_Txd(abySend[nRet]);  
  1087.           
  1088.             for(j=0; j<delay_counter; j++);//300000  
  1089. //      printk("A:%02X\n", abySend[nRet]);  
  1090.       }  
  1091.     }  
  1092.       
  1093.     if (k>0){  
  1094.       if (copy_from_user(abySend,buf+m*ST_SEND_LEN,k)){  
  1095.             return -EFAULT;  
  1096.       }  
  1097.       for(nRet=0; nRet<k; nRet++){  
  1098.           ST_ComTxd(mPst,abySend[nRet]);  
  1099.             //ST0A_Txd(abySend[nRet]);  
  1100.           
  1101.             for(j=0; j<delay_counter; j++);//300000  
  1102. //      printk("A:%02X\n", abySend[nRet]);  
  1103.       }   
  1104.  }  
  1105.     return nRet;      
  1106.       
  1107. }  
  1108.   
  1109.   
  1110. static int ST0A_open(struct inode *inode, struct file *filp)  
  1111. {  
  1112.     int nRet = 0;  
  1113.       
  1114.     MOD_INC_USE_COUNT;  
  1115.     return nRet;  
  1116. }  
  1117.   
  1118. static int ST0A_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1119. {  
  1120.     int nRet = 0;  
  1121.     switch(cmd) {  
  1122.     case ST_INIT:  
  1123.         copy_from_user(&st0A_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1124.         Init_ST0A(st0A_init.nBaud, st0A_init.byMode);  
  1125.         break;  
  1126.     default:  
  1127.         return -EINVAL;  
  1128.     }  
  1129.     return nRet;  
  1130. }  
  1131.   
  1132. static int ST0A_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1133. {  
  1134.     int i;  
  1135.     int nLen;  
  1136.     unsigned char abyRecv[ST_RECV_LEN];  
  1137.     nLen = get_ST0A_rxLen();  
  1138.     nLen = nLen>count ? count : nLen;  
  1139.     for(i=0; i<nLen; i++){  
  1140.         abyRecv[i] = st0A.abyRecvData[st0A.sRecvHead];  
  1141.         if(st0A.sRecvHead != st0A.sRecvTail){  
  1142.             st0A.sRecvHead++;  
  1143.             st0A.sRecvHead %= ST_RECV_LEN;  
  1144.         }  
  1145.         else  
  1146.             break;  
  1147.     }  
  1148.     copy_to_user((void *)buf, &abyRecv, i);  
  1149.     return i;  
  1150. }  
  1151.   
  1152. static int ST0A_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1153.       
  1154.     return st16c554_ComWrite(buf,count,&st0A);  
  1155.       
  1156. }  
  1157.   
  1158. static int ST0A_release(struct inode *inode, struct file *filp)  
  1159. {  
  1160.     int nRet = 0;  
  1161.     MOD_DEC_USE_COUNT;  
  1162.     return nRet;  
  1163. }  
  1164.   
  1165.   
  1166.   
  1167. static int ST0B_open(struct inode *inode, struct file *filp)  
  1168. {  
  1169.     int nRet = 0;  
  1170.     MOD_INC_USE_COUNT;  
  1171.     return nRet;  
  1172. }  
  1173.   
  1174. static int ST0B_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1175. {  
  1176.     int nRet = 0;  
  1177.     switch(cmd) {  
  1178.     case ST_INIT:  
  1179.         copy_from_user(&st0B_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1180.         Init_ST0B(st0B_init.nBaud, st0B_init.byMode);  
  1181.         break;  
  1182.     default:  
  1183.         return -EINVAL;  
  1184.     }  
  1185.     return nRet;  
  1186. }  
  1187.   
  1188. static int ST0B_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1189. {  
  1190.     int i;  
  1191.     int nLen;  
  1192.     unsigned char abyRecv[ST_RECV_LEN];  
  1193.     nLen = get_ST0B_rxLen();  
  1194.     nLen = nLen>count ? count : nLen;  
  1195.     for(i=0; i<nLen; i++){  
  1196.         abyRecv[i] = st0B.abyRecvData[st0B.sRecvHead];  
  1197.         if(st0B.sRecvHead != st0B.sRecvTail){  
  1198.             st0B.sRecvHead++;  
  1199.             st0B.sRecvHead %= ST_RECV_LEN;  
  1200.         }  
  1201.         else  
  1202.             break;  
  1203.     }  
  1204.     copy_to_user((void *)buf, &abyRecv, i);  
  1205.     return i;  
  1206. }  
  1207.   
  1208. static int ST0B_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1209.      
  1210.    return st16c554_ComWrite(buf,count,&st0B);  
  1211.      
  1212. }  
  1213.   
  1214. static int ST0B_release(struct inode *inode, struct file *filp)  
  1215. {  
  1216.     int nRet = 0;  
  1217.     MOD_DEC_USE_COUNT;  
  1218.     return nRet;  
  1219. }  
  1220.   
  1221.   
  1222. static int ST0C_open(struct inode *inode, struct file *filp)  
  1223. {  
  1224.     int nRet = 0;  
  1225.     MOD_INC_USE_COUNT;  
  1226.     return nRet;  
  1227. }  
  1228.   
  1229. static int ST0C_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1230. {  
  1231.     int nRet = 0;  
  1232.     switch(cmd) {  
  1233.     case ST_INIT:  
  1234.         copy_from_user(&st0C_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1235.         Init_ST0C(st0C_init.nBaud, st0C_init.byMode);  
  1236.         break;  
  1237.     default:  
  1238.         return -EINVAL;  
  1239.     }  
  1240.     return nRet;  
  1241. }  
  1242.   
  1243. static int ST0C_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1244. {  
  1245.     int i;  
  1246.     int nLen;  
  1247.     unsigned char abyRecv[ST_RECV_LEN];  
  1248.     nLen = get_ST0C_rxLen();  
  1249.     nLen = nLen>count ? count : nLen;  
  1250.     for(i=0; i<nLen; i++){  
  1251.         abyRecv[i] = st0C.abyRecvData[st0C.sRecvHead];  
  1252.         if(st0C.sRecvHead != st0C.sRecvTail){  
  1253.             st0C.sRecvHead++;  
  1254.             st0C.sRecvHead %= ST_RECV_LEN;  
  1255.         }  
  1256.         else  
  1257.             break;  
  1258.     }  
  1259.     copy_to_user((void *)buf, &abyRecv, i);  
  1260.     return i;  
  1261. }  
  1262.   
  1263. static int ST0C_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1264.      
  1265.    return st16c554_ComWrite(buf,count,&st0C);  
  1266.      
  1267. }  
  1268.   
  1269. static int ST0C_release(struct inode *inode, struct file *filp)  
  1270. {  
  1271.     int nRet = 0;  
  1272.     MOD_DEC_USE_COUNT;  
  1273.     return nRet;  
  1274. }  
  1275.   
  1276. static int ST0D_open(struct inode *inode, struct file *filp)  
  1277. {  
  1278.     int nRet = 0;  
  1279.     MOD_INC_USE_COUNT;  
  1280.     return nRet;  
  1281. }  
  1282.   
  1283. static int ST0D_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1284. {  
  1285.     int nRet = 0;  
  1286.     switch(cmd) {  
  1287.     case ST_INIT:  
  1288.         copy_from_user(&st0D_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1289.         Init_ST0D(st0D_init.nBaud, st0D_init.byMode);  
  1290.         break;    
  1291.     default:  
  1292.         return -EINVAL;  
  1293.     }  
  1294.     return nRet;  
  1295. }  
  1296.   
  1297. static int ST0D_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1298. {  
  1299.     int i;  
  1300.     int nLen;  
  1301.     unsigned char abyRecv[ST_RECV_LEN];  
  1302.     nLen = get_ST0D_rxLen();  
  1303.     nLen = nLen>count ? count : nLen;  
  1304.     for(i=0; i<nLen; i++){  
  1305.         abyRecv[i] = st0D.abyRecvData[st0D.sRecvHead];  
  1306.         if(st0D.sRecvHead != st0D.sRecvTail){  
  1307.             st0D.sRecvHead++;  
  1308.             st0D.sRecvHead %= ST_RECV_LEN;  
  1309.         }  
  1310.         else  
  1311.             break;  
  1312. //      printk("D-:%02X\n", abyRecv[i]);  
  1313.     }  
  1314.     copy_to_user((void *)buf, &abyRecv, i);  
  1315.     return i;  
  1316. }  
  1317.   
  1318. static int ST0D_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1319.       
  1320.     return st16c554_ComWrite(buf,count,&st0D);  
  1321.       
  1322. }  
  1323.   
  1324. static int ST0D_release(struct inode *inode, struct file *filp)  
  1325. {  
  1326.     int nRet = 0;  
  1327.       
  1328.     MOD_DEC_USE_COUNT;  
  1329.     return nRet;  
  1330. }  
  1331.   
  1332.   
  1333.   
  1334.   
  1335. static int ST0E_open(struct inode *inode, struct file *filp)  
  1336. {  
  1337.     int nRet = 0;  
  1338.       
  1339.     MOD_INC_USE_COUNT;  
  1340.     return nRet;  
  1341. }  
  1342.   
  1343. static int ST0E_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1344. {  
  1345.   
  1346.     int nRet = 0;  
  1347.     switch(cmd) {  
  1348.     case ST_INIT:  
  1349.         copy_from_user(&st0E_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1350.         Init_ST0E(st0E_init.nBaud, st0E_init.byMode);  
  1351.         break;    
  1352.     default:  
  1353.         return -EINVAL;  
  1354.     }  
  1355.     return nRet;  
  1356.   
  1357. }  
  1358.   
  1359. static int ST0E_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1360. {  
  1361.     int i;  
  1362.     int nLen;  
  1363.     unsigned char abyRecv[ST_RECV_LEN];  
  1364.     nLen = get_ST0E_rxLen();  
  1365.     nLen = nLen>count ? count : nLen;  
  1366.     for(i=0; i<nLen; i++){  
  1367.         abyRecv[i] = st0E.abyRecvData[st0E.sRecvHead];  
  1368.         if(st0E.sRecvHead != st0E.sRecvTail){  
  1369.             st0E.sRecvHead++;  
  1370.             st0E.sRecvHead %= ST_RECV_LEN;  
  1371.         }  
  1372.         else  
  1373.             break;  
  1374.     }  
  1375.     copy_to_user((void *)buf, &abyRecv, i);  
  1376.     return i;  
  1377. }  
  1378.   
  1379. static int ST0E_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1380.   
  1381.      return st16c554_ComWrite(buf,count,&st0E);  
  1382.       
  1383. }  
  1384.   
  1385. static int ST0E_release(struct inode *inode, struct file *filp)  
  1386. {  
  1387.     int nRet = 0;  
  1388.     MOD_DEC_USE_COUNT;  
  1389.     return nRet;  
  1390. }  
  1391.   
  1392.   
  1393.   
  1394. static int ST0F_open(struct inode *inode, struct file *filp)  
  1395. {  
  1396.     int nRet = 0;  
  1397.     MOD_INC_USE_COUNT;  
  1398.     return nRet;  
  1399. }  
  1400.   
  1401. static int ST0F_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1402. {  
  1403.     int nRet = 0;  
  1404.     switch(cmd) {  
  1405.     case ST_INIT:  
  1406.         copy_from_user(&st0F_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1407.         Init_ST0F(st0F_init.nBaud, st0F_init.byMode);  
  1408.         break;  
  1409.     default:  
  1410.         return -EINVAL;  
  1411.     }  
  1412.     return nRet;  
  1413. }  
  1414.   
  1415. static int ST0F_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1416. {  
  1417.     int i;  
  1418.     int nLen;  
  1419.     unsigned char abyRecv[ST_RECV_LEN];  
  1420.     nLen = get_ST0F_rxLen();  
  1421.     nLen = nLen>count ? count : nLen;  
  1422.     for(i=0; i<nLen; i++){  
  1423.         abyRecv[i] = st0F.abyRecvData[st0F.sRecvHead];  
  1424.         if(st0F.sRecvHead != st0F.sRecvTail){  
  1425.             st0F.sRecvHead++;  
  1426.             st0F.sRecvHead %= ST_RECV_LEN;  
  1427.         }  
  1428.         else  
  1429.             break;  
  1430.     }  
  1431.     copy_to_user((void *)buf, &abyRecv, i);  
  1432.     return i;  
  1433. }  
  1434.   
  1435. static int ST0F_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1436.   
  1437.     return st16c554_ComWrite(buf,count,&st0F);  
  1438.   
  1439. }  
  1440.   
  1441. static int ST0F_release(struct inode *inode, struct file *filp)  
  1442. {  
  1443.     int nRet = 0;  
  1444.     MOD_DEC_USE_COUNT;  
  1445.     return nRet;  
  1446. }  
  1447.   
  1448.   
  1449. static int ST0G_open(struct inode *inode, struct file *filp)  
  1450. {  
  1451.     int nRet = 0;  
  1452.     MOD_INC_USE_COUNT;  
  1453.     return nRet;  
  1454. }  
  1455.   
  1456. static int ST0G_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1457. {  
  1458.     int nRet = 0;  
  1459.     switch(cmd) {  
  1460.     case ST_INIT:  
  1461.         copy_from_user(&st0G_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1462.         Init_ST0G(st0G_init.nBaud, st0G_init.byMode);  
  1463.         break;  
  1464.     default:  
  1465.         return -EINVAL;  
  1466.     }  
  1467.     return nRet;  
  1468. }  
  1469.   
  1470. static int ST0G_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1471. {  
  1472.     int i;  
  1473.     int nLen;  
  1474.     unsigned char abyRecv[ST_RECV_LEN];  
  1475.     nLen = get_ST0G_rxLen();  
  1476.     nLen = nLen>count ? count : nLen;  
  1477.     for(i=0; i<nLen; i++){  
  1478.         abyRecv[i] = st0G.abyRecvData[st0G.sRecvHead];  
  1479.         if(st0G.sRecvHead != st0G.sRecvTail){  
  1480.             st0G.sRecvHead++;  
  1481.             st0G.sRecvHead %= ST_RECV_LEN;  
  1482.         }  
  1483.         else  
  1484.             break;  
  1485.     }  
  1486.     copy_to_user((void *)buf, &abyRecv, i);  
  1487.     return i;  
  1488. }  
  1489.   
  1490. static int ST0G_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1491.   
  1492.     return st16c554_ComWrite(buf,count,&st0G);  
  1493.   
  1494. }  
  1495.   
  1496. static int ST0G_release(struct inode *inode, struct file *filp)  
  1497. {  
  1498.     int nRet = 0;  
  1499.     MOD_DEC_USE_COUNT;  
  1500.     return nRet;  
  1501. }  
  1502.   
  1503. static int ST0H_open(struct inode *inode, struct file *filp)  
  1504. {  
  1505.     int nRet = 0;  
  1506.     MOD_INC_USE_COUNT;  
  1507.     return nRet;  
  1508. }  
  1509.   
  1510. static int ST0H_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)  
  1511. {  
  1512.     int nRet = 0;  
  1513.     switch(cmd) {  
  1514.     case ST_INIT:  
  1515.         copy_from_user(&st0H_init, (struct tagST_INIT *)arg, sizeof(struct tagST_INIT));  
  1516.         Init_ST0H(st0H_init.nBaud, st0H_init.byMode);  
  1517.         break;  
  1518.     default:  
  1519.         return -EINVAL;  
  1520.     }  
  1521.     return nRet;  
  1522. }  
  1523.   
  1524. static int ST0H_read(struct file *filp, char *buf, size_t count, loff_t *ppos)  
  1525. {  
  1526.     int i;  
  1527.     int nLen;  
  1528.     unsigned char abyRecv[ST_RECV_LEN];  
  1529.     nLen = get_ST0H_rxLen();  
  1530.     nLen = nLen>count ? count : nLen;  
  1531.     for(i=0; i<nLen; i++){  
  1532.         abyRecv[i] = st0H.abyRecvData[st0H.sRecvHead];  
  1533.         if(st0H.sRecvHead != st0H.sRecvTail){  
  1534.             st0H.sRecvHead++;  
  1535.             st0H.sRecvHead %= ST_RECV_LEN;  
  1536.         }  
  1537.         else  
  1538.             break;  
  1539. //      printk("D-:%02X\n", abyRecv[i]);  
  1540.     }  
  1541.     copy_to_user((void *)buf, &abyRecv, i);  
  1542.     return i;  
  1543. }  
  1544.   
  1545. static int ST0H_write (struct file *file, const char *buf, size_t count, loff_t *ppos){  
  1546.   
  1547.   
  1548.     return st16c554_ComWrite(buf,count,&st0H);  
  1549.   
  1550. }  
  1551.   
  1552. static int ST0H_release(struct inode *inode, struct file *filp)  
  1553. {  
  1554.     int nRet = 0;  
  1555.       
  1556.     MOD_DEC_USE_COUNT;  
  1557.     return nRet;  
  1558. }  
  1559.   
  1560.   
  1561.   
  1562.   
  1563. static struct file_operations st16c554_fops = {  
  1564.     owner:  THIS_MODULE,  
  1565.     open:   st16c554_open,  
  1566.     ioctl:  st16c554_ioctl,  
  1567.     read:   st16c554_read,  
  1568.     release:    st16c554_release,  
  1569. };  
  1570.   
  1571. static struct file_operations ST0A_fops = {  
  1572.     owner:  THIS_MODULE,  
  1573.     open:   ST0A_open,  
  1574.     ioctl:  ST0A_ioctl,  
  1575.     read:   ST0A_read,  
  1576.     write:  ST0A_write,  
  1577.     release:    ST0A_release,  
  1578. };  
  1579.   
  1580. static struct file_operations ST0B_fops = {  
  1581.     owner:  THIS_MODULE,  
  1582.     open:   ST0B_open,  
  1583.     ioctl:  ST0B_ioctl,  
  1584.     read:   ST0B_read,  
  1585.     write:  ST0B_write,  
  1586.     release:    ST0B_release,  
  1587. };  
  1588.   
  1589. static struct file_operations ST0C_fops = {  
  1590.     owner:  THIS_MODULE,  
  1591.     open:   ST0C_open,  
  1592.     ioctl:  ST0C_ioctl,  
  1593.     read:   ST0C_read,  
  1594.     write:  ST0C_write,  
  1595.     release:    ST0C_release,  
  1596. };  
  1597.   
  1598. static struct file_operations ST0D_fops = {  
  1599.     owner:  THIS_MODULE,  
  1600.     open:   ST0D_open,  
  1601.     ioctl:  ST0D_ioctl,  
  1602.     read:   ST0D_read,  
  1603.     write:  ST0D_write,  
  1604.     release:    ST0D_release,  
  1605. };  
  1606.   
  1607. static struct file_operations ST0E_fops = {  
  1608.     owner:  THIS_MODULE,  
  1609.     open:   ST0E_open,  
  1610.     ioctl:  ST0E_ioctl,  
  1611.     read:   ST0E_read,  
  1612.     write:  ST0E_write,  
  1613.     release:    ST0E_release,  
  1614. };  
  1615.   
  1616. static struct file_operations ST0F_fops = {  
  1617.     owner:  THIS_MODULE,  
  1618.     open:   ST0F_open,  
  1619.     ioctl:  ST0F_ioctl,  
  1620.     read:   ST0F_read,  
  1621.     write:  ST0F_write,  
  1622.     release:    ST0F_release,  
  1623. };  
  1624.   
  1625. static struct file_operations ST0G_fops = {  
  1626.     owner:  THIS_MODULE,  
  1627.     open:   ST0G_open,  
  1628.     ioctl:  ST0G_ioctl,  
  1629.     read:   ST0G_read,  
  1630.     write:  ST0G_write,  
  1631.     release:    ST0G_release,  
  1632. };  
  1633.   
  1634. static struct file_operations ST0H_fops = {  
  1635.     owner:  THIS_MODULE,  
  1636.     open:   ST0H_open,  
  1637.     ioctl:  ST0H_ioctl,  
  1638.     read:   ST0H_read,  
  1639.     write:  ST0H_write,  
  1640.     release:    ST0H_release,  
  1641. };  
  1642.   
  1643.   
  1644. static devfs_handle_t devfs_st_dir, devfs_ST0A, devfs_ST0B, devfs_ST0C, devfs_ST0D;  
  1645. static devfs_handle_t devfs_ST0E, devfs_ST0F, devfs_ST0G, devfs_ST0H;  
  1646.   
  1647. static int __init st16c554_init(void)  
  1648. {  
  1649.     int ret;  
  1650.       printk(KERN_INFO "Init ST16C554 ......\n" );  
  1651.       mtdcr(DCRN_EBC0_CFGADDR, DCRN_EBC0_B3CR);       
  1652.       printk(KERN_INFO "B3CR1=== %x\n",mfdcr(DCRN_EBC0_CFGDATA) );       
  1653.       mtdcr(DCRN_EBC0_CFGDATA, 0xf0218000);  //SET PCS3 BASEADDR     
  1654.       printk(KERN_INFO "B3CR2== %x\n",mfdcr(DCRN_EBC0_CFGDATA) );  
  1655.       
  1656.     ret = register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &st16c554_fops);  
  1657.     if (ret < 0) {  
  1658.       printk(DEVICE_NAME " can't get major number\n");  
  1659.       return ret;  
  1660.     }  
  1661.     stMajor = ret;  
  1662.       
  1663.     devfs_st_dir = devfs_mk_dir(NULL, DEVICE_NAME, NULL);  
  1664.     if (devfs_st_dir == NULL)  
  1665.         printk( " devfs_mk_dir() error! \n");  
  1666.     devfs_ST0A = devfs_register(devfs_st_dir, "0", DEVFS_FL_DEFAULT,     // dev/st16c554/0 for ST0A  
  1667.             stMajor, ST0A, S_IFCHR | S_IRUSR | S_IWUSR,  
  1668.             &ST0A_fops, NULL);  
  1669.     devfs_ST0B = devfs_register(devfs_st_dir, "1", DEVFS_FL_DEFAULT,     // dev/st16c554/1 for ST0B  
  1670.             stMajor, ST0B, S_IFCHR | S_IRUSR | S_IWUSR,  
  1671.             &ST0B_fops, NULL);  
  1672.     devfs_ST0C = devfs_register(devfs_st_dir, "2", DEVFS_FL_DEFAULT,     // dev/st16c554/2 for ST0C  
  1673.             stMajor, ST0C, S_IFCHR | S_IRUSR | S_IWUSR,  
  1674.             &ST0C_fops, NULL);  
  1675.     devfs_ST0D = devfs_register(devfs_st_dir, "3", DEVFS_FL_DEFAULT,     // dev/st16c554/3 for ST0D  
  1676.             stMajor, ST0D, S_IFCHR | S_IRUSR | S_IWUSR,  
  1677.             &ST0D_fops, NULL);   
  1678.               
  1679.     devfs_ST0E = devfs_register(devfs_st_dir, "4", DEVFS_FL_DEFAULT,     // dev/st16c554/4 for ST0E  
  1680.             stMajor, ST0E, S_IFCHR | S_IRUSR | S_IWUSR,  
  1681.             &ST0E_fops, NULL);  
  1682.     devfs_ST0F = devfs_register(devfs_st_dir, "5", DEVFS_FL_DEFAULT,     // dev/st16c554/5 for ST0F  
  1683.             stMajor, ST0F, S_IFCHR | S_IRUSR | S_IWUSR,  
  1684.             &ST0F_fops, NULL);  
  1685.     devfs_ST0G = devfs_register(devfs_st_dir, "6", DEVFS_FL_DEFAULT,     // dev/st16c554/6 for ST0G  
  1686.             stMajor, ST0G, S_IFCHR | S_IRUSR | S_IWUSR,  
  1687.             &ST0G_fops, NULL);  
  1688.     devfs_ST0H = devfs_register(devfs_st_dir, "7", DEVFS_FL_DEFAULT,     // dev/st16c554/7 for ST0H  
  1689.             stMajor, ST0H, S_IFCHR | S_IRUSR | S_IWUSR,  
  1690.             &ST0H_fops, NULL);   
  1691.       
  1692.     ret = request_irq(YC_mul232_IRQ0, UART0_interrupt, SA_INTERRUPT, "ST16C554_0_RX Ready", UART0_interrupt);  
  1693.     if(ret) {  
  1694.         printk("ST16C554: failed to register IRQ_EINT0(%d)\n", YC_mul232_IRQ0);  
  1695.         goto UART0_failed;  
  1696.     }  
  1697.       
  1698.     ret = request_irq(YC_mul232_IRQ1, UART1_interrupt, SA_INTERRUPT, "ST16C554_1_RX Ready", UART1_interrupt);  
  1699.     if(ret) {  
  1700.         printk("ST16C554: failed to register IRQ_EINT1(%d)\n", YC_mul232_IRQ1);  
  1701.         goto UART1_failed;  
  1702.     }  
  1703.     
  1704.     return 0;  
  1705. UART1_failed:  
  1706.     free_irq(YC_mul232_IRQ1, NULL);       
  1707. UART0_failed:  
  1708.     printk("ST16C554 DEVICE: failed to register \n");  
  1709.     devfs_unregister(devfs_ST0D);  
  1710.     devfs_unregister(devfs_ST0C);  
  1711.     devfs_unregister(devfs_ST0B);  
  1712.     devfs_unregister(devfs_ST0A);  
  1713.     devfs_unregister(devfs_ST0E);  
  1714.     devfs_unregister(devfs_ST0F);  
  1715.     devfs_unregister(devfs_ST0G);  
  1716.     devfs_unregister(devfs_ST0H);  
  1717.     devfs_unregister(devfs_st_dir);  
  1718.     unregister_chrdev(stMajor, DEVICE_NAME);  
  1719.     return 0;  
  1720. }  
  1721.   
  1722. static void __exit st16c554_exit(void)  
  1723. {  
  1724.     free_irq(YC_mul232_IRQ0, NULL);  
  1725.     free_irq(YC_mul232_IRQ1, NULL);  
  1726.       
  1727.     devfs_unregister(devfs_ST0D);  
  1728.     devfs_unregister(devfs_ST0C);  
  1729.     devfs_unregister(devfs_ST0B);  
  1730.     devfs_unregister(devfs_ST0A);  
  1731.     devfs_unregister(devfs_ST0E);  
  1732.     devfs_unregister(devfs_ST0F);  
  1733.     devfs_unregister(devfs_ST0G);  
  1734.     devfs_unregister(devfs_ST0H);  
  1735.     devfs_unregister(devfs_st_dir);  
  1736.     unregister_chrdev(stMajor, DEVICE_NAME);  
  1737.   
  1738.     iounmap((void *) (st0A.pbyBase0));  
  1739.   
  1740.     iounmap((void *) (st0B.pbyBase0));  
  1741.   
  1742.     iounmap((void *) (st0C.pbyBase0));  
  1743.   
  1744.     iounmap((void *) (st0D.pbyBase0));  
  1745.   
  1746.     iounmap((void *) (st0E.pbyBase0));  
  1747.   
  1748.     iounmap((void *) (st0F.pbyBase0));  
  1749.   
  1750.     iounmap((void *) (st0G.pbyBase0));  
  1751.   
  1752.     iounmap((void *) (st0H.pbyBase0));  
  1753.   
  1754. }  
  1755.   
  1756. module_init(st16c554_init);  
  1757. module_exit(st16c554_exit);  
 

posted on 2015-11-11 16:40  嵌入式操作系统  阅读(731)  评论(0编辑  收藏  举报

导航