11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fit2.c (c) 1998 Grant R. Guenther <grant@torque.net> 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Under the terms of the GNU General Public License. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fit2.c is a low-level protocol driver for the older version 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds of the Fidelity International Technology parallel port adapter. 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This adapter is used in their TransDisk 2000 and older TransDisk 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3000 portable hard-drives. As far as I can tell, this device 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds supports 4-bit mode _only_. 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Newer models of the FIT products use an enhanced protocol. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds The "fit3" protocol module should support current drives. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define FIT2_VERSION "1.0" 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/wait.h> 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "paride.h" 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* cont = 0 - access the IDE register file 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cont = 1 - access the IDE command set 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsNB: The FIT adapter does not appear to use the control registers. 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsSo, we map ALT_STATUS to STATUS and NO-OP writes to the device 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldscontrol register - this means that IDE reset will not work on these 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsdevices. 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fit2_write_regr( PIA *pi, int cont, int regr, int val) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ if (cont == 1) return; 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(0xc); w0(regr); w2(4); w0(val); w2(5); w0(0); w2(4); 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int fit2_read_regr( PIA *pi, int cont, int regr ) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ int a, b, r; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (cont) { 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (regr != 6) return 0xff; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = 7; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else r = regr + 0x10; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(0xc); w0(r); w2(4); w2(5); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w0(0); a = r1(); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w0(1); b = r1(); 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(4); 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return j44(a,b); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fit2_read_block( PIA *pi, char * buf, int count ) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ int k, a, b, c, d; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(0xc); w0(0x10); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k=0;k<count/4;k++) { 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(4); w2(5); 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w0(0); a = r1(); w0(1); b = r1(); 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w0(3); c = r1(); w0(2); d = r1(); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4*k+0] = j44(a,b); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4*k+1] = j44(d,c); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(4); w2(5); 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds a = r1(); w0(3); b = r1(); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w0(1); c = r1(); w0(0); d = r1(); 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4*k+2] = j44(d,c); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4*k+3] = j44(a,b); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(4); 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fit2_write_block( PIA *pi, char * buf, int count ) 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ int k; 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(0xc); w0(0); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (k=0;k<count/2;k++) { 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(4); w0(buf[2*k]); 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(5); w0(buf[2*k+1]); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(4); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fit2_connect ( PIA *pi ) 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ pi->saved_r0 = r0(); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pi->saved_r2 = r2(); 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(0xcc); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fit2_disconnect ( PIA *pi ) 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ w0(pi->saved_r0); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w2(pi->saved_r2); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void fit2_log_adapter( PIA *pi, char * scratch, int verbose ) 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ printk("%s: fit2 %s, FIT 2000 adapter at 0x%x, delay %d\n", 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pi->device,FIT2_VERSION,pi->port,pi->delay); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pi_protocol fit2 = { 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "fit2", 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .max_mode = 1, 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .epp_first = 2, 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .default_delay = 1, 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .max_units = 1, 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write_regr = fit2_write_regr, 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_regr = fit2_read_regr, 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write_block = fit2_write_block, 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_block = fit2_read_block, 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .connect = fit2_connect, 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .disconnect = fit2_disconnect, 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .log_adapter = fit2_log_adapter, 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init fit2_init(void) 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 141b4178ab58aa81f4ed3c75c48940682fe3b45d880Alexey Dobriyan return paride_register(&fit2); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit fit2_exit(void) 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 146f4330002d11f032559954cbff68a5cad95b6d27fAlexey Dobriyan paride_unregister(&fit2); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(fit2_init) 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(fit2_exit) 152