Re: [PATCH 5/6] serial: 8250: Extract IIR logic steering from rx dma

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 04/12/2016 08:30 AM, Sebastian Andrzej Siewior wrote:
> On 04/10/2016 07:14 AM, Peter Hurley wrote:
>> --- a/drivers/tty/serial/8250/8250_omap.c
>> +++ b/drivers/tty/serial/8250/8250_omap.c
>> @@ -812,35 +818,6 @@ static int omap_8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
>>  	struct dma_async_tx_descriptor  *desc;
>>  	unsigned long			flags;
>>  
>> -	switch (iir & 0x3f) {
>> -	case UART_IIR_RLSI:
>> -		/* 8250_core handles errors and break interrupts */
>> -		omap_8250_rx_dma_flush(p);
>> -		return -EIO;
>> -	case UART_IIR_RX_TIMEOUT:
>> -		/*
>> -		 * If RCVR FIFO trigger level was not reached, complete the
>> -		 * transfer and let 8250_core copy the remaining data.
>> -		 */
>> -		omap_8250_rx_dma_flush(p);
>> -		return -ETIMEDOUT;
>> -	case UART_IIR_RDI:
>> -		/*
>> -		 * The OMAP UART is a special BEAST. If we receive RDI we _have_
>> -		 * a DMA transfer programmed but it didn't work. One reason is
>> -		 * that we were too slow and there were too many bytes in the
>> -		 * FIFO, the UART counted wrong and never kicked the DMA engine
>> -		 * to do anything. That means once we receive RDI on OMAP then
>> -		 * the DMA won't do anything soon so we have to cancel the DMA
>> -		 * transfer and purge the FIFO manually.
>> -		 */
>> -		omap_8250_rx_dma_flush(p);
>> -		return -ETIMEDOUT;
>> -
>> -	default:
>> -		break;
>> -	}
>> -
>>  	if (priv->rx_dma_broken)
>>  		return -EINVAL;
>>  
>> @@ -1014,6 +991,18 @@ err:
>>  	return ret;
>>  }
>>  
>> +static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
>> +{
>> +	switch (iir & 0x3f) {
>> +	case UART_IIR_RLSI:
>> +	case UART_IIR_RX_TIMEOUT:
>> +	case UART_IIR_RDI:
> 
> So you think that it is not worth to preserve the comments we had here?

Well, the UART_IIR_RDI comment is wrong so I didn't want to preserve that,
and the UART_IIR_RX_TIMEOUT is the same thing that happens with the
base 8250 dma handling as well, so I didn't see the point.

The UART_IIR_RDI interrupt happens because:

1) The programmed DMA transfer has completed
2) But the DMA completion handler hasn't run yet because the virt-dma
   tasklet hasn't run yet because of the softirq priority inversion
   http://www.gossamer-threads.com/lists/engine?do=post_view_flat;post=2381467;page=1;sb=post_latest_reply;so=ASC;mh=25;list=linux
3) in the meantime, data has continued to arrive until the fifo is refilled
   which triggers the UART_IIR_RDI

Which is ironic because the UART_IIR_RDI is normally what we want to
actually happen because that is the dma transaction flow expected by
the base 8250 dma handling.

> 
>> +		omap_8250_rx_dma_flush(up);
>> +		return true;
>> +	}
>> +	return omap_8250_rx_dma(up);
>> +}
>> +
>>  /*
>>   * This is mostly serial8250_handle_irq(). We have a slightly different DMA
>>   * hoook for RX/TX and need different logic for them in the ISR. Therefore we
> 
> Sebastian
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-serial" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux