Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 1adbf90 in mainline


Ignore:
Timestamp:
2011-12-08T14:09:24Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
28f8f170, c5ebb59
Parents:
190c943
Message:

make the i8042 driver just a slightly more robust
(timeout if the device is not behaving as expected to avoid infinite loop)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/drivers/i8042/i8042.c

    r190c943 r1adbf90  
    4444#include <mm/slab.h>
    4545#include <ddi/device.h>
     46#include <time/delay.h>
    4647
    4748#define i8042_SET_COMMAND  0x60
     
    5152#define i8042_BUFFER_FULL_MASK  0x01
    5253#define i8042_WAIT_MASK         0x02
     54
     55#define i8042_TIMEOUT  65536
    5356
    5457static irq_ownership_t i8042_claim(irq_t *irq)
     
    7780static void i8042_clear_buffer(i8042_t *dev)
    7881{
    79         while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
     82        for (uint32_t i = 0; i < i8042_TIMEOUT; i++) {
     83                if ((pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK) == 0)
     84                        break;
     85               
    8086                (void) pio_read_8(&dev->data);
     87                delay(50);  /* 50 us think time */
     88        }
     89}
     90
     91static void i8042_send_command(i8042_t *dev, uint8_t cmd)
     92{
     93        for (uint32_t i = 0; i < i8042_TIMEOUT; i++) {
     94                if ((pio_read_8(&dev->status) & i8042_WAIT_MASK) == 0)
     95                        break;
     96               
     97                delay(50);  /* 50 us think time */
     98        }
     99       
     100        pio_write_8(&dev->status, cmd);
     101        delay(10000);  /* 10 ms think time */
    81102}
    82103
     
    84105i8042_instance_t *i8042_init(i8042_t *dev, inr_t inr)
    85106{
    86         i8042_instance_t *instance
    87             = malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
     107        i8042_instance_t *instance =
     108            malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
    88109        if (instance) {
    89110                instance->i8042 = dev;
     
    96117                instance->irq.handler = i8042_irq_handler;
    97118                instance->irq.instance = instance;
    98                
    99119        }
    100120       
     
    107127        ASSERT(kbrdin);
    108128       
     129        i8042_clear_buffer(instance->i8042);
     130       
    109131        instance->kbrdin = kbrdin;
    110132        irq_register(&instance->irq);
    111         i8042_clear_buffer(instance->i8042);
    112133}
    113134
     
    116137{
    117138        interrupts_disable();
    118        
    119139        i8042_clear_buffer(dev);
    120        
    121         /* Reset CPU */
    122         pio_write_8(&dev->status, i8042_CPU_RESET);
     140        i8042_send_command(dev, i8042_CPU_RESET);
    123141}
    124142
Note: See TracChangeset for help on using the changeset viewer.