diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-02-15 02:15:32 +0000 |
commit | 86464aed71025541805e7b1515541aee89879e33 (patch) | |
tree | e01a457a4912a8553bc65524aa3125d51f29f810 /drivers/block/paride | |
parent | 88f99939ecc6a95a79614574cb7d95ffccfc3466 (diff) |
Merge with Linux 2.2.1.
Diffstat (limited to 'drivers/block/paride')
-rw-r--r-- | drivers/block/paride/Config.in | 1 | ||||
-rw-r--r-- | drivers/block/paride/Makefile | 9 | ||||
-rw-r--r-- | drivers/block/paride/friq.c | 282 | ||||
-rw-r--r-- | drivers/block/paride/frpw.c | 11 | ||||
-rw-r--r-- | drivers/block/paride/jumbo | 8 | ||||
-rw-r--r-- | drivers/block/paride/on26.c | 23 | ||||
-rw-r--r-- | drivers/block/paride/paride.c | 8 | ||||
-rw-r--r-- | drivers/block/paride/pg.c | 8 | ||||
-rw-r--r-- | drivers/block/paride/pseudo.h | 22 | ||||
-rw-r--r-- | drivers/block/paride/pt.c | 2 |
10 files changed, 347 insertions, 27 deletions
diff --git a/drivers/block/paride/Config.in b/drivers/block/paride/Config.in index 00dd9c8e4..8d4dc1742 100644 --- a/drivers/block/paride/Config.in +++ b/drivers/block/paride/Config.in @@ -16,6 +16,7 @@ dep_tristate ' FIT TD-2000 protocol' CONFIG_PARIDE_FIT2 $CONFIG_PARIDE dep_tristate ' FIT TD-3000 protocol' CONFIG_PARIDE_FIT3 $CONFIG_PARIDE dep_tristate ' Shuttle EPAT/EPEZ protocol' CONFIG_PARIDE_EPAT $CONFIG_PARIDE dep_tristate ' Shuttle EPIA protocol' CONFIG_PARIDE_EPIA $CONFIG_PARIDE +dep_tristate ' Freecom IQ ASIC-2 protocol' CONFIG_PARIDE_FRIQ $CONFIG_PARIDE dep_tristate ' FreeCom power protocol' CONFIG_PARIDE_FRPW $CONFIG_PARIDE dep_tristate ' KingByte KBIC-951A/971A protocols' CONFIG_PARIDE_KBIC $CONFIG_PARIDE dep_tristate ' KT PHd protocol' CONFIG_PARIDE_KTTI $CONFIG_PARIDE diff --git a/drivers/block/paride/Makefile b/drivers/block/paride/Makefile index ae2d54dd9..32e856704 100644 --- a/drivers/block/paride/Makefile +++ b/drivers/block/paride/Makefile @@ -147,6 +147,15 @@ else endif endif + +ifeq ($(CONFIG_PARIDE_FRIQ),y) + LX_OBJS += friq.o +else + ifeq ($(CONFIG_PARIDE_FRIQ),m) + M_OBJS += friq.o + endif +endif + ifeq ($(CONFIG_PARIDE_ON20),y) LX_OBJS += on20.o else diff --git a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c new file mode 100644 index 000000000..37ebaa047 --- /dev/null +++ b/drivers/block/paride/friq.c @@ -0,0 +1,282 @@ +/* + friq.c (c) 1998 Grant R. Guenther <grant@torque.net> + Under the terms of the GNU public license + + friq.c is a low-level protocol driver for the Freecom "IQ" + parallel port IDE adapter. Early versions of this adapter + use the 'frpw' protocol. + + Freecom uses this adapter in a battery powered external + CD-ROM drive. It is also used in LS-120 drives by + Maxell and Panasonic, and other devices. + + The battery powered drive requires software support to + control the power to the drive. This module enables the + drive power when the high level driver (pcd) is loaded + and disables it when the module is unloaded. Note, if + the friq module is built in to the kernel, the power + will never be switched off, so other means should be + used to conserve battery power. + +*/ + +/* Changes: + + 1.01 GRG 1998.12.20 Added support for soft power switch +*/ + +#define FRIQ_VERSION "1.01" + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <asm/io.h> + +#include "paride.h" + +#define CMD(x) w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\ + w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x); + +#define j44(l,h) (((l>>4)&0x0f)|(h&0xf0)) + +/* cont = 0 - access the IDE register file + cont = 1 - access the IDE command set +*/ + +static int cont_map[2] = { 0x08, 0x10 }; + +static int friq_read_regr( PIA *pi, int cont, int regr ) + +{ int h,l,r; + + r = regr + cont_map[cont]; + + CMD(r); + w2(6); l = r1(); + w2(4); h = r1(); + w2(4); + + return j44(l,h); + +} + +static void friq_write_regr( PIA *pi, int cont, int regr, int val) + +{ int r; + + r = regr + cont_map[cont]; + + CMD(r); + w0(val); + w2(5);w2(7);w2(5);w2(4); +} + +static void friq_read_block_int( PIA *pi, char * buf, int count, int regr ) + +{ int h, l, k, ph; + + switch(pi->mode) { + + case 0: CMD(regr); + for (k=0;k<count;k++) { + w2(6); l = r1(); + w2(4); h = r1(); + buf[k] = j44(l,h); + } + w2(4); + break; + + case 1: ph = 2; + CMD(regr+0xc0); + w0(0xff); + for (k=0;k<count;k++) { + w2(0xa4 + ph); + buf[k] = r0(); + ph = 2 - ph; + } + w2(0xac); w2(0xa4); w2(4); + break; + + case 2: CMD(regr+0x80); + for (k=0;k<count-2;k++) buf[k] = r4(); + w2(0xac); w2(0xa4); + buf[count-2] = r4(); + buf[count-1] = r4(); + w2(4); + break; + + case 3: CMD(regr+0x80); + for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w(); + w2(0xac); w2(0xa4); + buf[count-2] = r4(); + buf[count-1] = r4(); + w2(4); + break; + + case 4: CMD(regr+0x80); + for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l(); + buf[count-4] = r4(); + buf[count-3] = r4(); + w2(0xac); w2(0xa4); + buf[count-2] = r4(); + buf[count-1] = r4(); + w2(4); + break; + + } +} + +static void friq_read_block( PIA *pi, char * buf, int count) + +{ friq_read_block_int(pi,buf,count,0x08); +} + +static void friq_write_block( PIA *pi, char * buf, int count ) + +{ int k; + + switch(pi->mode) { + + case 0: + case 1: CMD(8); w2(5); + for (k=0;k<count;k++) { + w0(buf[k]); + w2(7);w2(5); + } + w2(4); + break; + + case 2: CMD(0xc8); w2(5); + for (k=0;k<count;k++) w4(buf[k]); + w2(4); + break; + + case 3: CMD(0xc8); w2(5); + for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); + w2(4); + break; + + case 4: CMD(0xc8); w2(5); + for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); + w2(4); + break; + } +} + +static void friq_connect ( PIA *pi ) + +{ pi->saved_r0 = r0(); + pi->saved_r2 = r2(); + w2(4); +} + +static void friq_disconnect ( PIA *pi ) + +{ CMD(0x20); + w0(pi->saved_r0); + w2(pi->saved_r2); +} + +static int friq_test_proto( PIA *pi, char * scratch, int verbose ) + +{ int j, k, r; + int e[2] = {0,0}; + + pi->saved_r0 = r0(); + w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */ + udelay(500); + w0(pi->saved_r0); + + friq_connect(pi); + for (j=0;j<2;j++) { + friq_write_regr(pi,0,6,0xa0+j*0x10); + for (k=0;k<256;k++) { + friq_write_regr(pi,0,2,k^0xaa); + friq_write_regr(pi,0,3,k^0x55); + if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++; + } + } + friq_disconnect(pi); + + friq_connect(pi); + friq_read_block_int(pi,scratch,512,0x10); + r = 0; + for (k=0;k<128;k++) if (scratch[k] != k) r++; + friq_disconnect(pi); + + if (verbose) { + printk("%s: friq: port 0x%x, mode %d, test=(%d,%d,%d)\n", + pi->device,pi->port,pi->mode,e[0],e[1],r); + } + + return (r || (e[0] && e[1])); +} + + +static void friq_log_adapter( PIA *pi, char * scratch, int verbose ) + +{ char *mode_string[6] = {"4-bit","8-bit", + "EPP-8","EPP-16","EPP-32"}; + + printk("%s: friq %s, Freecom IQ ASIC-2 adapter at 0x%x, ", pi->device, + FRIQ_VERSION,pi->port); + printk("mode %d (%s), delay %d\n",pi->mode, + mode_string[pi->mode],pi->delay); + + pi->private = 1; + friq_connect(pi); + CMD(0x9e); /* disable sleep timer */ + friq_disconnect(pi); + +} + +static void friq_init_proto( PIA *pi) + +{ MOD_INC_USE_COUNT; + pi->private = 0; +} + +static void friq_release_proto( PIA *pi) + +{ if (pi->private) { /* turn off the power */ + friq_connect(pi); + CMD(0x1d); CMD(0x1e); + friq_disconnect(pi); + pi->private = 0; + } + + MOD_DEC_USE_COUNT; +} + +struct pi_protocol friq = {"friq",0,5,2,1,1, + friq_write_regr, + friq_read_regr, + friq_write_block, + friq_read_block, + friq_connect, + friq_disconnect, + 0, + 0, + friq_test_proto, + friq_log_adapter, + friq_init_proto, + friq_release_proto + }; + + +#ifdef MODULE + +int init_module(void) + +{ return pi_register( &friq ) - 1; +} + +void cleanup_module(void) + +{ pi_unregister( &friq ); +} + +#endif + +/* end of friq.c */ diff --git a/drivers/block/paride/frpw.c b/drivers/block/paride/frpw.c index 680f9e592..f4c98c645 100644 --- a/drivers/block/paride/frpw.c +++ b/drivers/block/paride/frpw.c @@ -5,6 +5,12 @@ frpw.c is a low-level protocol driver for the Freecom "Power" parallel port IDE adapter. + Some applications of this adapter may require a "printer" reset + prior to loading the driver. This can be done by loading and + unloading the "lp" driver, or it can be done by this driver + if you define FRPW_HARD_RESET. The latter is not recommended + as it may upset devices on other ports. + */ /* Changes: @@ -13,10 +19,11 @@ fix chip detect added EPP-16 and EPP-32 1.02 GRG 1998.09.23 added hard reset to initialisation process + 1.03 GRG 1998.12.14 made hard reset conditional */ -#define FRPW_VERSION "1.02" +#define FRPW_VERSION "1.03" #include <linux/module.h> #include <linux/delay.h> @@ -185,8 +192,10 @@ static int frpw_test_pnp ( PIA *pi ) { int olddelay, a, b; +#ifdef FRPW_HARD_RESET w0(0); w2(8); udelay(50); w2(0xc); /* parallel bus reset */ mdelay(1500); +#endif olddelay = pi->delay; pi->delay = 10; diff --git a/drivers/block/paride/jumbo b/drivers/block/paride/jumbo index b952fde92..f4b8ebf75 100644 --- a/drivers/block/paride/jumbo +++ b/drivers/block/paride/jumbo @@ -53,11 +53,11 @@ FPROTO=-DCONFIG_PARIDE_`echo "$PROTO" | tr [a-z] [A-Z]` FK="-D__KERNEL__ -I ../../../include" FLCH=-D_LINUX_CONFIG_H # -echo cc $FK $FSMP $FLCH $FPARP $FPROTO -Wall -O2 -o Jb.o -c paride.c -cc $FK $FSMP $FLCH $FPARP $FPROTO -Wall -O2 -o Jb.o -c paride.c +echo cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c +cc $FK $FSMP $FLCH $FPARP $FPROTO $FMODV -Wall -O2 -o Jb.o -c paride.c # -echo cc $FK $FSMP -Wall -O2 -o Jp.o -c $PROTO.c -cc $FK $FSMP -Wall -O2 -o Jp.o -c $PROTO.c +echo cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c +cc $FK $FSMP $FMODV -Wall -O2 -o Jp.o -c $PROTO.c # echo cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c cc $FK $FSMP $FMODV -DMODULE -DPARIDE_JUMBO -Wall -O2 -o Jd.o -c $HLD.c diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c index 78477593e..91dcad101 100644 --- a/drivers/block/paride/on26.c +++ b/drivers/block/paride/on26.c @@ -11,10 +11,12 @@ 1.01 GRG 1998.05.06 init_proto, release_proto 1.02 GRG 1998.09.23 updates for the -E rev chip + 1.03 GRG 1998.12.14 fix for slave drives + 1.04 GRG 1998.12.20 yet another bug fix */ -#define ON26_VERSION "1.02" +#define ON26_VERSION "1.04" #include <linux/module.h> #include <linux/delay.h> @@ -118,9 +120,11 @@ static void on26_disconnect ( PIA *pi ) w2(pi->saved_r2); } +#define RESET_WAIT 200 + static int on26_test_port( PIA *pi) /* hard reset */ -{ int i, m, d; +{ int i, m, d, x, y; pi->saved_r0 = r0(); pi->saved_r2 = r2(); @@ -151,11 +155,18 @@ static int on26_test_port( PIA *pi) /* hard reset */ on26_write_regr(pi,0,6,0xa0); - for (i=0;i<100;i++) { - if (!(on26_read_regr(pi,0,7) & 0x80)) break; - udelay(100000); + for (i=0;i<RESET_WAIT;i++) { + on26_write_regr(pi,0,6,0xa0); + x = on26_read_regr(pi,0,7); + on26_write_regr(pi,0,6,0xb0); + y = on26_read_regr(pi,0,7); + if (!((x&0x80)||(y&0x80))) break; + mdelay(100); } + if (i == RESET_WAIT) + printk("on26: Device reset failed (%x,%x)\n",x,y); + w0(4); P1; w0(4); P1; } @@ -189,7 +200,7 @@ static void on26_read_block( PIA *pi, char * buf, int count ) case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1; udelay(10); for (k=0;k<count/2;k++) { - w2(0x26); buf[2*k] = r0(); + w2(0x26); buf[2*k] = r0(); w2(0x24); buf[2*k+1] = r0(); } w0(2); P1; w0(9); P2; diff --git a/drivers/block/paride/paride.c b/drivers/block/paride/paride.c index 068deffd6..6e962d8c1 100644 --- a/drivers/block/paride/paride.c +++ b/drivers/block/paride/paride.c @@ -12,10 +12,11 @@ 1.01 GRG 1998.05.03 Use spinlocks 1.02 GRG 1998.05.05 init_proto, release_proto, ktti 1.03 GRG 1998.08.15 eliminate compiler warning + 1.04 GRG 1998.11.28 added support for FRIQ */ -#define PI_VERSION "1.03" +#define PI_VERSION "1.04" #include <linux/module.h> #include <linux/config.h> @@ -450,6 +451,11 @@ void paride_init( void ) pi_register(&frpw); }; #endif +#ifdef CONFIG_PARIDE_FRIQ + { extern struct pi_protocol friq; + pi_register(&friq); + }; +#endif #ifdef CONFIG_PARIDE_FIT2 { extern struct pi_protocol fit2; pi_register(&fit2); diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index 1563a2afc..89c83db65 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c @@ -367,21 +367,21 @@ static int pg_wait( int unit, int go, int stop, int tmo, char * msg ) PG.status = 0; j = 0; - while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(jiffies<tmo)) { + while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(time_before(jiffies,tmo))) { if (j++ < PG_SPIN) udelay(PG_SPIN_DEL); else pg_sleep(1); } - if ((r&(STAT_ERR&stop))||(jiffies>=tmo)) { + if ((r&(STAT_ERR&stop))||time_after_eq(jiffies, tmo)) { s = RR(0,7); e = RR(0,1); p = RR(0,2); if (verbose > 1) printk("%s: %s: stat=0x%x err=0x%x phase=%d%s\n", - PG.name,msg,s,e,p,(jiffies>=tmo)?" timeout":""); + PG.name,msg,s,e,p,time_after_eq(jiffies, tmo)?" timeout":""); - if (jiffies>=tmo) e |= 0x100; + if (time_after_eq(jiffies, tmo)) e |= 0x100; PG.status = (e >> 4) & 0xff; return -1; } diff --git a/drivers/block/paride/pseudo.h b/drivers/block/paride/pseudo.h index 17615c2ca..3992f3c30 100644 --- a/drivers/block/paride/pseudo.h +++ b/drivers/block/paride/pseudo.h @@ -16,19 +16,21 @@ when either it returns true, or timeout jiffies have passed, continuation() will be invoked. - If nice is true, the test will done approximately once a + If nice is 1, the test will done approximately once a jiffy. If nice is 0, the test will also be done whenever - the scheduler runs (by adding it to a task queue). + the scheduler runs (by adding it to a task queue). If + nice is greater than 1, the test will be done once every + (nice-1) jiffies. */ /* Changes: 1.01 1998.05.03 Switched from cli()/sti() to spinlocks - + 1.02 1998.12.14 Added support for nice > 1 */ -#define PS_VERSION "1.01" +#define PS_VERSION "1.02" #include <linux/sched.h> #include <linux/timer.h> @@ -37,15 +39,15 @@ static void ps_timer_int( unsigned long data); static void ps_tq_int( void *data); -static int ps_use_tq = 1; static void (* ps_continuation)(void); static int (* ps_ready)(void); static int ps_then; static int ps_timeout; static int ps_timer_active = 0; static int ps_tq_active = 0; +static int ps_nice = 0; -static spinlock_t ps_spinlock = SPIN_LOCK_UNLOCKED; +static spinlock_t ps_spinlock __attribute__((unused)) = SPIN_LOCK_UNLOCKED; static struct timer_list ps_timer = {0,0,0,0,ps_timer_int}; static struct tq_struct ps_tq = {0,0,ps_tq_int,NULL}; @@ -62,9 +64,9 @@ static void ps_set_intr( void (*continuation)(void), ps_ready = ready; ps_then = jiffies; ps_timeout = jiffies + timeout; - ps_use_tq = !nice; + ps_nice = nice; - if (ps_use_tq && !ps_tq_active) { + if (!ps_nice && !ps_tq_active) { #ifdef HAVE_DISABLE_HLT disable_hlt(); #endif @@ -74,7 +76,7 @@ static void ps_set_intr( void (*continuation)(void), if (!ps_timer_active) { ps_timer_active = 1; - ps_timer.expires = jiffies; + ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0); add_timer(&ps_timer); } @@ -136,7 +138,7 @@ static void ps_timer_int( unsigned long data) return; } ps_timer_active = 1; - ps_timer.expires = jiffies; + ps_timer.expires = jiffies + ((ps_nice>0)?(ps_nice-1):0); add_timer(&ps_timer); spin_unlock_irqrestore(&ps_spinlock,flags); } diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 1a09c84b0..2616319f7 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c @@ -471,7 +471,7 @@ static int pt_poll_dsc( int unit, int pause, int tmo, char *msg ) { int k, e, s; - k = 0; + k = 0; e = 0; s = 0; while (k < tmo) { pt_sleep(pause); k++; |