Is this problem below solved in a better way for other boards that I can use as a template for the dbau1500be?
With the dbau1500be I'm currently using the ugly patch below so that both pci/ide/harddisk and localbus/pcmcia/ide/cf work at the same time.
Looks like the problem I'm running into is that pci is LE and pcmcia is BE. Since the ide code is common it will do software swap for both cases or neither case. Since one is LE and the other BE, one is always in correct byte order and the other is the wrong byte order. What I need is to be able to swap in one case but not the other.
The patch below modifies the common code so that it knows the pcmcia i/o range and corrects the byte order in that case.
The only BE bit I found for the dbau1500be pcmcia is read-only and the manual say not to be used with pcmcia. I verified this bit is not set and attempting to set this bit doesn't have any effect. I'm familiar with the rbhma4300 which has a similar setup, but does have a pcmcia BE bit, and does not have this problem.
=================================================================== --- drivers/pcmcia/au1000_generic.c +++ drivers/pcmcia/au1000_generic.c @@ -59,11 +59,17 @@ static int pc_debug; #endif
+#ifndef CONFIG_CPU_LITTLE_ENDIAN +u32 dbau1500be_pcmcia_base; +u32 dbau1500be_pcmcia_stop; +#endif + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Pete Popov, MontaVista Software <ppopov@xxxxxxxxxx>"); MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller"); @@ -225,6 +231,12 @@ } #endif } + #ifndef CONFIG_CPU_LITTLE_ENDIAN + dbau1500be_pcmcia_base = pcmcia_socket[0].virt_io; + dbau1500be_pcmcia_stop = pcmcia_socket[socket_count-1].virt_io + 0x1000; + #endif
/* Only advertise as many sockets as we can detect: */ if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){ =================================================================== --- include/asm-mips/ide.h +++ include/asm-mips/ide.h @@ -163,9 +163,19 @@ #define outsw(port, addr, count) ide_outsw(port, addr, count) #define outsl(port, addr, count) ide_outsl(port, addr, count)
+#ifdef CONFIG_MIPS_DB1500 +extern u32 dbau1500be_pcmcia_base; +extern u32 dbau1500be_pcmcia_stop; +#endif + static inline void ide_insw(unsigned long port, void *addr, unsigned int count) { while (count--) { + #ifdef CONFIG_MIPS_DB1500 + if ( ( port >= dbau1500be_pcmcia_base ) && ( port < dbau1500be_pcmcia_stop ) ) + *(u16 *)addr = le16_to_cpu(*(volatile u16 *)(mips_io_port_base + port)); + else + #endif *(u16 *)addr = *(volatile u16 *)(mips_io_port_base + port); addr += 2; } @@ -174,6 +184,11 @@ static inline void ide_outsw(unsigned long port, void *addr, unsigned int count) { while (count--) { + #ifdef CONFIG_MIPS_DB1500 + if ( ( port >= dbau1500be_pcmcia_base ) && ( port < dbau1500be_pcmcia_stop ) ) + *(volatile u16 *)(mips_io_port_base + (port)) = cpu_to_le16(*(u16 *)addr); + else + #endif *(volatile u16 *)(mips_io_port_base + (port)) = *(u16 *)addr; addr += 2; } @@ -182,6 +197,11 @@ static inline void ide_insl(unsigned long port, void *addr, unsigned int count) { while (count--) { + #ifdef CONFIG_MIPS_DB1500 + if ( ( port >= dbau1500be_pcmcia_base ) && ( port < dbau1500be_pcmcia_stop ) ) + *(u32 *)addr = le32_to_cpu(*(volatile u32 *)(mips_io_port_base + port)); + else + #endif *(u32 *)addr = *(volatile u32 *)(mips_io_port_base + port); addr += 4; } @@ -190,6 +210,11 @@ static inline void ide_outsl(unsigned long port, void *addr, unsigned int count) { while (count--) { + #ifdef CONFIG_MIPS_DB1500 + if ( ( port >= dbau1500be_pcmcia_base ) && ( port < dbau1500be_pcmcia_stop ) ) + *(volatile u32 *)(mips_io_port_base + (port)) = cpu_to_le32(*(u32 *)addr); + else + #endif *(volatile u32 *)(mips_io_port_base + (port)) = *(u32 *)addr; addr += 4; } ===================================================================