[ros-diffs] [fireball] 30595: - Further develop OHCI init code (based on linux-2.6.14.3).

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Nov 20 14:51:59 CET 2007


Author: fireball
Date: Tue Nov 20 16:51:59 2007
New Revision: 30595

URL: http://svn.reactos.org/svn/reactos?rev=30595&view=rev
Log:
- Further develop OHCI init code (based on linux-2.6.14.3).

Modified:
    trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c
    trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h

Modified: trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c?rev=30595&r1=30594&r2=30595&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c (original)
+++ trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c Tue Nov 20 16:51:59 2007
@@ -45,6 +45,33 @@
 
 extern USB_DEV_MANAGER g_dev_mgr;
 
+
+#define OHCI_READ_PORT_ULONG( pul ) ( *pul )
+#define OHCI_WRITE_PORT_ULONG( pul, src ) \
+{\
+   	*pul = ( ULONG )src;\
+}
+
+#define OHCI_READ_PORT_UCHAR( pch ) ( *pch )
+#define OHCI_WRITE_PORT_UCHAR( pch, src ) ( *pch = ( UCHAR )src )
+#define OHCI_READ_PORT_USHORT( psh ) ( *psh )
+#define OHCI_WRITE_PORT_USHORT( psh, src ) ( *psh = ( USHORT )src )
+
+VOID
+ohci_wait_ms(POHCI_DEV ohci, LONG ms)
+{
+    LARGE_INTEGER lms;
+    if (ms <= 0)
+        return;
+
+    lms.QuadPart = -10 * ms;
+    KeSetTimer(&ohci->reset_timer, lms, NULL);
+
+    KeWaitForSingleObject(&ohci->reset_timer, Executive, KernelMode, FALSE, NULL);
+
+    return;
+}
+
 PDEVICE_OBJECT ohci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path,
                           PUSB_DEV_MANAGER dev_mgr)
 {
@@ -98,7 +125,7 @@
         if (pdev_ext)
         {
             // acquire higher irql to eliminate pre-empty
-            KeSynchronizeExecution(pdev_ext->ohci_int, ehci_cal_cpu_freq, NULL);
+            //KeSynchronizeExecution(pdev_ext->ohci_int, ehci_cal_cpu_freq, NULL);
         }
     }
     return NULL;
@@ -234,6 +261,38 @@
 
     //before we connect the interrupt, we have to init ohci
     pdev_ext->ohci->pdev_ext = pdev_ext;
+
+    KeInitializeTimer(&pdev_ext->ohci->reset_timer);
+
+    // take it over from SMM/BIOS/whoever has it
+	if (OHCI_READ_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CONTROL)) & OHCI_CTRL_IR)
+    {
+		ULONG temp;
+
+		DbgPrint("USB HC TakeOver from BIOS/SMM\n");
+
+		/* this timeout is arbitrary.  we make it long, so systems
+		 * depending on usb keyboards may be usable even if the
+		 * BIOS/SMM code seems pretty broken.
+		 */
+		temp = 500;	/* arbitrary: five seconds */
+
+        OHCI_WRITE_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_INTRENABLE), OHCI_INTR_OC);
+        OHCI_WRITE_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CMDSTATUS), OHCI_OCR);
+
+        while (OHCI_READ_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CONTROL)) & OHCI_CTRL_IR)
+        {
+			ohci_wait_ms(pdev_ext->ohci, 10);
+			if (--temp == 0) {
+				DbgPrint("USB HC takeover failed!"
+					"  (BIOS/SMM bug)\n");
+				return NULL;
+			}
+		}
+		//ohci_usb_reset (ohci);
+	}
+
+
 #if 0
     //init ehci_caps
     // i = ( ( PEHCI_HCS_CONTENT )( &pdev_ext->ehci->ehci_caps.hcs_params ) )->length;
@@ -258,8 +317,6 @@
                                     &pdev_ext->ehci->pending_endp_list));
 
     init_pending_endp_pool(&pdev_ext->ehci->pending_endp_pool);
