[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