Changeset 4f1173bc in rtems for c/src/libchip/serial/ns16550.c


Ignore:
Timestamp:
Feb 23, 2012, 4:40:33 PM (9 years ago)
Author:
Jennifer Averett <jennifer.averett@…>
Branches:
4.11, 5, master
Children:
8f7f6ca
Parents:
6903c7cd
Message:

Avoid NULL dereference in printk() before libchip console initialized

With the addition of dynamically registered libchip serial devices,
there is the need to be able to use printk() before the console driver
has initialized the indirect pointer table. This lets printk() support
routines call pass a control structure directly without a lookup through
the uninitialized indirect one.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/libchip/serial/ns16550.c

    r6903c7cd r4f1173bc  
    1 /*
     1/**
     2 *  @file
     3 * 
    24 *  This file contains the TTY driver for the National Semiconductor NS16550.
    35 *
     
    57 *  of "Super IO" controllers.
    68 *
     9 *  This driver uses the termios pseudo driver.
     10 */
     11
     12/*
    713 *  COPYRIGHT (c) 1998 by Radstone Technology
    814 *
    9  *
    10  * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
    11  * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
    12  * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
    13  * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
    14  *
    15  * You are hereby granted permission to use, copy, modify, and distribute
    16  * this file, provided that this notice, plus the above copyright notice
    17  * and disclaimer, appears in all copies. Radstone Technology will provide
    18  * no support for this code.
    19  *
    20  *  This driver uses the termios pseudo driver.
    21  */
    22 
    23 /*
    24  * $Id$
     15 *  THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
     16 *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
     17 *  IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
     18 *  AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
     19 *
     20 *  You are hereby granted permission to use, copy, modify, and distribute
     21 *  this file, provided that this notice, plus the above copyright notice
     22 *  and disclaimer, appears in all copies. Radstone Technology will provide
     23 *  no support for this code.
     24 *
     25 *  COPYRIGHT (c) 1989-2012.
     26 *  On-Line Applications Research Corporation (OAR).
     27 *
     28 *  The license and distribution terms for this file may be
     29 *  found in the file LICENSE in this distribution or at
     30 *  http://www.rtems.com/license/LICENSE.
     31 *
     32 *  $Id$
    2533 */
    2634
     
    102110  setRegister_f           setReg;
    103111  getRegister_f           getReg;
     112  console_tbl             *c = Console_Port_Tbl [minor];
    104113
    105114  pns16550Context=(ns16550_context *)malloc(sizeof(ns16550_context));
     
    113122  pns16550Context->ucModemCtrl=SP_MODEM_IRQ;
    114123
    115   pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
    116   setReg   = Console_Port_Tbl[minor]->setRegister;
    117   getReg   = Console_Port_Tbl[minor]->getRegister;
     124  pNS16550 = c->ulCtrlPort1;   
     125  setReg   = c->setRegister;
     126  getReg   = c->getRegister;
    118127
    119128  /* Clear the divisor latch, clear all interrupt enables,
     
    123132
    124133  (*setReg)(pNS16550, NS16550_LINE_CONTROL, 0x0);
    125   ns16550_enable_interrupts(minor, NS16550_DISABLE_ALL_INTR);
     134  ns16550_enable_interrupts( c, NS16550_DISABLE_ALL_INTR );
    126135
    127136  /* Set the divisor latch and set the baud rate. */
    128137
    129138  ulBaudDivisor = NS16550_Baud(
    130     (uint32_t) Console_Port_Tbl[minor]->ulClock,
    131     (uint32_t) ((uintptr_t)Console_Port_Tbl[minor]->pDeviceParams)
     139    (uint32_t) c->ulClock,
     140    (uint32_t) ((uintptr_t)c->pDeviceParams)
    132141  );
    133142  ucDataByte = SP_LINE_DLAB;
     
    135144
    136145  /* XXX */
    137   (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, (uint8_t) (ulBaudDivisor & 0xffU));
    138   (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (uint8_t) ((ulBaudDivisor >> 8) & 0xffU));
     146  (*setReg)(pNS16550,NS16550_TRANSMIT_BUFFER,(uint8_t)(ulBaudDivisor & 0xffU));
     147  (*setReg)(
     148    pNS16550,NS16550_INTERRUPT_ENABLE,
     149    (uint8_t)(( ulBaudDivisor >> 8 ) & 0xffU )
     150  );
    139151
    140152  /* Clear the divisor latch and set the character size to eight bits */
     
    150162  (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
    151163
    152   ns16550_enable_interrupts(minor, NS16550_DISABLE_ALL_INTR);
     164  ns16550_enable_interrupts(c, NS16550_DISABLE_ALL_INTR);
    153165
    154166  /* Set data terminal ready. */
     
    187199  if (c->pDeviceFns->deviceOutputUsesInterrupts) {
    188200    ns16550_initialize_interrupts( minor);
    189     ns16550_enable_interrupts( minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
     201    ns16550_enable_interrupts( c, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
    190202  }
    191203
     
    212224  }
    213225
    214   ns16550_enable_interrupts(minor, NS16550_DISABLE_ALL_INTR);
     226  ns16550_enable_interrupts(c, NS16550_DISABLE_ALL_INTR);
    215227
    216228  if (c->pDeviceFns->deviceOutputUsesInterrupts) {
     
    224236 * @brief Polled write for NS16550.
    225237 */
    226 NS16550_STATIC void ns16550_write_polled(int minor, char out)
    227 {
    228   console_tbl *c = Console_Port_Tbl [minor];
     238void ns16550_outch_polled(console_tbl *c, char out)
     239{
    229240  uintptr_t port = c->ulCtrlPort1;
    230241  getRegister_f get = c->getRegister;
     
    237248
    238249  /* Disable port interrupts */
    239   ns16550_enable_interrupts( minor, NS16550_DISABLE_ALL_INTR);
     250  ns16550_enable_interrupts( c, NS16550_DISABLE_ALL_INTR);
    240251
    241252  while (true) {
     
    264275  /* Restore port interrupt mask */
    265276  set( port, NS16550_INTERRUPT_ENABLE, interrupt_mask);
     277}
     278
     279NS16550_STATIC void ns16550_write_polled(int minor, char out)
     280{
     281  console_tbl *c = Console_Port_Tbl [minor];
     282 
     283  ns16550_outch_polled( c, out );
    266284}
    267285
     
    522540        /* Nothing to do */
    523541        d->bActive = false;
    524         ns16550_enable_interrupts( minor, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
     542        ns16550_enable_interrupts( c, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
    525543      }
    526544    }
     
    559577    ctx->transmitFifoChars = out;
    560578    d->bActive = true;
    561     ns16550_enable_interrupts( minor, NS16550_ENABLE_ALL_INTR);
     579    ns16550_enable_interrupts( c, NS16550_ENABLE_ALL_INTR);
    562580  }
    563581
     
    571589 */
    572590NS16550_STATIC void ns16550_enable_interrupts(
    573   int minor,
    574   int mask
     591  console_tbl *c,
     592  int         mask
    575593)
    576594{
     
    578596  setRegister_f  setReg;
    579597
    580   pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
    581   setReg   = Console_Port_Tbl[minor]->setRegister;
     598  pNS16550 = c->ulCtrlPort1;
     599  setReg   = c->setRegister;
    582600
    583601  (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, mask);
     
    722740
    723741/*
    724  *  ns16550_inbyte_nonblocking_polled
    725  *
    726  *  Console Termios polling input entry point.
    727  */
    728 
    729 NS16550_STATIC int ns16550_inbyte_nonblocking_polled(
    730   int minor
     742 *  Debug gets() support
     743 */
     744int ns16550_inch_polled(
     745  console_tbl *c
    731746)
    732747{
     
    736751  getRegister_f        getReg;
    737752
    738   pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
    739   getReg   = Console_Port_Tbl[minor]->getRegister;
     753  pNS16550 = c->ulCtrlPort1;
     754  getReg   = c->getRegister;
    740755
    741756  ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
    742   if(ucLineStatus & SP_LSR_RDY) {
     757  if (ucLineStatus & SP_LSR_RDY) {
    743758    cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
    744759    return (int)cChar;
    745   } else {
    746     return -1;
    747   }
    748 }
     760  }
     761  return -1;
     762}
     763
     764/*
     765 *  ns16550_inbyte_nonblocking_polled
     766 *
     767 *  Console Termios polling input entry point.
     768 */
     769NS16550_STATIC int ns16550_inbyte_nonblocking_polled(int minor)
     770{
     771  console_tbl *c = Console_Port_Tbl [minor];
     772 
     773  return ns16550_inch_polled( c );
     774}
Note: See TracChangeset for help on using the changeset viewer.