-
-    KeInitializeTimer(&pdev_ext->ehci->reset_timer);
 
     vector = HalGetInterruptVector(PCIBus,
                                    bus,

Modified: trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h?rev=30595&r1=30594&r2=30595&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h (original)
+++ trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h Tue Nov 20 16:51:59 2007
@@ -20,6 +20,142 @@
 
 #define OHCI_DEVICE_NAME "\\Device\\OHCI"
 #define OHCI_DOS_DEVICE_NAME "\\DosDevices\\OHCI"
+
+/* Host Controller Operational Registers */
+
+#define OHCI_REVISION       0x0
+#define OHCI_CONTROL        0x4
+#define OHCI_CMDSTATUS      0x8
+#define OHCI_INTRSTATUS     0xc
+#define OHCI_INTRENABLE     0x10
+#define OHCI_INTRDISABLE    0x14
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR	(3 << 0)	/* control/bulk service ratio */
+#define OHCI_CTRL_PLE	(1 << 2)	/* periodic list enable */
+#define OHCI_CTRL_IE	(1 << 3)	/* isochronous enable */
+#define OHCI_CTRL_CLE	(1 << 4)	/* control list enable */
+#define OHCI_CTRL_BLE	(1 << 5)	/* bulk list enable */
+#define OHCI_CTRL_HCFS	(3 << 6)	/* host controller functional state */
+#define OHCI_CTRL_IR	(1 << 8)	/* interrupt routing */
+#define OHCI_CTRL_RWC	(1 << 9)	/* remote wakeup connected */
+#define OHCI_CTRL_RWE	(1 << 10)	/* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+#	define OHCI_USB_RESET	(0 << 6)
+#	define OHCI_USB_RESUME	(1 << 6)
+#	define OHCI_USB_OPER	(2 << 6)
+#	define OHCI_USB_SUSPEND	(3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR	(1 << 0)	/* host controller reset */
+#define OHCI_CLF  	(1 << 1)	/* control list filled */
+#define OHCI_BLF  	(1 << 2)	/* bulk list filled */
+#define OHCI_OCR  	(1 << 3)	/* ownership change request */
+#define OHCI_SOC  	(3 << 16)	/* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO	(1 << 0)	/* scheduling overrun */
+#define OHCI_INTR_WDH	(1 << 1)	/* writeback of done_head */
+#define OHCI_INTR_SF	(1 << 2)	/* start frame */
+#define OHCI_INTR_RD	(1 << 3)	/* resume detect */
+#define OHCI_INTR_UE	(1 << 4)	/* unrecoverable error */
+#define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */
+#define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */
+#define OHCI_INTR_OC	(1 << 30)	/* ownership change */
+#define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */
+
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS            0x00000001   	/* current connect status */
+#define RH_PS_PES            0x00000002   	/* port enable status*/
+#define RH_PS_PSS            0x00000004   	/* port suspend status */
+#define RH_PS_POCI           0x00000008   	/* port over current indicator */
+#define RH_PS_PRS            0x00000010  	/* port reset status */
+#define RH_PS_PPS            0x00000100   	/* port power status */
+#define RH_PS_LSDA           0x00000200    	/* low speed device attached */
+#define RH_PS_CSC            0x00010000 	/* connect status change */
+#define RH_PS_PESC           0x00020000   	/* port enable status change */
+#define RH_PS_PSSC           0x00040000    	/* port suspend status change */
+#define RH_PS_OCIC           0x00080000    	/* over current indicator change */
+#define RH_PS_PRSC           0x00100000   	/* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS	     0x00000001		/* local power status */
+#define RH_HS_OCI	     0x00000002		/* over current indicator */
+#define RH_HS_DRWE	     0x00008000		/* device remote wakeup enable */
+#define RH_HS_LPSC	     0x00010000		/* local power status change */
+#define RH_HS_OCIC	     0x00020000		/* over current indicator change */
+#define RH_HS_CRWE	     0x80000000		/* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR		0x0000ffff		/* device removable flags */
+#define RH_B_PPCM	0xffff0000		/* port power control mask */
+
+/* roothub.a masks */
+#define	RH_A_NDP	(0xff << 0)		/* number of downstream ports */
+#define	RH_A_PSM	(1 << 8)		/* power switching mode */
+#define	RH_A_NPS	(1 << 9)		/* no power switching */
+#define	RH_A_DT		(1 << 10)		/* device type (mbz) */
+#define	RH_A_OCPM	(1 << 11)		/* over current protection mode */
+#define	RH_A_NOCP	(1 << 12)		/* no over current protection */
+#define	RH_A_POTPGT	(0xff << 24)		/* power on to power good time */
+
+/*
+ * This is the structure of the OHCI controller's memory mapped I/O region.
+ * You must use readl() and writel() (in <asm/io.h>) to access these fields!!
+ * Layout is in section 7 (and appendix B) of the spec.
+ */
+struct _OHCI_REGS
+{
+	/* control and status registers (section 7.1) */
+	ULONG	revision;
+	ULONG	control;
+	ULONG	cmdstatus;
+	ULONG	intrstatus;
+	ULONG	intrenable;
+	ULONG	intrdisable;
+
+	/* memory pointers (section 7.2) */
+	ULONG	hcca;
+	ULONG	ed_periodcurrent;
+	ULONG	ed_controlhead;
+	ULONG	ed_controlcurrent;
+	ULONG	ed_bulkhead;
+	ULONG	ed_bulkcurrent;
+	ULONG	donehead;
+
+	/* frame counters (section 7.3) */
+	ULONG	fminterval;
+	ULONG	fmremaining;
+	ULONG	fmnumber;
+	ULONG	periodicstart;
+	ULONG	lsthresh;
+
+	/* Root hub ports (section 7.4) */
+	struct	ohci_roothub_regs {
+		ULONG	a;
+		ULONG	b;
+		ULONG	status;
+#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports (RH_A_NDP) */
+		ULONG	portstatus [MAX_ROOT_PORTS];
+	} roothub;
+
+	/* and optional "legacy support" registers (appendix B) at 0x0100 */
+} OHCI_REGS, *POHCI_REGS;
 
 typedef struct _OHCI_DEV
 {
@@ -58,4 +194,5 @@
 } OHCI_DEVICE_EXTENSION, *POHCI_DEVICE_EXTENSION;
 
 
+
 #endif /* __OHCI_H__ */




More information about the Ros-diffs mailing list