1/* 2 dstr.c (c) 1997-8 Grant R. Guenther <grant@torque.net> 3 Under the terms of the GNU General Public License. 4 5 dstr.c is a low-level protocol driver for the 6 DataStor EP2000 parallel to IDE adapter chip. 7 8*/ 9 10/* Changes: 11 12 1.01 GRG 1998.05.06 init_proto, release_proto 13 14*/ 15 16#define DSTR_VERSION "1.01" 17 18#include <linux/module.h> 19#include <linux/delay.h> 20#include <linux/kernel.h> 21#include <linux/types.h> 22#include <linux/wait.h> 23#include <asm/io.h> 24 25#include "paride.h" 26 27/* mode codes: 0 nybble reads, 8-bit writes 28 1 8-bit reads and writes 29 2 8-bit EPP mode 30 3 EPP-16 31 4 EPP-32 32*/ 33 34#define j44(a,b) (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80)) 35 36#define P1 w2(5);w2(0xd);w2(5);w2(4); 37#define P2 w2(5);w2(7);w2(5);w2(4); 38#define P3 w2(6);w2(4);w2(6);w2(4); 39 40/* cont = 0 - access the IDE register file 41 cont = 1 - access the IDE command set 42*/ 43 44static int cont_map[2] = { 0x20, 0x40 }; 45 46static int dstr_read_regr( PIA *pi, int cont, int regr ) 47 48{ int a, b, r; 49 50 r = regr + cont_map[cont]; 51 52 w0(0x81); P1; 53 if (pi->mode) { w0(0x11); } else { w0(1); } 54 P2; w0(r); P1; 55 56 switch (pi->mode) { 57 58 case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4); 59 return j44(a,b); 60 61 case 1: w0(0); w2(0x26); a = r0(); w2(4); 62 return a; 63 64 case 2: 65 case 3: 66 case 4: w2(0x24); a = r4(); w2(4); 67 return a; 68 69 } 70 return -1; 71} 72 73static void dstr_write_regr( PIA *pi, int cont, int regr, int val ) 74 75{ int r; 76 77 r = regr + cont_map[cont]; 78 79 w0(0x81); P1; 80 if (pi->mode >= 2) { w0(0x11); } else { w0(1); } 81 P2; w0(r); P1; 82 83 switch (pi->mode) { 84 85 case 0: 86 case 1: w0(val); w2(5); w2(7); w2(5); w2(4); 87 break; 88 89 case 2: 90 case 3: 91 case 4: w4(val); 92 break; 93 } 94} 95 96#define CCP(x) w0(0xff);w2(0xc);w2(4);\ 97 w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\ 98 w0(x);w2(5);w2(4); 99 100static void dstr_connect ( PIA *pi ) 101 102{ pi->saved_r0 = r0(); 103 pi->saved_r2 = r2(); 104 w2(4); CCP(0xe0); w0(0xff); 105} 106 107static void dstr_disconnect ( PIA *pi ) 108 109{ CCP(0x30); 110 w0(pi->saved_r0); 111 w2(pi->saved_r2); 112} 113 114static void dstr_read_block( PIA *pi, char * buf, int count ) 115 116{ int k, a, b; 117 118 w0(0x81); P1; 119 if (pi->mode) { w0(0x19); } else { w0(9); } 120 P2; w0(0x82); P1; P3; w0(0x20); P1; 121 122 switch (pi->mode) { 123 124 case 0: for (k=0;k<count;k++) { 125 w2(6); a = r1(); w2(4); 126 w2(6); b = r1(); w2(4); 127 buf[k] = j44(a,b); 128 } 129 break; 130 131 case 1: w0(0); 132 for (k=0;k<count;k++) { 133 w2(0x26); buf[k] = r0(); w2(0x24); 134 } 135 w2(4); 136 break; 137 138 case 2: w2(0x24); 139 for (k=0;k<count;k++) buf[k] = r4(); 140 w2(4); 141 break; 142 143 case 3: w2(0x24); 144 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); 145 w2(4); 146 break; 147 148 case 4: w2(0x24); 149 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); 150 w2(4); 151 break; 152 153 } 154} 155 156static void dstr_write_block( PIA *pi, char * buf, int count ) 157 158{ int k; 159 160 w0(0x81); P1; 161 if (pi->mode) { w0(0x19); } else { w0(9); } 162 P2; w0(0x82); P1; P3; w0(0x20); P1; 163 164 switch (pi->mode) { 165 166 case 0: 167 case 1: for (k=0;k<count;k++) { 168 w2(5); w0(buf[k]); w2(7); 169 } 170 w2(5); w2(4); 171 break; 172 173 case 2: w2(0xc5); 174 for (k=0;k<count;k++) w4(buf[k]); 175 w2(0xc4); 176 break; 177 178 case 3: w2(0xc5); 179 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); 180 w2(0xc4); 181 break; 182 183 case 4: w2(0xc5); 184 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); 185 w2(0xc4); 186 break; 187 188 } 189} 190 191 192static void dstr_log_adapter( PIA *pi, char * scratch, int verbose ) 193 194{ char *mode_string[5] = {"4-bit","8-bit","EPP-8", 195 "EPP-16","EPP-32"}; 196 197 printk("%s: dstr %s, DataStor EP2000 at 0x%x, ", 198 pi->device,DSTR_VERSION,pi->port); 199 printk("mode %d (%s), delay %d\n",pi->mode, 200 mode_string[pi->mode],pi->delay); 201 202} 203 204static void dstr_init_proto( PIA *pi) 205 206{ MOD_INC_USE_COUNT; 207} 208 209static void dstr_release_proto( PIA *pi) 210 211{ MOD_DEC_USE_COUNT; 212} 213 214struct pi_protocol dstr = {"dstr",0,5,2,1,1, 215 dstr_write_regr, 216 dstr_read_regr, 217 dstr_write_block, 218 dstr_read_block, 219 dstr_connect, 220 dstr_disconnect, 221 0, 222 0, 223 0, 224 dstr_log_adapter, 225 dstr_init_proto, 226 dstr_release_proto 227 }; 228 229 230#ifdef MODULE 231 232int init_module(void) 233 234{ return pi_register( &dstr ) - 1; 235} 236 237void cleanup_module(void) 238 239{ pi_unregister( &dstr ); 240} 241 242#endif 243 244/* end of dstr.c */ 245MODULE_LICENSE("GPL"); 246