• Paul Fulghum's avatar
    serial: synclink_gt: dropped transmit data bugfix · de538eb3
    Paul Fulghum authored
    Fix transmit bug that could drop send data if write() called close to
    serial transmitter going idle after sending previous data.  Bug is caused
    by incorrect use of device information member tx_count.
    
    Driver originally processed one data block (write call) at a time, waiting
    for transmit idle before sending more.  tx_count recorded how much data
    was loaded in DMA buffers on write(), and was cleared on send completion. 
    tx_count use was overloaded to record accumulated data from put_char()
    callback when transmitter was idle.
    
    A bug was introduced when transmit code was reworked to allow multiple
    blocks of data in the tx DMA buffers which keeps transmitter from going
    idle between blocks.  tx_count was set to size of last block loaded,
    cleared when tx went idle, and monitored to know when to restart
    transmitter without proper synchronization.  tx_count could be cleared
    when unsent data remained in DMA buffers and transmitter required
    restarting, effectively dropping unsent data.
    
    Solution:
    1. tx_count now used only to track accumulated data from put_char
    2. DMA buffer state tracked by direct inspection of descriptors
       with spinlock synchronization
    3. consolidate these tasks in tx_load() :
       a. check for available buffer space
       b. load buffers
       c. restart DMA and or serial transmitter as needed
       These steps were previously duplicated in multiple places,
       sometimes incompletely.
    4. fix use of tx_count as active transmit indicator,
       instead using tx_active which is meant for that purpose
    Signed-off-by: default avatarPaul Fulghum <paulkf@microgate.com>
    Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
    Cc: Greg KH <greg@kroah.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    de538eb3
synclink_gt.c 129 KB