#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
 
 /* ------------------------------------------------------------------------- */
 
+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)
-#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;
 
 
 #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;
 #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);
 #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;
 #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);
                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));
                        break;
                }
 
-               input_data(device, buffer, ATA_SECTORWORDS);
+               ide_input_data(device, buffer, ATA_SECTORWORDS);
                (void) ide_inb(device, ATA_STATUS);     /* clear IRQ */
 
                ++n;
                        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;
  * ATAPI Support
  */
 
+void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts)
+       __attribute__ ((weak, alias("__ide_input_data_shorts")));
+
+void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts)
+       __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;
 #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;
 }
 
 #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);
 }
        }
 
        /* 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 */
                /* 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... */