]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/cmd_ide.c
cros_ec: Move EC interface into common library
[karo-tx-uboot.git] / common / cmd_ide.c
index 6b4813e4a9e3b64c18dd0ffd95585c825a723f8d..c375ef2093b46ea3507c1071ff0bb26aa2489314 100644 (file)
@@ -2,24 +2,7 @@
  * (C) Copyright 2000-2011
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- *
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /*
 # include <pcmcia.h>
 #endif
 
-#ifdef CONFIG_8xx
-# include <mpc8xx.h>
-#endif
-
-#ifdef CONFIG_MPC5xxx
-#include <mpc5xxx.h>
-#endif
-
 #include <ide.h>
 #include <ata.h>
 
@@ -81,19 +56,6 @@ static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS];
 block_dev_desc_t ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE];
 /* ------------------------------------------------------------------------- */
 
-#ifdef CONFIG_IDE_LED
-# if !defined(CONFIG_BMS2003)  && \
-     !defined(CONFIG_CPC45)    && \
-     !defined(CONFIG_KUP4K) && \
-     !defined(CONFIG_KUP4X)
-static void  ide_led   (uchar led, uchar status);
-#else
-extern void  ide_led   (uchar led, uchar status);
-#endif
-#else
-#define ide_led(a,b)   /* dummy */
-#endif
-
 #ifdef CONFIG_IDE_RESET
 static void  ide_reset (void);
 #else
@@ -109,8 +71,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
@@ -119,7 +79,8 @@ static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len
 
 #ifdef CONFIG_ATAPI
 static void    atapi_inquiry(block_dev_desc_t *dev_desc);
-ulong atapi_read (int device, lbaint_t blknr, ulong blkcnt, void *buffer);
+static ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt,
+                       void *buffer);
 #endif
 
 
@@ -292,6 +253,33 @@ int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
 
 /* ------------------------------------------------------------------------- */
 
+void __ide_led(uchar led, uchar status)
+{
+#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */
+       static uchar led_buffer;        /* Buffer for current LED status */
+
+       uchar *led_port = LED_PORT;
+
+       if (status)             /* switch LED on        */
+               led_buffer |= led;
+       else                    /* switch LED off       */
+               led_buffer &= ~led;
+
+       *led_port = led_buffer;
+#endif
+}
+
+void ide_led(uchar led, uchar status)
+       __attribute__ ((weak, alias("__ide_led")));
+
+#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */
+# define DEVICE_LED(x) 0
+# define LED_IDE1 1
+# define LED_IDE2 2
+#endif
+
+/* ------------------------------------------------------------------------- */
+
 inline void __ide_outb(int dev, int port, unsigned char val)
 {
        debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
@@ -444,14 +432,14 @@ void ide_init(void)
 
        curr_device = -1;
        for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
-#ifdef CONFIG_IDE_LED
                int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2;
-#endif
                ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
                ide_dev_desc[i].if_type = IF_TYPE_IDE;
                ide_dev_desc[i].dev = i;
                ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
                ide_dev_desc[i].blksz = 0;
+               ide_dev_desc[i].log2blksz =
+                       LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
                ide_dev_desc[i].lba = 0;
                ide_dev_desc[i].block_read = ide_read;
                ide_dev_desc[i].block_write = ide_write;
@@ -483,29 +471,24 @@ 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)
-#define input_swap_data(x,y,z) input_data(x,y,z)
-#else
-static void input_swap_data(int dev, ulong *sect_buf, int words)
+#if defined(__LITTLE_ENDIAN)
+void __ide_input_swap_data(int dev, ulong *sect_buf, int words)
 {
-#if defined(CONFIG_CPC45)
-       uchar i;
-       volatile uchar *pbuf_even =
-               (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN);
-       volatile uchar *pbuf_odd =
-               (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD);
-       ushort *dbuf = (ushort *) sect_buf;
-
-       while (words--) {
-               for (i = 0; i < 2; i++) {
-                       *(((uchar *) (dbuf)) + 1) = *pbuf_even;
-                       *(uchar *) dbuf = *pbuf_odd;
-                       dbuf += 1;
-               }
-       }
+       ide_input_data(dev, sect_buf, words);
+}
 #else
+void __ide_input_swap_data(int dev, ulong *sect_buf, int words)
+{
        volatile ushort *pbuf =
                (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
        ushort *dbuf = (ushort *) sect_buf;
@@ -517,64 +500,32 @@ static void input_swap_data(int dev, ulong *sect_buf, int words)
 #ifdef __MIPS__
                *dbuf++ = swab16p((u16 *) pbuf);
                *dbuf++ = swab16p((u16 *) pbuf);
-#elif defined(CONFIG_PCS440EP)
-               *dbuf++ = *pbuf;
-               *dbuf++ = *pbuf;
 #else
                *dbuf++ = ld_le16(pbuf);
                *dbuf++ = ld_le16(pbuf);
 #endif /* !MIPS */
        }
-#endif
 }
