1/* 2 paride.c (c) 1997-8 Grant R. Guenther <grant@torque.net> 3 Under the terms of the GNU General Public License. 4 5 This is the base module for the family of device drivers 6 that support parallel port IDE devices. 7 8*/ 9 10/* Changes: 11 12 1.01 GRG 1998.05.03 Use spinlocks 13 1.02 GRG 1998.05.05 init_proto, release_proto, ktti 14 1.03 GRG 1998.08.15 eliminate compiler warning 15 1.04 GRG 1998.11.28 added support for FRIQ 16 1.05 TMW 2000.06.06 use parport_find_number instead of 17 parport_enumerate 18 1.06 TMW 2001.03.26 more sane parport-or-not resource management 19*/ 20 21#define PI_VERSION "1.06" 22 23#include <linux/module.h> 24#include <linux/config.h> 25#include <linux/kmod.h> 26#include <linux/types.h> 27#include <linux/kernel.h> 28#include <linux/ioport.h> 29#include <linux/string.h> 30#include <linux/spinlock.h> 31#include <linux/wait.h> 32 33#ifdef CONFIG_PARPORT_MODULE 34#define CONFIG_PARPORT 35#endif 36 37#ifdef CONFIG_PARPORT 38#include <linux/parport.h> 39#endif 40 41#include "paride.h" 42 43#define MAX_PROTOS 32 44 45static struct pi_protocol *protocols[MAX_PROTOS]; 46 47static spinlock_t pi_spinlock = SPIN_LOCK_UNLOCKED; 48 49void pi_write_regr( PIA *pi, int cont, int regr, int val) 50 51{ pi->proto->write_regr(pi,cont,regr,val); 52} 53 54int pi_read_regr( PIA *pi, int cont, int regr) 55 56{ return pi->proto->read_regr(pi,cont,regr); 57} 58 59void pi_write_block( PIA *pi, char * buf, int count) 60 61{ pi->proto->write_block(pi,buf,count); 62} 63 64void pi_read_block( PIA *pi, char * buf, int count) 65 66{ pi->proto->read_block(pi,buf,count); 67} 68 69#ifdef CONFIG_PARPORT 70 71static void pi_wake_up( void *p) 72 73{ PIA *pi = (PIA *) p; 74 unsigned long flags; 75 void (*cont)(void) = NULL; 76 77 spin_lock_irqsave(&pi_spinlock,flags); 78 79 if (pi->claim_cont && !parport_claim(pi->pardev)) { 80 cont = pi->claim_cont; 81 pi->claim_cont = NULL; 82 pi->claimed = 1; 83 } 84 85 spin_unlock_irqrestore(&pi_spinlock,flags); 86 87 wake_up(&(pi->parq)); 88 89 if (cont) cont(); 90} 91 92#endif 93 94void pi_do_claimed( PIA *pi, void(*cont)(void)) 95 96#ifdef CONFIG_PARPORT 97 98{ unsigned long flags; 99 100 spin_lock_irqsave(&pi_spinlock,flags); 101 102 if (!pi->pardev || !parport_claim(pi->pardev)) { 103 pi->claimed = 1; 104 spin_unlock_irqrestore(&pi_spinlock,flags); 105 cont(); 106 } else { 107 pi->claim_cont = cont; 108 spin_unlock_irqrestore(&pi_spinlock,flags); 109 } 110} 111 112#else 113 114{ cont(); 115} 116 117#endif 118 119static void pi_claim( PIA *pi) 120 121{ if (pi->claimed) return; 122 pi->claimed = 1; 123#ifdef CONFIG_PARPORT 124 if (pi->pardev) 125 wait_event (pi->parq, 126 !parport_claim ((struct pardevice *)pi->pardev)); 127#endif 128} 129 130static void pi_unclaim( PIA *pi) 131 132{ pi->claimed = 0; 133#ifdef CONFIG_PARPORT 134 if (pi->pardev) parport_release((struct pardevice *)(pi->pardev)); 135#endif 136} 137 138void pi_connect( PIA *pi) 139 140{ pi_claim(pi); 141 pi->proto->connect(pi); 142} 143 144void pi_disconnect( PIA *pi) 145 146{ pi->proto->disconnect(pi); 147 pi_unclaim(pi); 148} 149 150static void pi_unregister_parport( PIA *pi) 151 152{ 153#ifdef CONFIG_PARPORT 154 if (pi->pardev) { 155 parport_unregister_device((struct pardevice *)(pi->pardev)); 156 pi->pardev = NULL; 157 } 158#endif 159} 160 161void pi_release( PIA *pi) 162 163{ pi_unregister_parport(pi); 164#ifndef CONFIG_PARPORT 165 if (pi->reserved) 166 release_region(pi->port,pi->reserved); 167#endif /* !CONFIG_PARPORT */ 168 pi->proto->release_proto(pi); 169} 170 171#define WR(r,v) pi_write_regr(pi,0,r,v) 172#define RR(r) (pi_read_regr(pi,0,r)) 173 174static int pi_test_proto( PIA *pi, char * scratch, int verbose ) 175 176{ int j, k; 177 int e[2] = {0,0}; 178 179 if (pi->proto->test_proto) { 180 pi_claim(pi); 181 j = pi->proto->test_proto(pi,scratch,verbose); 182 pi_unclaim(pi); 183 return j; 184 } 185 186 pi_connect(pi); 187 188 for (j=0;j<2;j++) { 189 WR(6,0xa0+j*0x10); 190 for (k=0;k<256;k++) { 191 WR(2,k^0xaa); 192 WR(3,k^0x55); 193 if (RR(2) != (k^0xaa)) e[j]++; 194 } 195 } 196 197 pi_disconnect(pi); 198 199 if (verbose) 200 printk("%s: %s: port 0x%x, mode %d, test=(%d,%d)\n", 201 pi->device,pi->proto->name,pi->port, 202 pi->mode,e[0],e[1]); 203 204 return (e[0] && e[1]); /* not here if both > 0 */ 205} 206 207int pi_register( PIP *pr) 208 209{ int k; 210 211 for (k=0;k<MAX_PROTOS;k++) 212 if (protocols[k] && !strcmp(pr->name,protocols[k]->name)) { 213 printk("paride: %s protocol already registered\n",pr->name); 214 return 0; 215 } 216 k = 0; 217 while((k<MAX_PROTOS) && (protocols[k])) k++; 218 if (k == MAX_PROTOS) { 219 printk("paride: protocol table full\n"); 220 return 0; 221 } 222 MOD_INC_USE_COUNT; 223 protocols[k] = pr; 224 pr->index = k; 225 printk("paride: %s registered as protocol %d\n",pr->name,k); 226 return 1; 227} 228 229void pi_unregister( PIP *pr) 230 231{ if (!pr) return; 232 if (protocols[pr->index] != pr) { 233 printk("paride: %s not registered\n",pr->name); 234 return; 235 } 236 protocols[pr->index] = 0; 237 MOD_DEC_USE_COUNT; 238} 239 240static int pi_register_parport( PIA *pi, int verbose) 241 242{ 243#ifdef CONFIG_PARPORT 244 245 struct parport *port; 246 247 port = parport_find_base (pi->port); 248 if (!port) 249 return 0; 250 251 pi->pardev = parport_register_device(port, 252 pi->device,NULL, 253 pi_wake_up,NULL, 254 0,(void *)pi); 255 parport_put_port (port); 256 if (!pi->pardev) 257 return 0; 258 259 init_waitqueue_head(&pi->parq); 260 261 if (verbose) printk("%s: 0x%x is %s\n",pi->device,pi->port, 262 port->name); 263 264 pi->parname = (char *)port->name; 265#endif 266 267 return 1; 268} 269 270static int pi_probe_mode( PIA *pi, int max, char * scratch, int verbose) 271 272{ int best, range; 273 274 if (pi->mode != -1) { 275 if (pi->mode >= max) return 0; 276 range = 3; 277 if (pi->mode >= pi->proto->epp_first) range = 8; 278 if ((range == 8) && (pi->port % 8)) return 0; 279 pi->reserved = range; 280 return (!pi_test_proto(pi,scratch,verbose)); 281 } 282 best = -1; 283 for(pi->mode=0;pi->mode<max;pi->mode++) { 284 range = 3; 285 if (pi->mode >= pi->proto->epp_first) range = 8; 286 if ((range == 8) && (pi->port % 8)) break; 287 pi->reserved = range; 288 if (!pi_test_proto(pi,scratch,verbose)) best = pi->mode; 289 } 290 pi->mode = best; 291 return (best > -1); 292} 293 294static int pi_probe_unit( PIA *pi, int unit, char * scratch, int verbose) 295 296{ int max,s,e; 297 298 s = unit; e = s+1; 299 300 if (s == -1) { 301 s = 0; 302 e = pi->proto->max_units; 303 } 304 305 if (!pi_register_parport(pi,verbose)) 306 return 0; 307 308 if (pi->proto->test_port) { 309 pi_claim(pi); 310 max = pi->proto->test_port(pi); 311 pi_unclaim(pi); 312 } 313 else max = pi->proto->max_mode; 314 315 if (pi->proto->probe_unit) { 316 pi_claim(pi); 317 for (pi->unit=s;pi->unit<e;pi->unit++) 318 if (pi->proto->probe_unit(pi)) { 319 pi_unclaim(pi); 320 if (pi_probe_mode(pi,max,scratch,verbose)) return 1; 321 pi_unregister_parport(pi); 322 return 0; 323 } 324 pi_unclaim(pi); 325 pi_unregister_parport(pi); 326 return 0; 327 } 328 329 if (!pi_probe_mode(pi,max,scratch,verbose)) { 330 pi_unregister_parport(pi); 331 return 0; 332 } 333 return 1; 334 335} 336 337int pi_init(PIA *pi, int autoprobe, int port, int mode, 338 int unit, int protocol, int delay, char * scratch, 339 int devtype, int verbose, char *device ) 340 341{ int p,k,s,e; 342 int lpts[7] = {0x3bc,0x378,0x278,0x268,0x27c,0x26c,0}; 343 344 s = protocol; e = s+1; 345 346 if (!protocols[0]) 347 request_module ("paride_protocol"); 348 349 if (autoprobe) { 350 s = 0; 351 e = MAX_PROTOS; 352 } else if ((s < 0) || (s >= MAX_PROTOS) || (port <= 0) || 353 (!protocols[s]) || (unit < 0) || 354 (unit >= protocols[s]->max_units)) { 355 printk("%s: Invalid parameters\n",device); 356 return 0; 357 } 358 359 for (p=s;p<e;p++) { 360 if (protocols[p]) { 361 pi->proto = protocols[p]; 362 pi->private = 0; 363 pi->proto->init_proto(pi); 364 if (delay == -1) pi->delay = pi->proto->default_delay; 365 else pi->delay = delay; 366 pi->devtype = devtype; 367 pi->device = device; 368 369 pi->parname = NULL; 370 pi->pardev = NULL; 371 init_waitqueue_head(&pi->parq); 372 pi->claimed = 0; 373 pi->claim_cont = NULL; 374 375 pi->mode = mode; 376 if (port != -1) { 377 pi->port = port; 378 if (pi_probe_unit(pi,unit,scratch,verbose)) break; 379 pi->port = 0; 380 } else { 381 k = 0; 382 while ((pi->port = lpts[k++])) 383 if (pi_probe_unit(pi,unit,scratch,verbose)) break; 384 if (pi->port) break; 385 } 386 pi->proto->release_proto(pi); 387 } 388 } 389 390 if (!pi->port) { 391 if (autoprobe) printk("%s: Autoprobe failed\n",device); 392 else printk("%s: Adapter not found\n",device); 393 return 0; 394 } 395 396#ifndef CONFIG_PARPORT 397 if (!request_region(pi->port,pi->reserved,pi->device)) 398 { 399 printk(KERN_WARNING"paride: Unable to request region 0x%x\n", pi->port); 400 return 0; 401 } 402#endif /* !CONFIG_PARPORT */ 403 404 if (pi->parname) 405 printk("%s: Sharing %s at 0x%x\n",pi->device, 406 pi->parname,pi->port); 407 408 pi->proto->log_adapter(pi,scratch,verbose); 409 410 return 1; 411} 412 413#ifdef MODULE 414 415int init_module(void) 416 417{ 418 int k; 419 const char *indicate_pp = ""; 420#ifdef CONFIG_PARPORT 421 indicate_pp = " (parport)"; 422#endif 423 424 for (k=0;k<MAX_PROTOS;k++) protocols[k] = 0; 425 426 printk("paride: version %s installed%s\n",PI_VERSION,indicate_pp); 427 return 0; 428} 429 430void cleanup_module(void) 431 432{ 433} 434 435#else 436 437void paride_init( void ) 438 439{ 440 441#ifdef CONFIG_PARIDE_ATEN 442 { extern struct pi_protocol aten; 443 pi_register(&aten); 444 }; 445#endif 446#ifdef CONFIG_PARIDE_BPCK 447 { extern struct pi_protocol bpck; 448 pi_register(&bpck); 449 }; 450#endif 451#ifdef CONFIG_PARIDE_COMM 452 { extern struct pi_protocol comm; 453 pi_register(&comm); 454 }; 455#endif 456#ifdef CONFIG_PARIDE_DSTR 457 { extern struct pi_protocol dstr; 458 pi_register(&dstr); 459 }; 460#endif 461#ifdef CONFIG_PARIDE_EPAT 462 { extern struct pi_protocol epat; 463 pi_register(&epat); 464 }; 465#endif 466#ifdef CONFIG_PARIDE_EPIA 467 { extern struct pi_protocol epia; 468 pi_register(&epia); 469 }; 470#endif 471#ifdef CONFIG_PARIDE_FRPW 472 { extern struct pi_protocol frpw; 473 pi_register(&frpw); 474 }; 475#endif 476#ifdef CONFIG_PARIDE_FRIQ 477 { extern struct pi_protocol friq; 478 pi_register(&friq); 479 }; 480#endif 481#ifdef CONFIG_PARIDE_FIT2 482 { extern struct pi_protocol fit2; 483 pi_register(&fit2); 484 }; 485#endif 486#ifdef CONFIG_PARIDE_FIT3 487 { extern struct pi_protocol fit3; 488 pi_register(&fit3); 489 }; 490#endif 491#ifdef CONFIG_PARIDE_KBIC 492 { extern struct pi_protocol k951; 493 extern struct pi_protocol k971; 494 pi_register(&k951); 495 pi_register(&k971); 496 }; 497#endif 498#ifdef CONFIG_PARIDE_KTTI 499 { extern struct pi_protocol ktti; 500 pi_register(&ktti); 501 }; 502#endif 503#ifdef CONFIG_PARIDE_ON20 504 { extern struct pi_protocol on20; 505 pi_register(&on20); 506 }; 507#endif 508#ifdef CONFIG_PARIDE_ON26 509 { extern struct pi_protocol on26; 510 pi_register(&on26); 511 }; 512#endif 513 514#ifdef CONFIG_PARIDE_PD 515 { extern int pd_init(void); 516 pd_init(); 517 }; 518#endif 519#ifdef CONFIG_PARIDE_PCD 520 { extern int pcd_init(void); 521 pcd_init(); 522 }; 523#endif 524#ifdef CONFIG_PARIDE_PF 525 { extern int pf_init(void); 526 pf_init(); 527 }; 528#endif 529#ifdef CONFIG_PARIDE_PT 530 { extern int pt_init(void); 531 pt_init(); 532 }; 533#endif 534#ifdef CONFIG_PARIDE_PG 535 { extern int pg_init(void); 536 pg_init(); 537 }; 538#endif 539} 540 541#endif 542 543/* end of paride.c */ 544MODULE_LICENSE("GPL"); 545