[coreboot] New patch to review for coreboot: ac87dc9 libpayload: Fix initialization of OHCI driver

Nico Huber (nico.huber@secunet.com) gerrit at coreboot.org
Wed Jun 20 17:36:45 CEST 2012


Nico Huber (nico.huber at secunet.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1126

-gerrit

commit ac87dc97d32ca8c8cfa5aa163fbe7358b4dd3608
Author: Nico Huber <nico.huber at secunet.com>
Date:   Wed Jun 20 11:37:17 2012 +0200

    libpayload: Fix initialization of OHCI driver
    
    This fixes some memory corruption, leaking and padding issues within
    the initialization of the OHCI driver.
    
    Change-Id: If6891f2a53e339d32c4324f4c9e0b1ed07596a60
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 payloads/libpayload/drivers/usb/ohci.c         |   14 +++++++++-----
 payloads/libpayload/drivers/usb/ohci_private.h |   22 ++++++++++++----------
 2 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/payloads/libpayload/drivers/usb/ohci.c b/payloads/libpayload/drivers/usb/ohci.c
index be6d5e3..6d98cc1 100644
--- a/payloads/libpayload/drivers/usb/ohci.c
+++ b/payloads/libpayload/drivers/usb/ohci.c
@@ -129,17 +129,20 @@ ohci_init (pcidev_t addr)
 	}
 	int interval = OHCI_INST (controller)->opreg->HcFmInterval;
 
-	td_t *periodic_td = memalign(sizeof(*periodic_td), sizeof(*periodic_td));
-	memset((void*)periodic_td, 0, sizeof(*periodic_td));
-	for (i=0; i<32; i++) OHCI_INST (controller)->hcca->HccaInterruptTable[i] = virt_to_phys(periodic_td);
-	/* TODO: build HCCA data structures */
-
 	OHCI_INST (controller)->opreg->HcCommandStatus = HostControllerReset;
 	udelay (10); /* at most 10us for reset to complete. State must be set to Operational within 2ms (5.1.1.4) */
 	OHCI_INST (controller)->opreg->HcFmInterval = interval;
 	OHCI_INST (controller)->hcca = memalign(256, 256);
 	memset((void*)OHCI_INST (controller)->hcca, 0, 256);
 
+	/* Initialize interrupt table. */
+	u32 *const intr_table = OHCI_INST(controller)->hcca->HccaInterruptTable;
+	ed_t *const periodic_ed = memalign(sizeof(ed_t), sizeof(ed_t));
+	memset((void *)periodic_ed, 0, sizeof(*periodic_ed));
+	for (i = 0; i < 32; ++i)
+		intr_table[i] = virt_to_phys(periodic_ed);
+	OHCI_INST (controller)->periodic_ed = periodic_ed;
+
 	OHCI_INST (controller)->opreg->HcHCCA = virt_to_phys(OHCI_INST (controller)->hcca);
 	OHCI_INST (controller)->opreg->HcControl &= ~IsochronousEnable; // unused by this driver
 	// disable everything, contrary to what OHCI spec says in 5.1.1.4, as we don't need IRQs
@@ -167,6 +170,7 @@ ohci_shutdown (hci_t *controller)
 	ohci_stop(controller);
 	OHCI_INST (controller)->roothub->destroy (OHCI_INST (controller)->
 						  roothub);
+	free ((void *)OHCI_INST (controller)->periodic_ed);
 	free (OHCI_INST (controller));
 	free (controller);
 }
diff --git a/payloads/libpayload/drivers/usb/ohci_private.h b/payloads/libpayload/drivers/usb/ohci_private.h
index 0bcae03..3826db0 100644
--- a/payloads/libpayload/drivers/usb/ohci_private.h
+++ b/payloads/libpayload/drivers/usb/ohci_private.h
@@ -189,22 +189,15 @@
 	volatile u32 HcRhPortStatus[];
      } __attribute__ ((packed)) opreg_t;
 
- 	typedef struct {
+	typedef struct { /* should be 256 bytes according to spec */
 		u32 HccaInterruptTable[32];
 		volatile u16 HccaFrameNumber;
 		volatile u16 HccaPad1;
 		volatile u32 HccaDoneHead;
-		u8 reserved[116]; // pad to 256 byte
+		u8 reserved[116]; /* pad according to spec */
+		u8 what[4]; /* really pad to 256 as spec only covers 252 */
 	} __attribute__ ((packed)) hcca_t;
 
-	typedef struct ohci {
-		opreg_t *opreg;
-		hcca_t *hcca;
-		usbdev_t *roothub;
-	} ohci_t;
-
-	typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t;
-
 	typedef volatile struct {
 		u32 config;
 		u32 tail_pointer;
@@ -259,4 +252,13 @@
 
 #define OHCI_INST(controller) ((ohci_t*)((controller)->instance))
 
+	typedef struct ohci {
+		opreg_t *opreg;
+		hcca_t *hcca;
+		usbdev_t *roothub;
+		ed_t *periodic_ed;
+	} ohci_t;
+
+	typedef enum { OHCI_SETUP=0, OHCI_OUT=1, OHCI_IN=2, OHCI_FROM_TD=3 } ohci_pid_t;
+
 #endif




More information about the coreboot mailing list