cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

comm.c (4950B)


      1/* 
      2        comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
      3                              Under the terms of the GNU General Public License.
      4
      5	comm.c is a low-level protocol driver for some older models
      6	of the DataStor "Commuter" parallel to IDE adapter.  Some of
      7	the parallel port devices marketed by Arista currently
      8	use this adapter.
      9*/
     10
     11/* Changes:
     12
     13	1.01	GRG 1998.05.05  init_proto, release_proto
     14
     15*/
     16
     17#define COMM_VERSION      "1.01"
     18
     19#include <linux/module.h>
     20#include <linux/init.h>
     21#include <linux/delay.h>
     22#include <linux/kernel.h>
     23#include <linux/types.h>
     24#include <linux/wait.h>
     25#include <asm/io.h>
     26
     27#include "paride.h"
     28
     29/* mode codes:  0  nybble reads, 8-bit writes
     30                1  8-bit reads and writes
     31                2  8-bit EPP mode
     32*/
     33
     34#define j44(a,b)	(((a>>3)&0x0f)|((b<<1)&0xf0))
     35
     36#define P1	w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
     37#define P2	w2(5);w2(7);w2(7);w2(5);w2(4);
     38
     39/* cont = 0 - access the IDE register file 
     40   cont = 1 - access the IDE command set 
     41*/
     42
     43static int  cont_map[2] = { 0x08, 0x10 };
     44
     45static int comm_read_regr( PIA *pi, int cont, int regr )
     46
     47{       int     l, h, r;
     48
     49        r = regr + cont_map[cont];
     50
     51        switch (pi->mode)  {
     52
     53        case 0: w0(r); P1; w0(0);
     54        	w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
     55                return j44(l,h);
     56
     57        case 1: w0(r+0x20); P1; 
     58        	w0(0); w2(0x26); h = r0(); w2(4);
     59                return h;
     60
     61	case 2:
     62	case 3:
     63        case 4: w3(r+0x20); (void)r1();
     64        	w2(0x24); h = r4(); w2(4);
     65                return h;
     66
     67        }
     68        return -1;
     69}       
     70
     71static void comm_write_regr( PIA *pi, int cont, int regr, int val )
     72
     73{       int  r;
     74
     75        r = regr + cont_map[cont];
     76
     77        switch (pi->mode)  {
     78
     79        case 0:
     80        case 1: w0(r); P1; w0(val); P2;
     81		break;
     82
     83	case 2:
     84	case 3:
     85        case 4: w3(r); (void)r1(); w4(val);
     86                break;
     87        }
     88}
     89
     90static void comm_connect ( PIA *pi  )
     91
     92{       pi->saved_r0 = r0();
     93        pi->saved_r2 = r2();
     94        w2(4); w0(0xff); w2(6);
     95        w2(4); w0(0xaa); w2(6);
     96        w2(4); w0(0x00); w2(6);
     97        w2(4); w0(0x87); w2(6);
     98        w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
     99}
    100
    101static void comm_disconnect ( PIA *pi )
    102
    103{       w2(0); w2(0); w2(0); w2(4); 
    104	w0(pi->saved_r0);
    105        w2(pi->saved_r2);
    106} 
    107
    108static void comm_read_block( PIA *pi, char * buf, int count )
    109
    110{       int     i, l, h;
    111
    112        switch (pi->mode) {
    113        
    114        case 0: w0(0x48); P1;
    115                for(i=0;i<count;i++) {
    116                        w0(0); w2(6); l = r1();
    117                        w0(0x80); h = r1(); w2(4);
    118                        buf[i] = j44(l,h);
    119                }
    120                break;
    121
    122        case 1: w0(0x68); P1; w0(0);
    123                for(i=0;i<count;i++) {
    124                        w2(0x26); buf[i] = r0(); w2(0x24);
    125                }
    126		w2(4);
    127		break;
    128		
    129	case 2: w3(0x68); (void)r1(); w2(0x24);
    130		for (i=0;i<count;i++) buf[i] = r4();
    131		w2(4);
    132		break;
    133
    134        case 3: w3(0x68); (void)r1(); w2(0x24);
    135                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
    136                w2(4);
    137                break;
    138
    139        case 4: w3(0x68); (void)r1(); w2(0x24);
    140                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
    141                w2(4);
    142                break;
    143		
    144	}
    145}
    146
    147/* NB: Watch out for the byte swapped writes ! */
    148
    149static void comm_write_block( PIA *pi, char * buf, int count )
    150
    151{       int	k;
    152
    153        switch (pi->mode) {
    154
    155        case 0:
    156        case 1: w0(0x68); P1;
    157        	for (k=0;k<count;k++) {
    158                        w2(5); w0(buf[k^1]); w2(7);
    159                }
    160                w2(5); w2(4);
    161                break;
    162
    163        case 2: w3(0x48); (void)r1();
    164                for (k=0;k<count;k++) w4(buf[k^1]);
    165                break;
    166
    167        case 3: w3(0x48); (void)r1();
    168                for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
    169                break;
    170
    171        case 4: w3(0x48); (void)r1();
    172                for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
    173                break;
    174
    175
    176        }
    177}
    178
    179static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
    180
    181{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
    182
    183        printk("%s: comm %s, DataStor Commuter at 0x%x, ",
    184                pi->device,COMM_VERSION,pi->port);
    185        printk("mode %d (%s), delay %d\n",pi->mode,
    186		mode_string[pi->mode],pi->delay);
    187
    188}
    189
    190static struct pi_protocol comm = {
    191	.owner		= THIS_MODULE,
    192	.name		= "comm",
    193	.max_mode	= 5,
    194	.epp_first	= 2,
    195	.default_delay	= 1,
    196	.max_units	= 1,
    197	.write_regr	= comm_write_regr,
    198	.read_regr	= comm_read_regr,
    199	.write_block	= comm_write_block,
    200	.read_block	= comm_read_block,
    201	.connect	= comm_connect,
    202	.disconnect	= comm_disconnect,
    203	.log_adapter	= comm_log_adapter,
    204};
    205
    206static int __init comm_init(void)
    207{
    208	return paride_register(&comm);
    209}
    210
    211static void __exit comm_exit(void)
    212{
    213	paride_unregister(&comm);
    214}
    215
    216MODULE_LICENSE("GPL");
    217module_init(comm_init)
    218module_exit(comm_exit)