-#endif /* __LITTLE_ENDIAN || CONFIG_AU1X00 */
+#endif /* __LITTLE_ENDIAN */
 
 
 #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;
-       volatile uchar *pbuf_even;
-       volatile uchar *pbuf_odd;
-
-       pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN);
-       pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD);
-       dbuf = (uchar *) sect_buf;
-       while (words--) {
-               EIEIO;
-               *pbuf_even = *dbuf++;
-               EIEIO;
-               *pbuf_odd = *dbuf++;
-               EIEIO;
-               *pbuf_even = *dbuf++;
-               EIEIO;
-               *pbuf_odd = *dbuf++;
-       }
-#else
        ushort *dbuf;
        volatile ushort *pbuf;
 
        pbuf = (ushort *) (ATA_CURR_BASE(dev) + ATA_DATA_REG);
        dbuf = (ushort *) sect_buf;
        while (words--) {
-#if defined(CONFIG_PCS440EP)
-               /* not tested, because CF was write protected */
-               EIEIO;
-               *pbuf = ld_le16(dbuf++);
-               EIEIO;
-               *pbuf = ld_le16(dbuf++);
-#else
                EIEIO;
                *pbuf = *dbuf++;
                EIEIO;
                *pbuf = *dbuf++;
-#endif
        }
-#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);
@@ -585,31 +536,8 @@ 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;
-       volatile uchar *pbuf_even;
-       volatile uchar *pbuf_odd;
-
-       pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN);
-       pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD);
-       dbuf = (uchar *) sect_buf;
-       while (words--) {
-               *dbuf++ = *pbuf_even;
-               EIEIO;
-               SYNC;
-               *dbuf++ = *pbuf_odd;
-               EIEIO;
-               SYNC;
-               *dbuf++ = *pbuf_even;
-               EIEIO;
-               SYNC;
-               *dbuf++ = *pbuf_odd;
-               EIEIO;
-               SYNC;
-       }
-#else
        ushort *dbuf;
        volatile ushort *pbuf;
 
@@ -619,22 +547,14 @@ static void input_data(int dev, ulong *sect_buf, int words)
        debug("in input data base for read is %lx\n", (unsigned long) pbuf);
 
        while (words--) {
-#if defined(CONFIG_PCS440EP)
-               EIEIO;
-               *dbuf++ = ld_le16(pbuf);
-               EIEIO;
-               *dbuf++ = ld_le16(pbuf);
-#else
                EIEIO;
                *dbuf++ = *pbuf;
                EIEIO;
                *dbuf++ = *pbuf;
-#endif
        }
-#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);
@@ -744,7 +664,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));
@@ -871,6 +791,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)
        /* assuming HD */
        dev_desc->type = DEV_TYPE_HARDDISK;
        dev_desc->blksz = ATA_BLOCKSIZE;
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
        dev_desc->lun = 0;      /* just to fill something in... */
 
 #if 0                          /* only used to test the powersaving mode,
@@ -892,7 +813,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)
 
 /* ------------------------------------------------------------------------- */
 
-ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer)
+ulong ide_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer)
 {
        ulong n = 0;
        unsigned char c;
@@ -906,7 +827,7 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer)
                lba48 = 1;
        }
 #endif
-       debug("ide_read dev %d start %lX, blocks %lX buffer at %lX\n",
+       debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n",
              device, blknr, blkcnt, (ulong) buffer);
 
        ide_led(DEVICE_LED(device), 1); /* LED on       */
@@ -996,17 +917,12 @@ ulong ide_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer)
 
                if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
                    ATA_STAT_DRQ) {
-#if defined(CONFIG_SYS_64BIT_LBA)
-                       printf("Error (no IRQ) dev %d blk %lld: status 0x%02x\n",
-                               device, blknr, c);
-#else
-                       printf("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
-                               device, (ulong) blknr, c);
-#endif
+                       printf("Error (no IRQ) dev %d blk " LBAF ": status "
+                              "%#02x\n", device, blknr, c);
                        break;
                }
 
-               input_data(device, buffer, ATA_SECTORWORDS);
+               ide_input_data(device, buffer, ATA_SECTORWORDS);
                (void) ide_inb(device, ATA_STATUS);     /* clear IRQ */
 
                ++n;
