[U-Boot-Users] Endian patch for AU1x00

Ed Okerson eokerson at texasconnect.net
Mon Dec 8 01:49:45 CET 2003


Attached is an patch to cmd_ide.c that fixes endian issues for the AU1x00
family of processors.  Previously these processors could only read Compact
Flash cards (and perhaps other IDE devices) if the drive was byte swapped
from what is written by a standard PC.  With this patch they can now read
them without the bytes needing to be swapped.

Ed Okerson
-------------- next part --------------
--- ../../u-boot/common/cmd_ide.c	2003-11-07 05:42:26.000000000 -0800
+++ cmd_ide.c	2003-11-30 13:13:53.000000000 -0800
@@ -172,7 +172,7 @@ static void __inline__ ide_outb(int dev,
 static unsigned char __inline__ ide_inb(int dev, int port);
 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);
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len, int swap);
 
 
 #ifdef CONFIG_ATAPI
@@ -239,7 +239,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;
@@ -631,7 +631,6 @@ void ide_init (void)
 #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;
@@ -817,8 +816,12 @@ 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)
+#if (defined(__LITTLE_ENDIAN) || defined(CONFIG_AU1X00))
+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)
@@ -875,11 +878,25 @@ input_data(int dev, ulong *sect_buf, int
 	}
 }
 #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__ */
 
@@ -912,6 +929,7 @@ static void ide_ident (block_dev_desc_t 
 {
 	ulong iobuf[ATA_SECTORWORDS];
 	unsigned char c;
+	unsigned char *l;
 	hd_driveid_t *iop = (hd_driveid_t *)iobuf;
 
 #ifdef CONFIG_AMIGAONEG3SE
@@ -992,9 +1010,11 @@ static void ide_ident (block_dev_desc_t 
 		if (retries == 0) {
 			do_retry = 1;
 		} else {
+			dev_desc->type=DEV_TYPE_UNKNOWN;
 			return;
 		}
 #else
+		dev_desc->type=DEV_TYPE_UNKNOWN;
 		return;
 #endif	/* CONFIG_AMIGAONEG3SE */
 	}
@@ -1017,10 +1037,14 @@ static void ide_ident (block_dev_desc_t 
 
 	input_swap_data (device, iobuf, ATA_SECTORWORDS);
 
-	ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision));
-	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_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision), 1);
+	ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor), 1);
+#else
+	ident_cpy (dev_desc->revision, iop->fw_rev, sizeof(dev_desc->revision), 0);
+	ident_cpy (dev_desc->vendor, iop->model, sizeof(dev_desc->vendor), 0);
+#endif
+	ident_cpy (dev_desc->product, iop->serial_no, sizeof(dev_desc->product), 0);
 	if ((iop->config & 0x0080)==0x0080)
 		dev_desc->removable = 1;
 	else
@@ -1062,7 +1086,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;
@@ -1162,7 +1190,6 @@ ulong ide_read (int device, ulong blknr,
 				device, blknr, c);
 			break;
 		}
-
 		input_data (device, buffer, ATA_SECTORWORDS);
 		(void) ide_inb (device, ATA_STATUS);	/* clear IRQ */
 
@@ -1234,9 +1261,10 @@ WR_OUT:
  * copy src to dest, skipping leading and trailing blanks and null
  * terminate the string
  */
-static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len)
+static void ident_cpy (unsigned char *dest, unsigned char *src, unsigned int len, int swap)
 {
-	int start,end;
+	int start, save, end;
+	unsigned char s, *d = dest;
 
 	start=0;
 	while (start<len) {
@@ -1246,14 +1274,28 @@ static void ident_cpy (unsigned char *de
 	}
 	end=len-1;
 	while (end>start) {
+		if(swap)
+			end--;
 		if (src[end]!=' ')
 			break;
-		end--;
+		if(!swap)
+			end--;
 	}
+	save = start;
 	for ( ; start<=end; start++) {
 		*dest++=src[start];
 	}
 	*dest='\0';
+	dest = d;
+
+	if(swap)
+	{
+		for ( ; save<=end; save+=2) {
+			s = d[save];
+			*dest++=d[save+1];
+			*dest++=s;
+		}
+	}
 }
 
 /* ------------------------------------------------------------------------- */
@@ -1423,19 +1465,18 @@ input_data_shorts(int dev, ushort *sect_
 }
 
 #else	/* ! __PPC__ */
+
 static void
 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)
 {
 	insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, shorts);
 }
-
 #endif	/* __PPC__ */
 
 /*
@@ -1705,10 +1746,15 @@ static void	atapi_inquiry(block_dev_desc
 		return;
 
 	/* copy device ident strings */
-	ident_cpy(dev_desc->vendor,&iobuf[8],8);
-	ident_cpy(dev_desc->product,&iobuf[16],16);
-	ident_cpy(dev_desc->revision,&iobuf[32],5);
-
+#if defined(__LITTLE_ENDIAN)
+	ident_cpy(dev_desc->vendor,&iobuf[8],8, 1);
+	ident_cpy(dev_desc->product,&iobuf[16],16, 0);
+	ident_cpy(dev_desc->revision,&iobuf[32],5, 1);
+#else
+	ident_cpy(dev_desc->vendor,&iobuf[8],8, 0);
+	ident_cpy(dev_desc->product,&iobuf[16],16, 0);
+	ident_cpy(dev_desc->revision,&iobuf[32],5, 0);
+#endif
 	dev_desc->lun=0;
 	dev_desc->lba=0;
 	dev_desc->blksz=0;


More information about the U-Boot mailing list