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);
480