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: Andrey Moiseev <o2g.org.ru@gmail.com> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
Родитель
049d75f72d
Коммит
2f0d260413
|
@ -223,21 +223,26 @@ static int i8042_flush(void)
|
|||
{
|
||||
unsigned long flags;
|
||||
unsigned char data, str;
|
||||
int i = 0;
|
||||
int count = 0;
|
||||
int retval = 0;
|
||||
|
||||
spin_lock_irqsave(&i8042_lock, flags);
|
||||
|
||||
while (((str = i8042_read_status()) & I8042_STR_OBF) && (i < I8042_BUFFER_SIZE)) {
|
||||
udelay(50);
|
||||
data = i8042_read_data();
|
||||
i++;
|
||||
dbg("%02x <- i8042 (flush, %s)\n",
|
||||
data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
|
||||
while ((str = i8042_read_status()) & I8042_STR_OBF) {
|
||||
if (count++ < I8042_BUFFER_SIZE) {
|
||||
udelay(50);
|
||||
data = i8042_read_data();
|
||||
dbg("%02x <- i8042 (flush, %s)\n",
|
||||
data, str & I8042_STR_AUXDATA ? "aux" : "kbd");
|
||||
} else {
|
||||
retval = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (i8042_flush() == I8042_BUFFER_SIZE) {
|
||||
if (i8042_flush()) {
|
||||
pr_err("No controller found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче