Merge branch 'master' of git://git.denx.de/u-boot-ubi
diff --git a/README b/README
index 940b507..bb13bc6 100644
--- a/README
+++ b/README
@@ -1133,6 +1133,12 @@
 		images, gzipped BMP images can be displayed via the
 		splashscreen support or the bmp command.
 
+- Run length encoded BMP image (RLE8) support: CONFIG_VIDEO_BMP_RLE8
+
+		If this option is set, 8-bit RLE compressed BMP images
+		can be displayed via the splashscreen support or the
+		bmp command.
+
 - Compression support:
 		CONFIG_BZIP2
 
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 6b5c582..ee3755c 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -387,7 +387,7 @@
 
 	dev = simple_strtoul(boot_device, &ep, 16);
 	stor_dev = usb_stor_get_dev(dev);
-	if (stor_dev->type == DEV_TYPE_UNKNOWN) {
+	if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) {
 		printf("\n** Device %d not available\n", dev);
 		return 1;
 	}
@@ -595,8 +595,10 @@
 	if (strncmp(argv[1], "part", 4) == 0) {
 		int devno, ok = 0;
 		if (argc == 2) {
-			for (devno = 0; devno < USB_MAX_STOR_DEV; ++devno) {
+			for (devno = 0; ; ++devno) {
 				stor_dev = usb_stor_get_dev(devno);
+				if (stor_dev == NULL)
+					break;
 				if (stor_dev->type != DEV_TYPE_UNKNOWN) {
 					ok++;
 					if (devno)
@@ -608,7 +610,8 @@
 		} else {
 			devno = simple_strtoul(argv[2], NULL, 16);
 			stor_dev = usb_stor_get_dev(devno);
-			if (stor_dev->type != DEV_TYPE_UNKNOWN) {
+			if (stor_dev != NULL &&
+			    stor_dev->type != DEV_TYPE_UNKNOWN) {
 				ok++;
 				debug("print_part of %x\n", devno);
 				print_part(stor_dev);
@@ -668,12 +671,12 @@
 		if (argc == 3) {
 			int dev = (int)simple_strtoul(argv[2], NULL, 10);
 			printf("\nUSB device %d: ", dev);
-			if (dev >= USB_MAX_STOR_DEV) {
+			stor_dev = usb_stor_get_dev(dev);
+			if (stor_dev == NULL) {
 				printf("unknown device\n");
 				return 1;
 			}
 			printf("\n    Device %d: ", dev);
-			stor_dev = usb_stor_get_dev(dev);
 			dev_print(stor_dev);
 			if (stor_dev->type == DEV_TYPE_UNKNOWN)
 				return 1;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index a8642c9..4fc01a2 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -175,7 +175,7 @@
 
 block_dev_desc_t *usb_stor_get_dev(int index)
 {
-	return (index < USB_MAX_STOR_DEV) ? &usb_dev_desc[index] : NULL;
+	return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
 }
 
 
@@ -244,7 +244,7 @@
 			 * get info and fill it in
 			 */
 			if (usb_stor_get_info(dev, &usb_stor[usb_max_devs],
-						&usb_dev_desc[usb_max_devs]))
+						&usb_dev_desc[usb_max_devs]) == 1)
 				usb_max_devs++;
 		}
 		/* if storage device */
@@ -888,7 +888,7 @@
 		USB_STOR_PRINTF("inquiry returns %d\n", i);
 		if (i == 0)
 			break;
-	} while (retry--);
+	} while (--retry);
 
 	if (!retry) {
 		printf("error in inquiry\n");
diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c
index 5f9bd10..dbb5e8c 100644
--- a/drivers/bios_emulator/atibios.c
+++ b/drivers/bios_emulator/atibios.c
@@ -173,7 +173,7 @@
 ****************************************************************************/
 void *PCI_mapBIOSImage(pci_dev_t pcidev)
 {
-	u32 BIOSImagePhys;
+	u32 BIOSImageBus;
 	int BIOSImageBAR;
 	u8 *BIOSImage;
 
@@ -195,16 +195,18 @@
 	 specific programming for different cards to solve this problem.
 	*/
 
-	if ((BIOSImagePhys = PCI_findBIOSAddr(pcidev, &BIOSImageBAR)) == 0) {
+	BIOSImageBus = PCI_findBIOSAddr(pcidev, &BIOSImageBAR);
+	if (BIOSImageBus == 0) {
 		printf("Find bios addr error\n");
 		return NULL;
 	}
 
-	BIOSImage = (u8 *) BIOSImagePhys;
+	BIOSImage = pci_bus_to_virt(pcidev, BIOSImageBus,
+				    PCI_REGION_MEM, 0, MAP_NOCACHE);
 
 	/*Change the PCI BAR registers to map it onto the bus.*/
 	pci_write_config_dword(pcidev, BIOSImageBAR, 0);
-	pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImagePhys | 0x1);
+	pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImageBus | 0x1);
 
 	udelay(1);
 
@@ -315,7 +317,8 @@
 	BE_init(0, 65536, VGAInfo, 0);
 
 	/*Post all the display controller BIOS'es*/
-	PCI_postController(pcidev, VGAInfo);
+	if (!PCI_postController(pcidev, VGAInfo))
+		return false;
 
 	/*Cleanup and exit the emulator if requested. If the BIOS emulator
 	is needed after booting the card, we will not call BE_exit and
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 9ebeb4f..7784d92 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -55,14 +55,14 @@
 	{
 		0x12,		/* bLength */
 		1,		/* bDescriptorType: UDESC_DEVICE */
-		0x0002,		/* bcdUSB: v2.0 */
+		cpu_to_le16(0x0200), /* bcdUSB: v2.0 */
 		9,		/* bDeviceClass: UDCLASS_HUB */
 		0,		/* bDeviceSubClass: UDSUBCLASS_HUB */
 		1,		/* bDeviceProtocol: UDPROTO_HSHUBSTT */
 		64,		/* bMaxPacketSize: 64 bytes */
 		0x0000,		/* idVendor */
 		0x0000,		/* idProduct */
-		0x0001,		/* bcdDevice */
+		cpu_to_le16(0x0100), /* bcdDevice */
 		1,		/* iManufacturer */
 		2,		/* iProduct */
 		0,		/* iSerialNumber */
@@ -536,7 +536,7 @@
 	uint32_t reg;
 	uint32_t *status_reg;
 
-	if (le16_to_cpu(req->index) >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+	if (le16_to_cpu(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
 		printf("The request port(%d) is not configured\n",
 			le16_to_cpu(req->index) - 1);
 		return -1;
@@ -630,19 +630,8 @@
 			tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
 		if (reg & EHCI_PS_OCA)
 			tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
-		if (reg & EHCI_PS_PR &&
-		    (portreset & (1 << le16_to_cpu(req->index)))) {
-			int ret;
-			/* force reset to complete */
-			reg = reg & ~(EHCI_PS_PR | EHCI_PS_CLEAR);
-			ehci_writel(status_reg, reg);
-			ret = handshake(status_reg, EHCI_PS_PR, 0, 2 * 1000);
-			if (!ret)
-				tmpbuf[0] |= USB_PORT_STAT_RESET;
-			else
-				printf("port(%d) reset error\n",
-					le16_to_cpu(req->index) - 1);
-		}
+		if (reg & EHCI_PS_PR)
+			tmpbuf[0] |= USB_PORT_STAT_RESET;
 		if (reg & EHCI_PS_PP)
 			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
 
@@ -699,6 +688,8 @@
 				ehci_writel(status_reg, reg);
 				break;
 			} else {
+				int ret;
+
 				reg |= EHCI_PS_PR;
 				reg &= ~EHCI_PS_PE;
 				ehci_writel(status_reg, reg);
@@ -710,8 +701,19 @@
 				wait_ms(50);
 				/* terminate the reset */
 				ehci_writel(status_reg, reg & ~EHCI_PS_PR);
-				wait_ms(2);
-				portreset |= 1 << le16_to_cpu(req->index);
+				/*
+				 * A host controller must terminate the reset
+				 * and stabilize the state of the port within
+				 * 2 milliseconds
+				 */
+				ret = handshake(status_reg, EHCI_PS_PR, 0,
+						2 * 1000);
+				if (!ret)
+					portreset |=
+						1 << le16_to_cpu(req->index);
+				else
+					printf("port(%d) reset error\n",
+					le16_to_cpu(req->index) - 1);
 			}
 			break;
 		default:
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 441b1a2..047902a 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -28,6 +28,7 @@
 #ifdef CONFIG_PCI_EHCI_DEVICE
 static struct pci_device_id ehci_pci_ids[] = {
 	/* Please add supported PCI EHCI controller ids here */
+	{0x1033, 0x00E0},
 	{0, 0}
 };
 #endif
diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c
index 9ebb0b0..4a9bd07 100644
--- a/drivers/video/ati_radeon_fb.c
+++ b/drivers/video/ati_radeon_fb.c
@@ -210,7 +210,7 @@
 	 * ToDo: identify these cases
 	 */
 
-	DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n",
+	DPRINT("radeonfb: Found %dk of %s %d bits wide videoram\n",
 	       rinfo->video_ram / 1024,
 	       rinfo->vram_ddr ? "DDR" : "SDRAM",
 	       rinfo->vram_width);
@@ -586,18 +586,21 @@
 		rinfo->pdev.device = did;
 		rinfo->family = get_radeon_id_family(rinfo->pdev.device);
 		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0,
-				&rinfo->fb_base_phys);
+				&rinfo->fb_base_bus);
 		pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
-				&rinfo->mmio_base_phys);
-		rinfo->fb_base_phys &= 0xfffff000;
-		rinfo->mmio_base_phys &= ~0x04;
+				&rinfo->mmio_base_bus);
+		rinfo->fb_base_bus &= 0xfffff000;
+		rinfo->mmio_base_bus &= ~0x04;
 
-		rinfo->mmio_base = (void *)rinfo->mmio_base_phys;
-		DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base);
+		rinfo->mmio_base = pci_bus_to_virt(pdev, rinfo->mmio_base_bus,
+					PCI_REGION_MEM, 0, MAP_NOCACHE);
+		DPRINT("rinfo->mmio_base = 0x%p bus=0x%x\n",
+		       rinfo->mmio_base, rinfo->mmio_base_bus);
 		rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
 		DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base);
 		/* PostBIOS with x86 emulater */
-		BootVideoCardBIOS(pdev, NULL, 0);
+		if (!BootVideoCardBIOS(pdev, NULL, 0))
+			return -1;
 
 		/*
 		 * Check for errata
@@ -610,14 +613,15 @@
 
 		rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM,
 				rinfo->video_ram);
-		rinfo->fb_base = (void *)rinfo->fb_base_phys;
-
-		DPRINT("Radeon: framebuffer base phy address 0x%08x," \
-		      "MMIO base phy address 0x%08x," \
-		      "framebuffer local base 0x%08x.\n ",
-		      rinfo->fb_base_phys, rinfo->mmio_base_phys,
-		      rinfo->fb_local_base);
-
+		rinfo->fb_base = pci_bus_to_virt(pdev, rinfo->fb_base_bus,
+					PCI_REGION_MEM, 0, MAP_NOCACHE);
+		DPRINT("Radeon: framebuffer base address 0x%08x, "
+		       "bus address 0x%08x\n"
+		       "MMIO base address 0x%08x, bus address 0x%08x, "
+		       "framebuffer local base 0x%08x.\n ",
+		       (u32)rinfo->fb_base, rinfo->fb_base_bus,
+		       (u32)rinfo->mmio_base, rinfo->mmio_base_bus,
+		       rinfo->fb_local_base);
 		return 0;
 	}
 	return -1;
@@ -733,13 +737,13 @@
 	}
 
 	pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS;
-	pGD->pciBase = rinfo->fb_base_phys;
-	pGD->frameAdrs = rinfo->fb_base_phys;
+	pGD->pciBase = (unsigned int)rinfo->fb_base;
+	pGD->frameAdrs = (unsigned int)rinfo->fb_base;
 	pGD->memSize = 64 * 1024 * 1024;
 
 	/* Cursor Start Address */
-	pGD->dprBase =
-	    (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys;
+	pGD->dprBase = (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) +
+		(unsigned int)rinfo->fb_base;
 	if ((pGD->dprBase & 0x0fff) != 0) {
 		/* allign it */
 		pGD->dprBase &= 0xfffff000;
@@ -747,8 +751,8 @@
 	}
 	DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase,
 		PATTERN_ADR);
-	pGD->vprBase = rinfo->fb_base_phys;	/* Dummy */
-	pGD->cprBase = rinfo->fb_base_phys;	/* Dummy */
+	pGD->vprBase = (unsigned int)rinfo->fb_base;	/* Dummy */
+	pGD->cprBase = (unsigned int)rinfo->fb_base;	/* Dummy */
 	/* set up Hardware */
 
 	/* Clear video memory (only visible screen area) */
diff --git a/drivers/video/ati_radeon_fb.h b/drivers/video/ati_radeon_fb.h
index e981f95..0659045 100644
--- a/drivers/video/ati_radeon_fb.h
+++ b/drivers/video/ati_radeon_fb.h
@@ -49,8 +49,8 @@
 	struct pci_device_id	pdev;
 	u16			family;
 
-	u32			fb_base_phys;
-	u32			mmio_base_phys;
+	u32			fb_base_bus;
+	u32			mmio_base_bus;
 
 	void			*mmio_base;
 	void			*fb_base;
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index 49f0a2e..d1f47c9 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -803,8 +803,193 @@
 #endif
 
 /*
+ * RLE8 bitmap support
+ */
+
+#ifdef CONFIG_VIDEO_BMP_RLE8
+/* Pre-calculated color table entry */
+struct palette {
+	union {
+		unsigned short	w;	/* word */
+		unsigned int	dw;	/* double word */
+	} ce; /* color entry */
+};
+
+/*
+ * Helper to draw encoded/unencoded run.
+ */
+static void draw_bitmap (uchar **fb, uchar *bm, struct palette *p,
+			 int cnt, int enc)
+{
+	ulong addr = (ulong)*fb;
+	int *off;
+	int enc_off = 1;
+	int i;
+
+	/*
+	 * Setup offset of the color index in the bitmap.
+	 * Color index of encoded run is at offset 1.
+	 */
+	off = enc ? &enc_off : &i;
+
+	switch (VIDEO_DATA_FORMAT) {
+	case GDF__8BIT_INDEX:
+		for (i = 0; i < cnt; i++)
+			*(unsigned char *)addr++ = bm[*off];
+		break;
+	case GDF_15BIT_555RGB:
+	case GDF_16BIT_565RGB:
+		/* differences handled while pre-calculating palette */
+		for (i = 0; i < cnt; i++) {
+			*(unsigned short *)addr = p[bm[*off]].ce.w;
+			addr += 2;
+		}
+		break;
+	case GDF_32BIT_X888RGB:
+		for (i = 0; i < cnt; i++) {
+			*(unsigned long *)addr = p[bm[*off]].ce.dw;
+			addr += 4;
+		}
+		break;
+	}
+	*fb = (uchar *)addr; /* return modified address */
+}
+
+static int display_rle8_bitmap (bmp_image_t *img, int xoff, int yoff,
+				int width, int height)
+{
+	unsigned char *bm;
+	unsigned char *fbp;
+	unsigned int cnt, runlen;
+	int decode = 1;
+	int x, y, bpp, i, ncolors;
+	struct palette p[256];
+	bmp_color_table_entry_t cte;
+	int green_shift, red_off;
+
+	x = 0;
+	y = __le32_to_cpu(img->header.height) - 1;
+	ncolors = __le32_to_cpu(img->header.colors_used);
+	bpp = VIDEO_PIXEL_SIZE;
+	fbp = (unsigned char *)((unsigned int)video_fb_address +
+				(((y + yoff) * VIDEO_COLS) + xoff) * bpp);
+
+	bm = (uchar *)img + __le32_to_cpu(img->header.data_offset);
+
+	/* pre-calculate and setup palette */
+	switch (VIDEO_DATA_FORMAT) {
+	case GDF__8BIT_INDEX:
+		for (i = 0; i < ncolors; i++) {
+			cte = img->color_table[i];
+			video_set_lut (i, cte.red, cte.green, cte.blue);
+		}
+		break;
+	case GDF_15BIT_555RGB:
+	case GDF_16BIT_565RGB:
+		if (VIDEO_DATA_FORMAT == GDF_15BIT_555RGB) {
+			green_shift = 3;
+			red_off = 10;
+		} else {
+			green_shift = 2;
+			red_off = 11;
+		}
+		for (i = 0; i < ncolors; i++) {
+			cte = img->color_table[i];
+			p[i].ce.w = SWAP16((unsigned short)
+					   (((cte.red >> 3) << red_off) |
+					    ((cte.green >> green_shift) << 5) |
+					    cte.blue >> 3));
+		}
+		break;
+	case GDF_32BIT_X888RGB:
+		for (i = 0; i < ncolors; i++) {
+			cte = img->color_table[i];
+			p[i].ce.dw = SWAP32((cte.red << 16) | (cte.green << 8) |
+					     cte.blue);
+		}
+		break;
+	default:
+		printf("RLE Bitmap unsupported in video mode 0x%x\n",
+			VIDEO_DATA_FORMAT);
+		return -1;
+	}
+
+	while (decode) {
+		switch (bm[0]) {
+		case 0:
+			switch (bm[1]) {
+			case 0:
+				/* scan line end marker */
+				bm += 2;
+				x = 0;
+				y--;
+				fbp = (unsigned char *)
+					((unsigned int)video_fb_address +
+					 (((y + yoff) * VIDEO_COLS) +
+					  xoff) * bpp);
+				continue;
+			case 1:
+				/* end of bitmap data marker */
+				decode = 0;
+				break;
+			case 2:
+				/* run offset marker */
+				x += bm[2];
+				y -= bm[3];
+				fbp = (unsigned char *)
+					((unsigned int)video_fb_address +
+					 (((y + yoff) * VIDEO_COLS) +
+					  x + xoff) * bpp);
+				bm += 4;
+				break;
+			default:
+				/* unencoded run */
+				cnt = bm[1];
+				runlen = cnt;
+				bm += 2;
+				if (y < height) {
+					if (x >= width) {
+						x += runlen;
+						goto next_run;
+					}
+					if (x + runlen > width)
+						cnt = width - x;
+
+					draw_bitmap (&fbp, bm, p, cnt, 0);
+					x += runlen;
+				}
+next_run:
+				bm += runlen;
+				if (runlen & 1)
+					bm++; /* 0 padding if length is odd */
+			}
+			break;
+		default:
+			/* encoded run */
+			if (y < height) { /* only draw into visible area */
+				cnt = bm[0];
+				runlen = cnt;
+				if (x >= width) {
+					x += runlen;
+					bm += 2;
+					continue;
+				}
+				if (x + runlen > width)
+					cnt = width - x;
+
+				draw_bitmap (&fbp, bm, p, cnt, 1);
+				x += runlen;
+			}
+			bm += 2;
+			break;
+		}
+	}
+	return 0;
+}
+#endif
+
+/*
  * Display the BMP file located at address bmp_image.
- * Only uncompressed
  */
 int video_display_bitmap (ulong bmp_image, int x, int y)
 {
@@ -872,7 +1057,11 @@
 	debug ("Display-bmp: %d x %d  with %d colors\n",
 	       width, height, colors);
 
-	if (compression != BMP_BI_RGB) {
+	if (compression != BMP_BI_RGB
+#ifdef CONFIG_VIDEO_BMP_RLE8
+	    && compression != BMP_BI_RLE8
+#endif
+	   ) {
 		printf ("Error: compression type %ld not supported\n",
 			compression);
 #ifdef CONFIG_VIDEO_BMP_GZIP
@@ -906,6 +1095,13 @@
 			((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) +
 			x * VIDEO_PIXEL_SIZE);
 
+#ifdef CONFIG_VIDEO_BMP_RLE8
+	if (compression == BMP_BI_RLE8) {
+		return display_rle8_bitmap(bmp,
+					   x, y, width, height);
+	}
+#endif
+
 	/* We handle only 8bpp or 24 bpp bitmap */
 	switch (le16_to_cpu (bmp->header.bit_count)) {
 	case 8: