diff --git a/board/esd/cpci750/ide.c b/board/esd/cpci750/ide.c
index aa001df..4ef10e7 100644
--- a/board/esd/cpci750/ide.c
+++ b/board/esd/cpci750/ide.c
@@ -30,7 +30,6 @@
 #include <ide.h>
 #include <pci.h>
 
-extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];
 int cpci_hd_type;
 
 int ata_device(int dev)
diff --git a/board/linkstation/ide.c b/board/linkstation/ide.c
index f3e3fce..541c958 100644
--- a/board/linkstation/ide.c
+++ b/board/linkstation/ide.c
@@ -37,7 +37,6 @@
 #define IT8212_PCI_IdeBusSkewCONTROL	0x4c
 #define IT8212_PCI_IdeDrivingCURRENT	0x42
 
-extern ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS];
 extern struct pci_controller hose;
 
 int ide_preinit (void)
diff --git a/board/pcs440ep/pcs440ep.c b/board/pcs440ep/pcs440ep.c
index 746a54c..52da053 100644
--- a/board/pcs440ep/pcs440ep.c
+++ b/board/pcs440ep/pcs440ep.c
@@ -672,7 +672,6 @@ U_BOOT_CMD(
  * ( bus per_addr 20 -30 is connectsd on CF bus A10-A0)
  * These values are shifted
  */
-extern ulong *ide_bus_offset;
 void inline ide_outb(int dev, int port, unsigned char val)
 {
 	debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index 2604809..93371fd 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -109,8 +109,6 @@ static uchar ide_wait  (int dev, ulong t);
 
 #define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */
 
-static void input_data(int dev, ulong *sect_buf, int words);
-static void output_data(int dev, const ulong *sect_buf, int words);
 static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
 
 #ifndef CONFIG_SYS_ATA_PORT_ADDR
@@ -483,13 +481,25 @@ block_dev_desc_t *ide_get_dev(int dev)
 
 /* ------------------------------------------------------------------------- */
 
+void ide_input_swap_data(int dev, ulong *sect_buf, int words)
+	__attribute__ ((weak, alias("__ide_input_swap_data")));
+
+void ide_input_data(int dev, ulong *sect_buf, int words)
+	__attribute__ ((weak, alias("__ide_input_data")));
+
+void ide_output_data(int dev, const ulong *sect_buf, int words)
+	__attribute__ ((weak, alias("__ide_output_data")));
+
 /* We only need to swap data if we are running on a big endian cpu. */
 /* But Au1x00 cpu:s already swaps data in big endian mode! */
 #if defined(__LITTLE_ENDIAN) || \
    (defined(CONFIG_SOC_AU1X00) && !defined(CONFIG_GTH2))
-#define input_swap_data(x,y,z) input_data(x,y,z)
+void __ide_input_swap_data(int dev, ulong *sect_buf, int words)
+{
+	ide_input_data(dev, sect_buf, words);
+}
 #else
-static void input_swap_data(int dev, ulong *sect_buf, int words)
+void __ide_input_swap_data(int dev, ulong *sect_buf, int words)
 {
 #if defined(CONFIG_CPC45)
 	uchar i;
@@ -532,7 +542,7 @@ static void input_swap_data(int dev, ulong *sect_buf, int words)
 
 
 #if defined(CONFIG_IDE_SWAP_IO)
-static void output_data(int dev, const ulong *sect_buf, int words)
+void __ide_output_data(int dev, const ulong *sect_buf, int words)
 {
 #if defined(CONFIG_CPC45)
 	uchar *dbuf;
@@ -575,7 +585,7 @@ static void output_data(int dev, const ulong *sect_buf, int words)
 #endif
 }
 #else  /* ! CONFIG_IDE_SWAP_IO */
-static void output_data(int dev, const ulong *sect_buf, int words)
+void __ide_output_data(int dev, const ulong *sect_buf, int words)
 {
 #if defined(CONFIG_IDE_AHB)
 	ide_write_data(dev, sect_buf, words);
@@ -586,7 +596,7 @@ static void output_data(int dev, const ulong *sect_buf, int words)
 #endif /* CONFIG_IDE_SWAP_IO */
 
 #if defined(CONFIG_IDE_SWAP_IO)
-static void input_data(int dev, ulong *sect_buf, int words)
+void __ide_input_data(int dev, ulong *sect_buf, int words)
 {
 #if defined(CONFIG_CPC45)
 	uchar *dbuf;
@@ -635,7 +645,7 @@ static void input_data(int dev, ulong *sect_buf, int words)
 #endif
 }
 #else  /* ! CONFIG_IDE_SWAP_IO */
-static void input_data(int dev, ulong *sect_buf, int words)
+void __ide_input_data(int dev, ulong *sect_buf, int words)
 {
 #if defined(CONFIG_IDE_AHB)
 	ide_read_data(dev, sect_buf, words);
@@ -745,7 +755,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)
 		return;
 #endif
 
-	input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
+	ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS);
 
 	ident_cpy((unsigned char *) dev_desc->revision, iop.fw_rev,
 		  sizeof(dev_desc->revision));
@@ -1007,7 +1017,7 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer)
 			break;
 		}
 
-		input_data(device, buffer, ATA_SECTORWORDS);
+		ide_input_data(device, buffer, ATA_SECTORWORDS);
 		(void) ide_inb(device, ATA_STATUS);	/* clear IRQ */
 
 		++n;
@@ -1100,7 +1110,7 @@ ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer)
 			goto WR_OUT;
 		}
 
-		output_data(device, buffer, ATA_SECTORWORDS);
+		ide_output_data(device, buffer, ATA_SECTORWORDS);
 		c = ide_inb(device, ATA_STATUS);	/* clear IRQ */
 		++n;
 		++blknr;
@@ -1233,10 +1243,17 @@ int ide_device_present(int dev)
  * ATAPI Support
  */
 
+void ide_input_data_shorts(int dev, ushort *sect_buf, int words)
+	__attribute__ ((weak, alias("__ide_input_data_shorts")));
+
+void ide_output_data_shorts(int dev, ushort *sect_buf, int words)
+	__attribute__ ((weak, alias("__ide_output_data_shorts")));
+
+
 #if defined(CONFIG_IDE_SWAP_IO)
 /* since ATAPI may use commands with not 4 bytes alligned length
  * we have our own transfer functions, 2 bytes alligned */
-static void output_data_shorts(int dev, ushort *sect_buf, int shorts)
+void __ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
 {
 #if defined(CONFIG_CPC45)
 	uchar *dbuf;
@@ -1268,7 +1285,7 @@ static void output_data_shorts(int dev, ushort *sect_buf, int shorts)
 #endif
 }
 
-static void input_data_shorts(int dev, ushort *sect_buf, int shorts)
+void __ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
 {
 #if defined(CONFIG_CPC45)
 	uchar *dbuf;
@@ -1301,12 +1318,12 @@ static void input_data_shorts(int dev, ushort *sect_buf, int shorts)
 }
 
 #else  /* ! CONFIG_IDE_SWAP_IO */
-static void output_data_shorts(int dev, ushort *sect_buf, int shorts)
+void __ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
 {
 	outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
 }
 
-static void input_data_shorts(int dev, ushort *sect_buf, int shorts)
+void __ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
 {
 	insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts);
 }
@@ -1385,7 +1402,7 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
 	}
 
 	/* write command block */
-	output_data_shorts(device, (unsigned short *) ccb, ccblen / 2);
+	ide_output_data_shorts(device, (unsigned short *) ccb, ccblen / 2);
 
 	/* ATAPI Command written wait for completition */
 	udelay(5000);		/* device must set bsy */
@@ -1436,12 +1453,12 @@ unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen,
 		/* ok now decide if it is an in or output */
 		if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) {
 			debug("Write to device\n");
-			output_data_shorts(device, (unsigned short *) buffer,
-					   n);
+			ide_output_data_shorts(device,
+				(unsigned short *) buffer, n);
 		} else {
 			debug("Read from device @ %p shorts %d\n", buffer, n);
-			input_data_shorts(device, (unsigned short *) buffer,
-					  n);
+			ide_input_data_shorts(device,
+				(unsigned short *) buffer, n);
 		}
 	}
 	udelay(5000);		/* seems that some CD ROMs need this... */
diff --git a/include/ide.h b/include/ide.h
index 3bae40d..53cd8fb 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -27,6 +27,7 @@
 #define	IDE_BUS(dev)	(dev >> 1)
 
 #define	ATA_CURR_BASE(dev)	(CONFIG_SYS_ATA_BASE_ADDR+ide_bus_offset[IDE_BUS(dev)])
+extern ulong ide_bus_offset[];
 
 #ifdef CONFIG_IDE_LED
 
@@ -72,4 +73,14 @@ void ide_write_register(int dev, unsigned int port, unsigned char val);
 void ide_read_data(int dev, ulong *sect_buf, int words);
 void ide_write_data(int dev, ulong *sect_buf, int words);
 #endif
+
+/*
+ * I/O function overrides
+ */
+void ide_input_swap_data(int dev, ulong *sect_buf, int words);
+void ide_input_data(int dev, ulong *sect_buf, int words);
+void ide_output_data(int dev, const ulong *sect_buf, int words);
+void ide_input_data_shorts(int dev, ushort *sect_buf, int words);
+void ide_output_data_shorts(int dev, ushort *sect_buf, int words);
+
 #endif /* _IDE_H */
