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

Changeset cbc3587 in mainline


Ignore:
Timestamp:
2018-09-21T21:01:00Z (4 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial
Children:
631281d
Parents:
8591b31
Message:

Remove infinite loops from kernel ns16550 driver

Replace potential infinite loops by loops with large number of
iterations. This prevents the kernel from hanging when there is no
ns16550 device and the kernel is configured with ns16550 support.

File:
1 edited

Legend:

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

    r8591b31 rcbc3587  
    4747#define LSR_TH_READY    0x20
    4848
     49#define RETRY_CNT       100000
     50
     51#define NOTHING \
     52        do { \
     53        } while(0)
     54
     55#define WHILE_CNT_AND_COND_DO(cnt, expr, statement) \
     56        do { \
     57                for (volatile unsigned i = 0; i < (cnt); i++) \
     58                        if ((expr)) \
     59                                statement; \
     60                        else \
     61                                break; \
     62        } while (0)
     63
    4964static uint8_t ns16550_reg_read(ns16550_instance_t *inst, ns16550_reg_t reg)
    5065{
     
    7893}
    7994
    80 /**< Clear input buffer. */
     95/** Clear input buffer. */
    8196static void ns16550_clear_buffer(ns16550_instance_t *instance)
    8297{
    83         while (ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_DATA_READY)
    84                 (void) ns16550_reg_read(instance, NS16550_REG_RBR);
     98        WHILE_CNT_AND_COND_DO(RETRY_CNT,
     99            ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_DATA_READY,
     100            (void) ns16550_reg_read(instance, NS16550_REG_RBR));
    85101}
    86102
    87103static void ns16550_sendb(ns16550_instance_t *instance, uint8_t byte)
    88104{
    89         while (!(ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_TH_READY))
    90                 ;
     105        WHILE_CNT_AND_COND_DO(RETRY_CNT,
     106            !(ns16550_reg_read(instance, NS16550_REG_LSR) & LSR_TH_READY),
     107            NOTHING);
     108
    91109        ns16550_reg_write(instance, NS16550_REG_THR, byte);
    92110}
Note: See TracChangeset for help on using the changeset viewer.