@@ -1021,7 +937,7 @@ IDE_READ_E:
 /* ------------------------------------------------------------------------- */
 
 
-ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer)
+ulong ide_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer)
 {
        ulong n = 0;
        unsigned char c;
@@ -1089,17 +1005,12 @@ ulong ide_write(int device, lbaint_t blknr, ulong blkcnt, const void *buffer)
 
                if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) !=
                    ATA_STAT_DRQ) {
-#if defined(CONFIG_SYS_64BIT_LBA)
-                       printf("Error (no IRQ) dev %d blk %lld: status 0x%02x\n",
-                               device, blknr, c);
-#else
-                       printf("Error (no IRQ) dev %d blk %ld: status 0x%02x\n",
-                               device, (ulong) blknr, c);
-#endif
+                       printf("Error (no IRQ) dev %d blk " LBAF ": status "
+                               "%#02x\n", device, blknr, c);
                        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;
@@ -1196,27 +1107,6 @@ static void ide_reset(void)
 
 /* ------------------------------------------------------------------------- */
 
-#if defined(CONFIG_IDE_LED)    && \
-   !defined(CONFIG_CPC45)      && \
-   !defined(CONFIG_KUP4K)      && \
-   !defined(CONFIG_KUP4X)
-
-static uchar led_buffer;       /* Buffer for current LED status        */
-
-static void ide_led(uchar led, uchar status)
-{
-       uchar *led_port = LED_PORT;
-
-       if (status)             /* switch LED on        */
-               led_buffer |= led;
-       else                    /* switch LED off       */
-               led_buffer &= ~led;
-
-       *led_port = led_buffer;
-}
-
-#endif /* CONFIG_IDE_LED */
-
 #if defined(CONFIG_OF_IDE_FIXUP)
 int ide_device_present(int dev)
 {
@@ -1232,25 +1122,18 @@ int ide_device_present(int dev)
  * 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;
-       volatile uchar *pbuf_even;
-       volatile uchar *pbuf_odd;
-
-       pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN);
-       pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD);
-       while (shorts--) {
-               EIEIO;
-               *pbuf_even = *dbuf++;
-               EIEIO;
-               *pbuf_odd = *dbuf++;
-       }
-#else
        ushort *dbuf;
        volatile ushort *pbuf;
 
@@ -1264,25 +1147,10 @@ static void output_data_shorts(int dev, ushort *sect_buf, int shorts)
                EIEIO;
                *pbuf = *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;
-       volatile uchar *pbuf_even;
-       volatile uchar *pbuf_odd;
-
-       pbuf_even = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_EVEN);
-       pbuf_odd = (uchar *) (ATA_CURR_BASE(dev) + ATA_DATA_ODD);
-       while (shorts--) {
-               EIEIO;
-               *dbuf++ = *pbuf_even;
-               EIEIO;
-               *dbuf++ = *pbuf_odd;
-       }
-#else
        ushort *dbuf;
        volatile ushort *pbuf;
 
@@ -1296,16 +1164,15 @@ static void input_data_shorts(int dev, ushort *sect_buf, int shorts)
                EIEIO;
                *dbuf++ = *pbuf;
        }
-#endif
 }
 
 #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);
 }
@@ -1384,7 +1251,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 */
@@ -1435,12 +1302,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... */
@@ -1567,6 +1434,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
        dev_desc->lun = 0;
        dev_desc->lba = 0;
        dev_desc->blksz = 0;
+       dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
        dev_desc->type = iobuf[0] & 0x1f;
 
        if ((iobuf[1] & 0x80) == 0x80)
@@ -1611,6 +1479,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
        dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
                ((unsigned long) iobuf[5] << 16) +
                ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
 #ifdef CONFIG_LBA48
        /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
        dev_desc->lba48 = 0;
@@ -1628,13 +1497,13 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
 #define ATAPI_READ_BLOCK_SIZE  2048    /* assuming CD part */
 #define ATAPI_READ_MAX_BLOCK   (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE)
 
-ulong atapi_read(int device, lbaint_t blknr, ulong blkcnt, void *buffer)
+ulong atapi_read(int device, ulong blknr, lbaint_t blkcnt, void *buffer)
 {
        ulong n = 0;
        unsigned char ccb[12];  /* Command descriptor block */
        ulong cnt;
 
-       debug("atapi_read dev %d start %lX, blocks %lX buffer at %lX\n",
+       debug("atapi_read dev %d start %lX, blocks " LBAF " buffer at %lX\n",
              device, blknr, blkcnt, (ulong) buffer);
 
        do {