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