Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f0d2604 authored by Andrey Moiseev's avatar Andrey Moiseev Committed by Dmitry Torokhov
Browse files

Input: i8042 - i8042_flush fix for a full 8042 buffer



When 8042 internal data buffer is full, the driver
erroneously decides that the controller is not present.

i8042_flush returns the number of flushed bytes, which is
in 0 - I8042_BUFFER_SIZE range inclusive. Therefore, i8042_flush
has no way to indicate an error. Moreover i8042_controller_check
takes initially full buffer (i8042_flush returned
I8042_BUFFER_SIZE) as a sign of absence of the controller.

Let's change i8042 to return success/error instead and make sure
we do not return error prematurely.

Signed-off-by: default avatarAndrey Moiseev <o2g.org.ru@gmail.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 049d75f7
Loading
Loading
Loading
Loading
+14 −9
Original line number Original line Diff line number Diff line
@@ -223,21 +223,26 @@ static int i8042_flush(void)
{
{
	unsigned long flags;
	unsigned long flags;
	unsigned char data, str;
	unsigned char data, str;
	int i = 0;
	int count = 0;
	int retval = 0;


	spin_lock_irqsave(&i8042_lock, flags);
	spin_lock_irqsave(&i8042_lock, flags);


	while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) {
	while ((str = i8042_read_status()) & I8042_STR_OBF) {
		if (count++ < I8042_BUFFER_SIZE) {
			udelay(50);
			udelay(50);
			data = i8042_read_data();
			data = i8042_read_data();
		i++;
			dbg("%02x <- i8042 (flush, %s)\n",
			dbg("%02x <- i8042 (flush, %s)\n",
			    data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
			    data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
		} else {
			retval = -EIO;
			break;
		}
	}
	}


	spin_unlock_irqrestore(&i8042_lock, flags);
	spin_unlock_irqrestore(&i8042_lock, flags);


	return i;
	return retval;
}
}


/*
/*
@@ -849,7 +854,7 @@ static int __init i8042_check_aux(void)


static int i8042_controller_check(void)
static int i8042_controller_check(void)
{
{
	if (i8042_flush() == I8042_BUFFER_SIZE) {
	if (i8042_flush()) {
		pr_err("No controller found\n");
		pr_err("No controller found\n");
		return -ENODEV;
		return -ENODEV;
	}
	}