[U-Boot-Users] IDE Little Endian patch
Ed Okerson
eokerson at texasconnect.net
Thu Mar 4 05:05:22 CET 2004
The attached patch fixes IDE problems for little endian systems. The
previous patch was rejected (a couple of months ago) and has been reworked
as per Wolfgang's request.
Ed Okerson
-------------- next part --------------
--- common/cmd_ide.c.new 2004-03-02 10:43:48.000000000 -0800
+++ common/cmd_ide.c 2004-03-03 19:55:37.625017368 -0800
@@ -176,7 +176,9 @@ static unsigned char __inline__ ide_inb(
static void input_data(int dev, ulong *sect_buf, int words);
static void output_data(int dev, ulong *sect_buf, int words);
static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len);
-
+#if defined(__LITTLE_ENDIAN)
+static void ident_swap (unsigned char *dest, unsigned int len);
+#endif
#ifdef CONFIG_ATAPI
static void atapi_inquiry(block_dev_desc_t *dev_desc);
@@ -242,7 +244,7 @@ int do_ide (cmd_tbl_t *cmdtp, int flag,
}
}
if (!ok) {
- puts ("\nno IDE devices available\n");
+ puts ("\nno IDE devices with partitions available\n");
rcode ++;
}
return rcode;
@@ -833,7 +835,11 @@ output_data_short(int dev, ulong *sect_b
/* 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_AU1X00)
-#define input_swap_data(x,y,z) input_data(x,y,z)
+static void
+input_swap_data(int dev, ulong *sect_buf, int words)
+{
+ insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
+}
#else
static void
input_swap_data(int dev, ulong *sect_buf, int words)
@@ -945,12 +951,25 @@ input_data(int dev, ulong *sect_buf, int
#endif /* CONFIG_BMS2003 */
}
#else /* ! __PPC__ */
+#if (!defined(__LITTLE_ENDIAN) && defined(CONFIG_AU1X00))
+static void
+input_data(int dev, ulong *sect_buf, int words)
+{
+ volatile ushort *pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG);
+ ushort *dbuf = (ushort *)sect_buf;
+
+ while (words--) {
+ *dbuf++ = swab16(*pbuf);
+ *dbuf++ = swab16(*pbuf);
+ }
+}
+#else
static void
input_data(int dev, ulong *sect_buf, int words)
{
insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
}
-
+#endif /* CONFIG_AU1X00 */
#endif /* __PPC__ */
#ifdef CONFIG_AMIGAONEG3SE
@@ -1091,6 +1110,10 @@ static void ide_ident (block_dev_desc_t
ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor));
ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product));
+#if defined(__LITTLE_ENDIAN)
+ ident_swap (dev_desc->revision, sizeof(dev_desc->revision));
+ ident_swap (dev_desc->vendor, sizeof(dev_desc->vendor));
+#endif
if ((iop->config & 0x0080)==0x0080)
dev_desc->removable = 1;
else
@@ -1132,7 +1155,11 @@ static void ide_ident (block_dev_desc_t
#endif /* CONFIG_ATAPI */
/* swap shorts */
+#if (defined(__LITTLE_ENDIAN) && defined(CONFIG_AU1X00))
+ dev_desc->lba = iop->lba_capacity;
+#else
dev_desc->lba = (iop->lba_capacity << 16) | (iop->lba_capacity >> 16);
+#endif
/* assuming HD */
dev_desc->type=DEV_TYPE_HARDDISK;
dev_desc->blksz=ATA_BLOCKSIZE;
@@ -1326,6 +1353,19 @@ static void ident_cpy (unsigned char *de
*dest='\0';
}
+static void ident_swap (unsigned char *dest, unsigned int len)
+{
+ int start;
+ unsigned char s, *d = dest;
+
+ start = 0;
+ for ( ; start<=len; start+=2) {
+ s = d[start];
+ *dest++=d[start+1];
+ *dest++=s;
+ }
+}
+
/* ------------------------------------------------------------------------- */
/*
@@ -1809,6 +1849,11 @@ static void atapi_inquiry(block_dev_desc
ident_cpy(dev_desc->product,&iobuf[16],16);
ident_cpy(dev_desc->revision,&iobuf[32],5);
+#if defined(__LITTLE_ENDIAN)
+ ident_swap (dev_desc->vendor, 8);
+ ident_swap (dev_desc->revision, 5);
+#endif
+
dev_desc->lun=0;
dev_desc->lba=0;
dev_desc->blksz=0;
More information about the U-Boot
mailing list