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/kmod.h> 25#include <linux/types.h> 26#include <linux/kernel.h> 27#include <linux/ioport.h> 28#include <linux/string.h> 29#include <linux/spinlock.h> 30#include <linux/wait.h> 31#include <linux/sched.h> /* TASK_* */ 32#include <linux/parport.h> 33 34#include "paride.h" 35 36MODULE_LICENSE("GPL"); 37 38#define MAX_PROTOS 32 39 40static struct pi_protocol *protocols[MAX_PROTOS]; 41 42static DEFINE_SPINLOCK(pi_spinlock); 43 44void pi_write_regr(PIA * pi, int cont, int regr, int val) 45{ 46 pi->proto->write_regr(pi, cont, regr, val); 47} 48 49EXPORT_SYMBOL(pi_write_regr); 50 51int pi_read_regr(PIA * pi, int cont, int regr) 52{ 53 return pi->proto->read_regr(pi, cont, regr); 54} 55 56EXPORT_SYMBOL(pi_read_regr); 57 58void pi_write_block(PIA * pi, char *buf, int count) 59{ 60 pi->proto->write_block(pi, buf, count); 61} 62 63EXPORT_SYMBOL(pi_write_block); 64 65void pi_read_block(PIA * pi, char *buf, int count) 66{ 67 pi->proto->read_block(pi, buf, count); 68} 69 70EXPORT_SYMBOL(pi_read_block); 71 72static void pi_wake_up(void *p) 73{ 74 PIA *pi = (PIA *) p; 75 unsigned long flags; 76 void (*cont) (void) = NULL; 77 78 spin_lock_irqsave(&pi_spinlock, flags); 79 80 if (pi->claim_cont && !parport_claim(pi->pardev)) { 81 cont = pi->claim_cont; 82 pi->claim_cont = NULL; 83 pi->claimed = 1; 84 } 85 86 spin_unlock_irqrestore(&pi_spinlock, flags); 87 88 wake_up(&(pi->parq)); 89 90 if (cont) 91 cont(); 92} 93 94int pi_schedule_claimed(PIA * pi, void (*cont) (void)) 95{ 96 unsigned long flags; 97 98 spin_lock_irqsave(&pi_spinlock, flags); 99 if (pi->pardev && parport_claim(pi->pardev)) { 100 pi->claim_cont = cont; 101 spin_unlock_irqrestore(&pi_spinlock, flags); 102 return 0; 103 } 104 pi->claimed = 1; 105 spin_unlock_irqrestore(&pi_spinlock, flags); 106 return 1; 107} 108EXPORT_SYMBOL(pi_schedule_claimed); 109 110void pi_do_claimed(PIA * pi, void (*cont) (void)) 111{ 112 if (pi_schedule_claimed(pi, cont)) 113 cont(); 114} 115 116EXPORT_SYMBOL(pi_do_claimed); 117 118static void pi_claim(PIA * pi) 119{ 120 if (pi->claimed) 121 return; 122 pi->claimed = 1; 123 if (pi->pardev) 124 wait_event(pi->parq, 125 !parport_claim((struct pardevice *) pi->pardev)); 126} 127 128static void pi_unclaim(PIA * pi) 129{ 130 pi->claimed = 0; 131 if (pi->pardev) 132 parport_release((struct pardevice *) (pi->pardev)); 133} 134 135void pi_connect(PIA * pi) 136{ 137 pi_claim(pi); 138 pi->proto->connect(pi); 139} 140 141EXPORT_SYMBOL(pi_connect); 142 143void pi_disconnect(PIA * pi) 144{ 145 pi->proto->disconnect(pi); 146 pi_unclaim(pi); 147} 148 149EXPORT_SYMBOL(pi_disconnect); 150 151static void pi_unregister_parport(PIA * pi) 152{ 153 if (pi->pardev) { 154 parport_unregister_device((struct pardevice *) (pi->pardev)); 155 pi->pardev = NULL; 156 } 157} 158 159void pi_release(PIA * pi) 160{ 161 pi_unregister_parport(pi); 162 if (pi->proto->release_proto) 163 pi->proto->release_proto(pi); 164 module_put(pi->proto->owner); 165} 166 167EXPORT_SYMBOL(pi_release); 168 169static int default_test_proto(PIA * pi, char *scratch, int verbose) 170{ 171 int j, k; 172 int e[2] = { 0, 0 }; 173 174 pi->proto->connect(pi); 175 176 for (j = 0; j < 2; j++) { 177 pi_write_regr(pi, 0, 6, 0xa0 + j * 0x10); 178 for (k = 0; k < 256; k++) { 179 pi_write_regr(pi, 0, 2, k ^ 0xaa); 180 pi_write_regr(pi, 0, 3, k ^ 0x55); 181 if (pi_read_regr(pi, 0, 2) != (k ^ 0xaa)) 182 e[j]++; 183 } 184 } 185 pi->proto->disconnect(pi); 186 187 if (verbose) 188 printk("%s: %s: port 0x%x, mode %d, test=(%d,%d)\n", 189 pi->device, pi->proto->name, pi->port, 190 pi->mode, e[0], e[1]); 191 192 return (e[0] && e[1]); /* not here if both > 0 */ 193} 194 195static int pi_test_proto(PIA * pi, char *scratch, int verbose) 196{ 197 int res; 198 199 pi_claim(pi); 200 if (pi->proto->test_proto) 201 res = pi->proto->test_proto(pi, scratch, verbose); 202 else 203 res = default_test_proto(pi, scratch, verbose); 204 pi_unclaim(pi); 205 206 return res; 207} 208 209int paride_register(PIP * pr) 210{ 211 int k; 212 213 for (k = 0; k < MAX_PROTOS; k++) 214 if (protocols[k] && !strcmp(pr->name, protocols[k]->name)) { 215 printk("paride: %s protocol already registered\n", 216 pr->name); 217 return -1; 218 } 219 k = 0; 220 while ((k < MAX_PROTOS) && (protocols[k])) 221 k++; 222 if (k == MAX_PROTOS) { 223 printk("paride: protocol table full\n"); 224 return -1; 225 } 226 protocols[k] = pr; 227 pr->index = k; 228 printk("paride: %s registered as protocol %d\n", pr->name, k); 229 return 0; 230} 231 232EXPORT_SYMBOL(paride_register); 233 234void paride_unregister(PIP * pr) 235{ 236 if (!pr) 237 return; 238 if (protocols[pr->index] != pr) { 239 printk("paride: %s not registered\n", pr->name); 240 return; 241 } 242 protocols[pr->index] = NULL; 243} 244 245EXPORT_SYMBOL(paride_unregister); 246 247static int pi_register_parport(PIA * pi, int verbose) 248{ 249 struct parport *port; 250 251 port = parport_find_base(pi->port); 252 if (!port) 253 return 0; 254 255 pi->pardev = parport_register_device(port, 256 pi->device, NULL, 257 pi_wake_up, NULL, 0, (void *) pi); 258 parport_put_port(port); 259 if (!pi->pardev) 260 return 0; 261 262 init_waitqueue_head(&pi->parq); 263 264 if (verbose) 265 printk("%s: 0x%x is %s\n", pi->device, pi->port, port->name); 266 267 pi->parname = (char *) port->name; 268 269 return 1; 270} 271 272static int pi_probe_mode(PIA * pi, int max, char *scratch, int verbose) 273{ 274 int best, range; 275 276 if (pi->mode != -1) { 277 if (pi->mode >= max) 278 return 0; 279 range = 3; 280 if (pi->mode >= pi->proto->epp_first) 281 range = 8; 282 if ((range == 8) && (pi->port % 8)) 283 return 0; 284 pi->reserved = range; 285 return (!pi_test_proto(pi, scratch, verbose)); 286 } 287 best = -1; 288 for (pi->mode = 0; pi->mode < max; pi->mode++) { 289 range = 3; 290 if (pi->mode >= pi->proto->epp_first) 291 range = 8; 292 if ((range == 8) && (pi->port % 8)) 293 break; 294 pi->reserved = range; 295 if (!pi_test_proto(pi, scratch, verbose)) 296 best = pi->mode; 297 } 298 pi->mode = best; 299 return (best > -1); 300} 301 302static int pi_probe_unit(PIA * pi, int unit, char *scratch, int verbose) 303{ 304 int max, s, e; 305 306 s = unit; 307 e = s + 1; 308 309 if (s == -1) { 310 s = 0; 311 e = pi->proto->max_units; 312 } 313 314 if (!pi_register_parport(pi, verbose)) 315 return 0; 316 317 if (pi->proto->test_port) { 318 pi_claim(pi); 319 max = pi->proto->test_port(pi); 320 pi_unclaim(pi); 321 } else 322 max = pi->proto->max_mode; 323 324 if (pi->proto->probe_unit) { 325 pi_claim(pi); 326 for (pi->unit = s; pi->unit < e; pi->unit++) 327 if (pi->proto->probe_unit(pi)) { 328 pi_unclaim(pi); 329 if (pi_probe_mode(pi, max, scratch, verbose)) 330 return 1; 331 pi_unregister_parport(pi); 332 return 0; 333 } 334 pi_unclaim(pi); 335 pi_unregister_parport(pi); 336 return 0; 337 } 338 339 if (!pi_probe_mode(pi, max, scratch, verbose)) { 340 pi_unregister_parport(pi); 341 return 0; 342 } 343 return 1; 344 345} 346 347int pi_init(PIA * pi, int autoprobe, int port, int mode, 348 int unit, int protocol, int delay, char *scratch, 349 int devtype, int verbose, char *device) 350{ 351 int p, k, s, e; 352 int lpts[7] = { 0x3bc, 0x378, 0x278, 0x268, 0x27c, 0x26c, 0 }; 353 354 s = protocol; 355 e = s + 1; 356 357 if (!protocols[0]) 358 request_module("paride_protocol"); 359 360 if (autoprobe) { 361 s = 0; 362 e = MAX_PROTOS; 363 } else if ((s < 0) || (s >= MAX_PROTOS) || (port <= 0) || 364 (!protocols[s]) || (unit < 0) || 365 (unit >= protocols[s]->max_units)) { 366 printk("%s: Invalid parameters\n", device); 367 return 0; 368 } 369 370 for (p = s; p < e; p++) { 371 struct pi_protocol *proto = protocols[p]; 372 if (!proto) 373 continue; 374 /* still racy */ 375 if (!try_module_get(proto->owner)) 376 continue; 377 pi->proto = proto; 378 pi->private = 0; 379 if (proto->init_proto && proto->init_proto(pi) < 0) { 380 pi->proto = NULL; 381 module_put(proto->owner); 382 continue; 383 } 384 if (delay == -1) 385 pi->delay = pi->proto->default_delay; 386 else 387 pi->delay = delay; 388 pi->devtype = devtype; 389 pi->device = device; 390 391 pi->parname = NULL; 392 pi->pardev = NULL; 393 init_waitqueue_head(&pi->parq); 394 pi->claimed = 0; 395 pi->claim_cont = NULL; 396 397 pi->mode = mode; 398 if (port != -1) { 399 pi->port = port; 400 if (pi_probe_unit(pi, unit, scratch, verbose)) 401 break; 402 pi->port = 0; 403 } else { 404 k = 0; 405 while ((pi->port = lpts[k++])) 406 if (pi_probe_unit 407 (pi, unit, scratch, verbose)) 408 break; 409 if (pi->port) 410 break; 411 } 412 if (pi->proto->release_proto) 413 pi->proto->release_proto(pi); 414 module_put(proto->owner); 415 } 416 417 if (!pi->port) { 418 if (autoprobe) 419 printk("%s: Autoprobe failed\n", device); 420 else 421 printk("%s: Adapter not found\n", device); 422 return 0; 423 } 424 425 if (pi->parname) 426 printk("%s: Sharing %s at 0x%x\n", pi->device, 427 pi->parname, pi->port); 428 429 pi->proto->log_adapter(pi, scratch, verbose); 430 431 return 1; 432} 433 434EXPORT_SYMBOL(pi_init); 435