^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) bpck.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Under the terms of the GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) bpck.c is a low-level protocol driver for the MicroSolutions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) "backpack" parallel port IDE adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 1.01 GRG 1998.05.05 init_proto, release_proto, pi->delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 1.02 GRG 1998.08.15 default pi->delay returned to 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define BPCK_VERSION "1.02"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "paride.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #undef r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #undef w2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PC pi->private
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define r2() (PC=(in_p(2) & 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define w2(byte) {out_p(2,byte); PC = byte;}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define t2(pat) {PC ^= pat; out_p(2,PC);}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define e2() {PC &= 0xfe; out_p(2,PC);}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define o2() {PC |= 1; out_p(2,PC);}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* cont = 0 - access the IDE register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) cont = 1 - access the IDE command set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) cont = 2 - use internal bpck register addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int cont_map[3] = { 0x40, 0x48, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static int bpck_read_regr( PIA *pi, int cont, int regr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) { int r, l, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) r = regr + cont_map[cont];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) l = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) t2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) h = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return j44(l,h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case 1: w0(r & 0xf); w0(r); t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) e2(); t2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) t2(4); h = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) t2(1); t2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) return h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case 4: w0(r); w2(9); w2(0); w2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) h = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) { int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) r = regr + cont_map[cont];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) case 1: w0(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) w0(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) o2(); t2(4); t2(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) case 4: w0(r); w2(9); w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) w0(val); w2(1); w2(3); w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* These macros access the bpck registers in native addressing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define WR(r,v) bpck_write_regr(pi,2,r,v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define RR(r) (bpck_read_regr(pi,2,r))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void bpck_write_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) { int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) case 0: WR(4,0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) w0(0x40); t2(2); t2(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) WR(4,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) case 1: WR(4,0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) w0(0x40); t2(2); t2(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) WR(4,0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) case 2: WR(4,0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) w0(0x40); w2(9); w2(0); w2(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) for (i=0;i<count;i++) w4(buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) case 3: WR(4,0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) w0(0x40); w2(9); w2(0); w2(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case 4: WR(4,0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) w0(0x40); w2(9); w2(0); w2(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static void bpck_read_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) { int i, l, h;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case 0: WR(4,0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) w0(0x40); t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) for (i=0;i<count;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) t2(4); l = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) t2(4); h = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) buf[i] = j44(l,h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) WR(4,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) case 1: WR(4,0x50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) w0(0x40); t2(2); t2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) t2(1); t2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) WR(4,0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) case 2: WR(4,0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) w0(0x40); w2(9); w2(0); w2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) for (i=0;i<count;i++) buf[i] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) case 3: WR(4,0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) w0(0x40); w2(9); w2(0); w2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) case 4: WR(4,0x48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) w0(0x40); w2(9); w2(0); w2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int bpck_probe_unit ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) { int o1, o0, f7, id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int t, s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) id = pi->unit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) s = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) w2(4); w2(0xe); r2(); t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) o1 = r1()&0xf8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) o0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) w0(255-id); w2(4); w0(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) t2(8); t2(8); t2(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) t2(2); t = r1()&0xf8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) f7 = ((id % 8) == 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if ((t == o1) && ((!f7) || (s == o1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) w2(0x4c); w0(o0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static void bpck_connect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) w0(0xff-pi->unit); w2(4); w0(pi->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) t2(8); t2(8); t2(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) t2(2); t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) case 0: t2(8); WR(4,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) case 1: t2(8); WR(4,0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case 4: w2(0); WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) WR(5,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (pi->devtype == PI_PCD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) WR(0x46,0x10); /* fiddle with ESS logic ??? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) WR(0x4c,0x38);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) WR(0x4d,0x88);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) WR(0x46,0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) WR(0x41,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) WR(0x4e,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void bpck_disconnect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) { w0(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) w2(0x4c); w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static void bpck_force_spp ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* This fakes the EPP protocol to turn off EPP ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) { pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) w0(0xff-pi->unit); w2(4); w0(pi->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) t2(8); t2(8); t2(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) t2(2); t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) w0(4); w2(9); w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) w0(0); w2(1); w2(3); w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) w0(0); w2(9); w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) w2(0x4c); w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) #define TEST_LEN 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { int i, e, l, h, om;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) char buf[TEST_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) bpck_force_spp(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) case 0: bpck_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) WR(0x13,0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) w0(0x13); t2(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for(i=0;i<TEST_LEN;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) t2(4); l = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) t2(4); h = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) buf[i] = j44(l,h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) bpck_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) case 1: bpck_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) WR(0x13,0x7f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) w0(0x13); t2(2); t2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) t2(1); t2(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) bpck_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) case 4: om = pi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) pi->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) bpck_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) WR(7,3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) bpck_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) pi->mode = om;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) bpck_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) w2(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) WR(7,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) bpck_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (verbose) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) printk("%s: bpck: 0x%x unit %d mode %d: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pi->device,pi->port,pi->unit,pi->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) e = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) static void bpck_read_eeprom ( PIA *pi, char * buf )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) { int i, j, k, p, v, f, om, od;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) bpck_force_spp(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) om = pi->mode; od = pi->delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pi->mode = 0; pi->delay = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) bpck_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) WR(4,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) for (i=0;i<64;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) WR(6,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) WR(6,0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) p = 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) for (k=0;k<9;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) f = (((i + 0x180) & p) != 0) * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) WR(6,f+0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) WR(6,f+0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) WR(6,f+0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) p = (p >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) for (j=0;j<2;j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) for (k=0;k<8;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) WR(6,0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) WR(6,0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) WR(6,0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) f = RR(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) v = 2*v + (f == 0x84);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) buf[2*i+1-j] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) WR(6,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) WR(6,0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) WR(5,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) bpck_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (om >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) bpck_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) WR(7,3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) WR(4,8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) bpck_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) pi->mode = om; pi->delay = od;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int bpck_test_port ( PIA *pi ) /* check for 8-bit port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { int i, r, m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) m = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (r == i) m = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (r == (255-i)) m = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (r != (255-i)) m = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (m == 2) { w2(0x26); w2(0xc); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (m == -1) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) { char *mode_string[5] = { "4-bit","8-bit","EPP-8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) "EPP-16","EPP-32" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) #ifdef DUMP_EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) bpck_read_eeprom(pi,scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #ifdef DUMP_EEPROM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (verbose) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) for(i=0;i<128;i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if ((scratch[i] < ' ') || (scratch[i] > '~'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) scratch[i] = '.';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) printk("%s: %64.64s\n",pi->device,&scratch[64]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) printk("%s: bpck %s, backpack %8.8s unit %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) pi->device,BPCK_VERSION,&scratch[110],pi->unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) pi->mode,mode_string[pi->mode],pi->delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static struct pi_protocol bpck = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .name = "bpck",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .max_mode = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .epp_first = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .default_delay = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .max_units = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .write_regr = bpck_write_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .read_regr = bpck_read_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .write_block = bpck_write_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .read_block = bpck_read_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .connect = bpck_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .disconnect = bpck_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .test_port = bpck_test_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .probe_unit = bpck_probe_unit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .test_proto = bpck_test_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .log_adapter = bpck_log_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) static int __init bpck_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return paride_register(&bpck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static void __exit bpck_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) paride_unregister(&bpck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) module_init(bpck_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) module_exit(bpck_exit)