diff options
author | Vitaly Bordug <vbordug@ru.mvista.com> | 2006-04-25 20:26:46 +0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-04-28 21:11:33 +1000 |
commit | 09b03b6c29638eb5c79b02e585cb1b20d91a8ea0 (patch) | |
tree | c6348427c9b785a90db7f87d55903c6b75804170 /drivers/serial/cpm_uart/cpm_uart.h | |
parent | 4427d6bf966379304f77b7cc8c92421e6bb95483 (diff) | |
download | linux-09b03b6c29638eb5c79b02e585cb1b20d91a8ea0.tar.gz linux-09b03b6c29638eb5c79b02e585cb1b20d91a8ea0.tar.bz2 linux-09b03b6c29638eb5c79b02e585cb1b20d91a8ea0.zip |
[PATCH] ppc32 CPM_UART: Fixed odd address translations
Current address translation methods can produce wrong results, because
virt_to_bus and vice versa may not produce correct offsets on dma-allocated
memory. The right way is, while tracking both phys and virt address of the
window that has been allocated for boffer descriptors, and use those
numbers to compute the offset and make translation properly.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'drivers/serial/cpm_uart/cpm_uart.h')
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 17f2c7aa4503..aa5eb7ddeda9 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -66,6 +66,7 @@ struct uart_cpm_port { uint dp_addr; void *mem_addr; dma_addr_t dma_addr; + u32 mem_size; /* helpers */ int baud; int bits; @@ -92,4 +93,36 @@ void scc2_lineif(struct uart_cpm_port *pinfo); void scc3_lineif(struct uart_cpm_port *pinfo); void scc4_lineif(struct uart_cpm_port *pinfo); +/* + virtual to phys transtalion +*/ +static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo) +{ + int offset; + u32 val = (u32)addr; + /* sane check */ + if ((val >= (u32)pinfo->mem_addr) && + (val<((u32)pinfo->mem_addr + pinfo->mem_size))) { + offset = val - (u32)pinfo->mem_addr; + return pinfo->dma_addr+offset; + } + printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val); + return 0; +} + +static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo) +{ + int offset; + u32 val = addr; + /* sane check */ + if ((val >= pinfo->dma_addr) && + (val<(pinfo->dma_addr + pinfo->mem_size))) { + offset = val - (u32)pinfo->dma_addr; + return (void*)(pinfo->mem_addr+offset); + } + printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val); + return 0; +} + + #endif /* CPM_UART_H */ |