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

gscps2.c (11605B)


      1/*
      2 * drivers/input/serio/gscps2.c
      3 *
      4 * Copyright (c) 2004-2006 Helge Deller <deller@gmx.de>
      5 * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
      6 * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org>
      7 *
      8 * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
      9 *	Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca>
     10 *	Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
     11 *	Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
     12 *	Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
     13 *
     14 * HP GSC PS/2 port driver, found in PA/RISC Workstations
     15 *
     16 * This file is subject to the terms and conditions of the GNU General Public
     17 * License.  See the file "COPYING" in the main directory of this archive
     18 * for more details.
     19 *
     20 * TODO:
     21 * - Dino testing (did HP ever shipped a machine on which this port
     22 *                 was usable/enabled ?)
     23 */
     24
     25#include <linux/init.h>
     26#include <linux/module.h>
     27#include <linux/slab.h>
     28#include <linux/serio.h>
     29#include <linux/input.h>
     30#include <linux/interrupt.h>
     31#include <linux/spinlock.h>
     32#include <linux/delay.h>
     33#include <linux/ioport.h>
     34
     35#include <asm/irq.h>
     36#include <asm/io.h>
     37#include <asm/parisc-device.h>
     38
     39MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>");
     40MODULE_DESCRIPTION("HP GSC PS2 port driver");
     41MODULE_LICENSE("GPL");
     42
     43#define PFX "gscps2.c: "
     44
     45/*
     46 * Driver constants
     47 */
     48
     49/* various constants */
     50#define ENABLE			1
     51#define DISABLE			0
     52
     53#define GSC_DINO_OFFSET		0x0800	/* offset for DINO controller versus LASI one */
     54
     55/* PS/2 IO port offsets */
     56#define GSC_ID			0x00	/* device ID offset (see: GSC_ID_XXX) */
     57#define GSC_RESET		0x00	/* reset port offset */
     58#define GSC_RCVDATA		0x04	/* receive port offset */
     59#define GSC_XMTDATA		0x04	/* transmit port offset */
     60#define GSC_CONTROL		0x08	/* see: Control register bits */
     61#define GSC_STATUS		0x0C	/* see: Status register bits */
     62
     63/* Control register bits */
     64#define GSC_CTRL_ENBL		0x01	/* enable interface */
     65#define GSC_CTRL_LPBXR		0x02	/* loopback operation */
     66#define GSC_CTRL_DIAG		0x20	/* directly control clock/data line */
     67#define GSC_CTRL_DATDIR		0x40	/* data line direct control */
     68#define GSC_CTRL_CLKDIR		0x80	/* clock line direct control */
     69
     70/* Status register bits */
     71#define GSC_STAT_RBNE		0x01	/* Receive Buffer Not Empty */
     72#define GSC_STAT_TBNE		0x02	/* Transmit Buffer Not Empty */
     73#define GSC_STAT_TERR		0x04	/* Timeout Error */
     74#define GSC_STAT_PERR		0x08	/* Parity Error */
     75#define GSC_STAT_CMPINTR	0x10	/* Composite Interrupt = irq on any port */
     76#define GSC_STAT_DATSHD		0x40	/* Data Line Shadow */
     77#define GSC_STAT_CLKSHD		0x80	/* Clock Line Shadow */
     78
     79/* IDs returned by GSC_ID port register */
     80#define GSC_ID_KEYBOARD		0	/* device ID values */
     81#define GSC_ID_MOUSE		1
     82
     83
     84static irqreturn_t gscps2_interrupt(int irq, void *dev);
     85
     86#define BUFFER_SIZE 0x0f
     87
     88/* GSC PS/2 port device struct */
     89struct gscps2port {
     90	struct list_head node;
     91	struct parisc_device *padev;
     92	struct serio *port;
     93	spinlock_t lock;
     94	char __iomem *addr;
     95	u8 act, append; /* position in buffer[] */
     96	struct {
     97		u8 data;
     98		u8 str;
     99	} buffer[BUFFER_SIZE+1];
    100	int id;
    101};
    102
    103/*
    104 * Various HW level routines
    105 */
    106
    107#define gscps2_readb_input(x)		readb((x)+GSC_RCVDATA)
    108#define gscps2_readb_control(x)		readb((x)+GSC_CONTROL)
    109#define gscps2_readb_status(x)		readb((x)+GSC_STATUS)
    110#define gscps2_writeb_control(x, y)	writeb((x), (y)+GSC_CONTROL)
    111
    112
    113/*
    114 * wait_TBE() - wait for Transmit Buffer Empty
    115 */
    116
    117static int wait_TBE(char __iomem *addr)
    118{
    119	int timeout = 25000; /* device is expected to react within 250 msec */
    120	while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
    121		if (!--timeout)
    122			return 0;	/* This should not happen */
    123		udelay(10);
    124	}
    125	return 1;
    126}
    127
    128
    129/*
    130 * gscps2_flush() - flush the receive buffer
    131 */
    132
    133static void gscps2_flush(struct gscps2port *ps2port)
    134{
    135	while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
    136		gscps2_readb_input(ps2port->addr);
    137	ps2port->act = ps2port->append = 0;
    138}
    139
    140/*
    141 * gscps2_writeb_output() - write a byte to the port
    142 *
    143 * returns 1 on success, 0 on error
    144 */
    145
    146static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
    147{
    148	unsigned long flags;
    149	char __iomem *addr = ps2port->addr;
    150
    151	if (!wait_TBE(addr)) {
    152		printk(KERN_DEBUG PFX "timeout - could not write byte %#x\n", data);
    153		return 0;
    154	}
    155
    156	while (gscps2_readb_status(addr) & GSC_STAT_RBNE)
    157		/* wait */;
    158
    159	spin_lock_irqsave(&ps2port->lock, flags);
    160	writeb(data, addr+GSC_XMTDATA);
    161	spin_unlock_irqrestore(&ps2port->lock, flags);
    162
    163	/* this is ugly, but due to timing of the port it seems to be necessary. */
    164	mdelay(6);
    165
    166	/* make sure any received data is returned as fast as possible */
    167	/* this is important e.g. when we set the LEDs on the keyboard */
    168	gscps2_interrupt(0, NULL);
    169
    170	return 1;
    171}
    172
    173
    174/*
    175 * gscps2_enable() - enables or disables the port
    176 */
    177
    178static void gscps2_enable(struct gscps2port *ps2port, int enable)
    179{
    180	unsigned long flags;
    181	u8 data;
    182
    183	/* now enable/disable the port */
    184	spin_lock_irqsave(&ps2port->lock, flags);
    185	gscps2_flush(ps2port);
    186	data = gscps2_readb_control(ps2port->addr);
    187	if (enable)
    188		data |= GSC_CTRL_ENBL;
    189	else
    190		data &= ~GSC_CTRL_ENBL;
    191	gscps2_writeb_control(data, ps2port->addr);
    192	spin_unlock_irqrestore(&ps2port->lock, flags);
    193	wait_TBE(ps2port->addr);
    194	gscps2_flush(ps2port);
    195}
    196
    197/*
    198 * gscps2_reset() - resets the PS/2 port
    199 */
    200
    201static void gscps2_reset(struct gscps2port *ps2port)
    202{
    203	unsigned long flags;
    204
    205	/* reset the interface */
    206	spin_lock_irqsave(&ps2port->lock, flags);
    207	gscps2_flush(ps2port);
    208	writeb(0xff, ps2port->addr + GSC_RESET);
    209	gscps2_flush(ps2port);
    210	spin_unlock_irqrestore(&ps2port->lock, flags);
    211}
    212
    213static LIST_HEAD(ps2port_list);
    214
    215/**
    216 * gscps2_interrupt() - Interruption service routine
    217 *
    218 * This function reads received PS/2 bytes and processes them on
    219 * all interfaces.
    220 * The problematic part here is, that the keyboard and mouse PS/2 port
    221 * share the same interrupt and it's not possible to send data if any
    222 * one of them holds input data. To solve this problem we try to receive
    223 * the data as fast as possible and handle the reporting to the upper layer
    224 * later.
    225 */
    226
    227static irqreturn_t gscps2_interrupt(int irq, void *dev)
    228{
    229	struct gscps2port *ps2port;
    230
    231	list_for_each_entry(ps2port, &ps2port_list, node) {
    232
    233	  unsigned long flags;
    234	  spin_lock_irqsave(&ps2port->lock, flags);
    235
    236	  while ( (ps2port->buffer[ps2port->append].str =
    237		   gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
    238		ps2port->buffer[ps2port->append].data =
    239				gscps2_readb_input(ps2port->addr);
    240		ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
    241	  }
    242
    243	  spin_unlock_irqrestore(&ps2port->lock, flags);
    244
    245	} /* list_for_each_entry */
    246
    247	/* all data was read from the ports - now report the data to upper layer */
    248
    249	list_for_each_entry(ps2port, &ps2port_list, node) {
    250
    251	  while (ps2port->act != ps2port->append) {
    252
    253	    unsigned int rxflags;
    254	    u8 data, status;
    255
    256	    /* Did new data arrived while we read existing data ?
    257	       If yes, exit now and let the new irq handler start over again */
    258	    if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
    259		return IRQ_HANDLED;
    260
    261	    status = ps2port->buffer[ps2port->act].str;
    262	    data   = ps2port->buffer[ps2port->act].data;
    263
    264	    ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
    265	    rxflags =	((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
    266			((status & GSC_STAT_PERR) ? SERIO_PARITY  : 0 );
    267
    268	    serio_interrupt(ps2port->port, data, rxflags);
    269
    270	  } /* while() */
    271
    272	} /* list_for_each_entry */
    273
    274	return IRQ_HANDLED;
    275}
    276
    277
    278/*
    279 * gscps2_write() - send a byte out through the aux interface.
    280 */
    281
    282static int gscps2_write(struct serio *port, unsigned char data)
    283{
    284	struct gscps2port *ps2port = port->port_data;
    285
    286	if (!gscps2_writeb_output(ps2port, data)) {
    287		printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
    288		return -1;
    289	}
    290	return 0;
    291}
    292
    293/*
    294 * gscps2_open() is called when a port is opened by the higher layer.
    295 * It resets and enables the port.
    296 */
    297
    298static int gscps2_open(struct serio *port)
    299{
    300	struct gscps2port *ps2port = port->port_data;
    301
    302	gscps2_reset(ps2port);
    303
    304	/* enable it */
    305	gscps2_enable(ps2port, ENABLE);
    306
    307	gscps2_interrupt(0, NULL);
    308
    309	return 0;
    310}
    311
    312/*
    313 * gscps2_close() disables the port
    314 */
    315
    316static void gscps2_close(struct serio *port)
    317{
    318	struct gscps2port *ps2port = port->port_data;
    319	gscps2_enable(ps2port, DISABLE);
    320}
    321
    322/**
    323 * gscps2_probe() - Probes PS2 devices
    324 * @return: success/error report
    325 */
    326
    327static int __init gscps2_probe(struct parisc_device *dev)
    328{
    329	struct gscps2port *ps2port;
    330	struct serio *serio;
    331	unsigned long hpa = dev->hpa.start;
    332	int ret;
    333
    334	if (!dev->irq)
    335		return -ENODEV;
    336
    337	/* Offset for DINO PS/2. Works with LASI even */
    338	if (dev->id.sversion == 0x96)
    339		hpa += GSC_DINO_OFFSET;
    340
    341	ps2port = kzalloc(sizeof(struct gscps2port), GFP_KERNEL);
    342	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
    343	if (!ps2port || !serio) {
    344		ret = -ENOMEM;
    345		goto fail_nomem;
    346	}
    347
    348	dev_set_drvdata(&dev->dev, ps2port);
    349
    350	ps2port->port = serio;
    351	ps2port->padev = dev;
    352	ps2port->addr = ioremap(hpa, GSC_STATUS + 4);
    353	spin_lock_init(&ps2port->lock);
    354
    355	gscps2_reset(ps2port);
    356	ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
    357
    358	snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
    359		 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
    360	strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
    361	serio->id.type		= SERIO_8042;
    362	serio->write		= gscps2_write;
    363	serio->open		= gscps2_open;
    364	serio->close		= gscps2_close;
    365	serio->port_data	= ps2port;
    366	serio->dev.parent	= &dev->dev;
    367
    368	ret = -EBUSY;
    369	if (request_irq(dev->irq, gscps2_interrupt, IRQF_SHARED, ps2port->port->name, ps2port))
    370		goto fail_miserably;
    371
    372	if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
    373		printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
    374				hpa, ps2port->id);
    375		ret = -ENODEV;
    376		goto fail;
    377	}
    378
    379#if 0
    380	if (!request_mem_region(hpa, GSC_STATUS + 4, ps2port->port.name))
    381		goto fail;
    382#endif
    383
    384	pr_info("serio: %s port at 0x%08lx irq %d @ %s\n",
    385		ps2port->port->name,
    386		hpa,
    387		ps2port->padev->irq,
    388		ps2port->port->phys);
    389
    390	serio_register_port(ps2port->port);
    391
    392	list_add_tail(&ps2port->node, &ps2port_list);
    393
    394	return 0;
    395
    396fail:
    397	free_irq(dev->irq, ps2port);
    398
    399fail_miserably:
    400	iounmap(ps2port->addr);
    401	release_mem_region(dev->hpa.start, GSC_STATUS + 4);
    402
    403fail_nomem:
    404	kfree(ps2port);
    405	kfree(serio);
    406	return ret;
    407}
    408
    409/**
    410 * gscps2_remove() - Removes PS2 devices
    411 * @return: success/error report
    412 */
    413
    414static void __exit gscps2_remove(struct parisc_device *dev)
    415{
    416	struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
    417
    418	serio_unregister_port(ps2port->port);
    419	free_irq(dev->irq, ps2port);
    420	gscps2_flush(ps2port);
    421	list_del(&ps2port->node);
    422	iounmap(ps2port->addr);
    423#if 0
    424	release_mem_region(dev->hpa, GSC_STATUS + 4);
    425#endif
    426	dev_set_drvdata(&dev->dev, NULL);
    427	kfree(ps2port);
    428}
    429
    430
    431static const struct parisc_device_id gscps2_device_tbl[] __initconst = {
    432	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
    433#ifdef DINO_TESTED
    434	{ HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
    435#endif
    436	{ 0, }	/* 0 terminated list */
    437};
    438MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
    439
    440static struct parisc_driver parisc_ps2_driver __refdata = {
    441	.name		= "gsc_ps2",
    442	.id_table	= gscps2_device_tbl,
    443	.probe		= gscps2_probe,
    444	.remove		= __exit_p(gscps2_remove),
    445};
    446
    447static int __init gscps2_init(void)
    448{
    449	register_parisc_driver(&parisc_ps2_driver);
    450	return 0;
    451}
    452
    453static void __exit gscps2_exit(void)
    454{
    455	unregister_parisc_driver(&parisc_ps2_driver);
    456}
    457
    458
    459module_init(gscps2_init);
    460module_exit(gscps2_exit);
    461