cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

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