epia.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.         epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  3.                               Under the terms of the GNU General Public License.
  4.         epia.c is a low-level protocol driver for Shuttle Technologies 
  5. EPIA parallel to IDE adapter chip.  This device is now obsolete
  6. and has been replaced with the EPAT chip, which is supported
  7. by epat.c, however, some devices based on EPIA are still
  8. available.
  9. */
  10. /* Changes:
  11.         1.01    GRG 1998.05.06 init_proto, release_proto
  12. 1.02    GRG 1998.06.17 support older versions of EPIA
  13. */
  14. #define EPIA_VERSION      "1.02"
  15. #include <linux/module.h>
  16. #include <linux/delay.h>
  17. #include <linux/kernel.h>
  18. #include <linux/types.h>
  19. #include <linux/wait.h>
  20. #include <asm/io.h>
  21. #include "paride.h"
  22. /* mode codes:  0  nybble reads on port 1, 8-bit writes
  23.                 1  5/3 reads on ports 1 & 2, 8-bit writes
  24.                 2  8-bit reads and writes
  25.                 3  8-bit EPP mode
  26. 4  16-bit EPP
  27. 5  32-bit EPP
  28. */
  29. #define j44(a,b)                (((a>>4)&0x0f)+(b&0xf0))
  30. #define j53(a,b)                (((a>>3)&0x1f)+((b<<4)&0xe0))
  31. /* cont =  0   IDE register file
  32.    cont =  1   IDE control registers
  33. */
  34. static int cont_map[2] = { 0, 0x80 };
  35. static int epia_read_regr( PIA *pi, int cont, int regr )
  36. {       int     a, b, r;
  37. regr += cont_map[cont];
  38.         switch (pi->mode)  {
  39.         case 0: r = regr^0x39;
  40.                 w0(r); w2(1); w2(3); w0(r);
  41.                 a = r1(); w2(1); b = r1(); w2(4);
  42.                 return j44(a,b);
  43.         case 1: r = regr^0x31;
  44.                 w0(r); w2(1); w0(r&0x37); 
  45.                 w2(3); w2(5); w0(r|0xf0);
  46.                 a = r1(); b = r2(); w2(4);
  47.                 return j53(a,b);
  48.         case 2: r = regr^0x29;
  49.                 w0(r); w2(1); w2(0X21); w2(0x23); 
  50.                 a = r0(); w2(4);
  51.                 return a;
  52. case 3:
  53. case 4:
  54.         case 5: w3(regr); w2(0x24); a = r4(); w2(4);
  55.                 return a;
  56.         }
  57.         return -1;
  58. }       
  59. static void epia_write_regr( PIA *pi, int cont, int regr, int val)
  60. {       int  r;
  61. regr += cont_map[cont];
  62.         switch (pi->mode)  {
  63.         case 0:
  64.         case 1:
  65.         case 2: r = regr^0x19;
  66.                 w0(r); w2(1); w0(val); w2(3); w2(4);
  67.                 break;
  68. case 3:
  69. case 4:
  70.         case 5: r = regr^0x40;
  71.                 w3(r); w4(val); w2(4);
  72.                 break;
  73.         }
  74. }
  75. #define WR(r,v)         epia_write_regr(pi,0,r,v)
  76. #define RR(r)           (epia_read_regr(pi,0,r))
  77. /* The use of register 0x84 is entirely unclear - it seems to control
  78.    some EPP counters ...  currently we know about 3 different block
  79.    sizes:  the standard 512 byte reads and writes, 12 byte writes and 
  80.    2048 byte reads (the last two being used in the CDrom drivers.
  81. */
  82. static void epia_connect ( PIA *pi  )
  83. {       pi->saved_r0 = r0();
  84.         pi->saved_r2 = r2();
  85.         w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
  86.         w2(1); w2(4);
  87.         if (pi->mode >= 3) { 
  88.                 w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
  89.                 w2(0x24); w2(0x26); w2(4);
  90.         }
  91.         WR(0x86,8);  
  92. }
  93. static void epia_disconnect ( PIA *pi )
  94. {       /* WR(0x84,0x10); */
  95.         w0(pi->saved_r0);
  96.         w2(1); w2(4);
  97.         w0(pi->saved_r0);
  98.         w2(pi->saved_r2);
  99. static void epia_read_block( PIA *pi, char * buf, int count )
  100. {       int     k, ph, a, b;
  101.         switch (pi->mode) {
  102.         case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
  103.                 ph = 1;
  104.                 for (k=0;k<count;k++) {
  105.                         w2(2+ph); a = r1();
  106.                         w2(4+ph); b = r1();
  107.                         buf[k] = j44(a,b);
  108.                         ph = 1 - ph;
  109.                 } 
  110.                 w0(0); w2(4);
  111.                 break;
  112.         case 1: w0(0x91); w2(1); w0(0x10); w2(3); 
  113.                 w0(0x51); w2(5); w0(0xd1); 
  114.                 ph = 1;
  115.                 for (k=0;k<count;k++) {
  116.                         w2(4+ph);
  117.                         a = r1(); b = r2();
  118.                         buf[k] = j53(a,b);
  119.                         ph = 1 - ph;
  120.                 }
  121.                 w0(0); w2(4);
  122.                 break;
  123.         case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); 
  124.                 ph = 1;
  125.                 for (k=0;k<count;k++) {
  126.                         w2(0x24+ph);
  127.                         buf[k] = r0();
  128.                         ph = 1 - ph;
  129.                 }
  130.                 w2(6); w2(4);
  131.                 break;
  132.         case 3: if (count > 512) WR(0x84,3);
  133. w3(0); w2(0x24);
  134.                 for (k=0;k<count;k++) buf[k] = r4();
  135.                 w2(4); WR(0x84,0);
  136.                 break;
  137.         case 4: if (count > 512) WR(0x84,3);
  138. w3(0); w2(0x24);
  139. for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
  140.                 w2(4); WR(0x84,0);
  141.                 break;
  142.         case 5: if (count > 512) WR(0x84,3);
  143. w3(0); w2(0x24);
  144.                 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
  145.                 w2(4); WR(0x84,0);
  146.                 break;
  147.         }
  148. }
  149. static void epia_write_block( PIA *pi, char * buf, int count )
  150. {       int     ph, k, last, d;
  151.         switch (pi->mode) {
  152.         case 0:
  153.         case 1:
  154.         case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
  155.                 ph = 0;  last = 0x8000;
  156.                 for (k=0;k<count;k++) {
  157.                         d = buf[k];
  158.                         if (d != last) { last = d; w0(d); }
  159.                         w2(4+ph);
  160.                         ph = 1 - ph;
  161.                 }
  162.                 w2(7); w2(4);
  163.                 break;
  164.         case 3: if (count < 512) WR(0x84,1);
  165. w3(0x40);
  166.                 for (k=0;k<count;k++) w4(buf[k]);
  167. if (count < 512) WR(0x84,0);
  168.                 break;
  169.         case 4: if (count < 512) WR(0x84,1);
  170. w3(0x40);
  171.                 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
  172. if (count < 512) WR(0x84,0);
  173.                 break;
  174.         case 5: if (count < 512) WR(0x84,1);
  175. w3(0x40);
  176.                 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
  177. if (count < 512) WR(0x84,0);
  178.                 break;
  179.         }
  180. }
  181. static int epia_test_proto( PIA *pi, char * scratch, int verbose )
  182. {       int     j, k, f;
  183. int e[2] = {0,0};
  184.         epia_connect(pi);
  185.         for (j=0;j<2;j++) {
  186.             WR(6,0xa0+j*0x10);
  187.             for (k=0;k<256;k++) {
  188.                 WR(2,k^0xaa);
  189.                 WR(3,k^0x55);
  190.                 if (RR(2) != (k^0xaa)) e[j]++;
  191.                 }
  192.     WR(2,1); WR(3,1);
  193.             }
  194.         epia_disconnect(pi);
  195.         f = 0;
  196.         epia_connect(pi);
  197.         WR(0x84,8);
  198.         epia_read_block(pi,scratch,512);
  199.         for (k=0;k<256;k++) {
  200.             if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
  201.             if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
  202.         }
  203.         WR(0x84,0);
  204.         epia_disconnect(pi);
  205.         if (verbose)  {
  206.             printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)n",
  207.                    pi->device,pi->port,pi->mode,e[0],e[1],f);
  208.         }
  209.         
  210.         return (e[0] && e[1]) || f;
  211. }
  212. static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
  213. {       char    *mode_string[6] = {"4-bit","5/3","8-bit",
  214.    "EPP-8","EPP-16","EPP-32"};
  215.         printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
  216.                 pi->device,EPIA_VERSION,pi->port);
  217.         printk("mode %d (%s), delay %dn",pi->mode,
  218. mode_string[pi->mode],pi->delay);
  219. }
  220. static void epia_init_proto( PIA *pi)
  221. {       MOD_INC_USE_COUNT;
  222. }
  223. static void epia_release_proto( PIA *pi)
  224. {       MOD_DEC_USE_COUNT;
  225. }
  226. struct pi_protocol epia = {"epia",0,6,3,1,1,
  227.                            epia_write_regr,
  228.                            epia_read_regr,
  229.                            epia_write_block,
  230.                            epia_read_block,
  231.                            epia_connect,
  232.                            epia_disconnect,
  233.                            0,
  234.                            0,
  235.                            epia_test_proto,
  236.                            epia_log_adapter,
  237.                            epia_init_proto,
  238.                            epia_release_proto
  239.                           };
  240. #ifdef MODULE
  241. int     init_module(void)
  242. {       return pi_register( &epia ) - 1;
  243. }
  244. void    cleanup_module(void)
  245. {       pi_unregister( &epia );
  246. }
  247. #endif
  248. /* end of epia.c */
  249. MODULE_LICENSE("GPL");