[ros-diffs] [fireball] 30596: - Add roothub status operations. - Ports count is correctly detected now. - Added all necessary stubs for HCD interface, so that usbdriver can work further.

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Nov 20 16:16:17 CET 2007


Author: fireball
Date: Tue Nov 20 18:16:16 2007
New Revision: 30596

URL: http://svn.reactos.org/svn/reactos?rev=30596&view=rev
Log:
- Add roothub status operations.
- Ports count is correctly detected now.
- Added all necessary stubs for HCD interface, so that usbdriver can work further.

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=30596&r1=30595&r2=30596&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c (original)
+++ trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.c Tue Nov 20 18:16:16 2007
@@ -39,8 +39,13 @@
 
 // shared with EHCI
 NTSTATUS ehci_dispatch_irp(IN PDEVICE_OBJECT DeviceObject, IN PIRP irp);
+PUSB_DEV_MANAGER ehci_get_dev_mgr(PHCD hcd);
 VOID ehci_set_dev_mgr(PHCD hcd, PUSB_DEV_MANAGER dev_mgr);
 VOID ehci_set_id(PHCD hcd, UCHAR id);
+UCHAR ehci_get_id(PHCD hcd);
+UCHAR ehci_alloc_addr(PHCD hcd);
+VOID ehci_free_addr(PHCD hcd, UCHAR addr);
+
 BOOLEAN NTAPI ehci_cal_cpu_freq(PVOID context);
 
 extern USB_DEV_MANAGER g_dev_mgr;
@@ -56,6 +61,31 @@
 #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 )
+
+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
+ * The erratum (#4) description is incorrect.  AMD's workaround waits
+ * till some bits (mostly reserved) are clear; ok for all revs.
+ */
+#define read_roothub(hc, register, mask) ({ \
+	ULONG temp = OHCI_READ_PORT_ULONG(&((hc)->regs->roothub.register)); \
+	if (temp == -1) \
+		/*disable (hc)*/; \
+	/*else if (hc->flags & OHCI_QUIRK_AMD756) \
+		while (temp & mask) \
+			temp = ohci_readl (hc, &hc->regs->roothub.register); */ \
+	temp; })
+
+static ULONG roothub_a (POHCI_DEV hc)
+	{ return read_roothub (hc, a, 0xfc0fe000); }
+/*
+static inline u32 roothub_b (struct ohci_hcd *hc)
+	{ return ohci_readl (hc, &hc->regs->roothub.b); }
+static inline u32 roothub_status (struct ohci_hcd *hc)
+	{ return ohci_readl (hc, &hc->regs->roothub.status); }
+static u32 roothub_portstatus (struct ohci_hcd *hc, int i)
+	{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+*/
+
 
 VOID
 ohci_wait_ms(POHCI_DEV ohci, LONG ms)
@@ -261,6 +291,7 @@
 
     //before we connect the interrupt, we have to init ohci
     pdev_ext->ohci->pdev_ext = pdev_ext;
+    pdev_ext->ohci->regs = (POHCI_REGS)pdev_ext->ohci->port_base;
 
     KeInitializeTimer(&pdev_ext->ohci->reset_timer);
 
@@ -292,6 +323,23 @@
 		//ohci_usb_reset (ohci);
 	}
 
+	/* Disable HC interrupts */
+    OHCI_WRITE_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_INTRDISABLE), OHCI_INTR_MIE);
+	// flush the writes
+    (VOID)OHCI_READ_PORT_ULONG((PULONG)(pdev_ext->ohci->port_base + OHCI_CONTROL));
+
+	/* Read the number of ports unless overridden */
+	pdev_ext->ohci->num_ports = roothub_a(pdev_ext->ohci) & RH_A_NDP;
+
+    DbgPrint("OHCI: %d ports\n", pdev_ext->ohci->num_ports);
+
+	//ohci->hcca = dma_alloc_coherent (ohci_to_hcd(ohci)->self.controller,
+	//		sizeof *ohci->hcca, &ohci->hcca_dma, 0);
+	//if (!ohci->hcca)
+	//	return -ENOMEM;
+
+	//if ((ret = ohci_mem_init (ohci)) < 0)
+	//	ohci_stop (ohci_to_hcd(ohci));
 
 #if 0
     //init ehci_caps
@@ -413,30 +461,217 @@
     return pdev;
 }
 
+BOOLEAN
+ohci_start(PHCD hcd)
+{
+    //ULONG tmp;
+    //PBYTE base;
+    //PEHCI_USBCMD_CONTENT usbcmd;
+    //POHCI_DEV ohci;
+
+    if (hcd == NULL)
+        return FALSE;
+
+    return TRUE;
+#if 0
+    ehci = struct_ptr(hcd, EHCI_DEV, hcd_interf);
+    base = ehci->port_base;
+
+    // stop the controller
+    tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBCMD));
+    usbcmd = (PEHCI_USBCMD_CONTENT) & tmp;
+    usbcmd->run_stop = 0;
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
+
+    // wait the controller stop( ehci spec, 16 microframe )
+    usb_wait_ms_dpc(2);
+
+    // reset the controller
+    usbcmd = (PEHCI_USBCMD_CONTENT) & tmp;
+    usbcmd->hcreset = TRUE;
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
+
+    for(;;)
+    {
+        // interval.QuadPart = -100 * 10000; // 10 ms
+        // KeDelayExecutionThread( KernelMode, FALSE, &interval );
+        KeStallExecutionProcessor(10);
+        tmp = EHCI_READ_PORT_ULONG((PULONG) (base + EHCI_USBCMD));
+        if (!usbcmd->hcreset)
+            break;
+    }
+
+    // prepare the registers
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_CTRLDSSEGMENT), 0);
+
+    // turn on all the int
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBINTR),
+                          EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
+                          // EHCI_USBINTR_FLROVR | \  // it is noisy
+                          // EHCI_USBINTR_PC     // we detect it by polling
+        );
+    // write the list base reg
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_PERIODICLISTBASE), ehci->frame_list_phys_addr.LowPart);
+
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_ASYNCLISTBASE), ehci->skel_async_qh->phys_addr & ~(0x1f));
+
+    usbcmd->int_threshold = 1;
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
+
+    // let's rock
+    usbcmd->run_stop = 1;
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
+
+    // set the configuration flag
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_CONFIGFLAG), 1);
+
+    // enable the list traversaling
+    usbcmd->async_enable = 1;
+    usbcmd->periodic_enable = 1;
+    EHCI_WRITE_PORT_ULONG((PULONG) (base + EHCI_USBCMD), tmp);
+#endif
+    return TRUE;
+}
+
+
+ULONG
+ohci_get_type(PHCD hcd)
+{
+    return HCD_TYPE_OHCI;       // ( hcd->flags & HCD_TYPE_MASK );
+}
+
+NTSTATUS
+ohci_submit_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
+{
+    return STATUS_UNSUCCESSFUL;
+}
+
+PUSB_DEV
+ohci_get_root_hub(PHCD hcd)
+{
+    return ohci_from_hcd(hcd)->root_hub;
+}
+
+VOID
+ohci_set_root_hub(PHCD hcd, PUSB_DEV root_hub)
+{
+    if (hcd == NULL || root_hub == NULL)
+        return;
+    ohci_from_hcd(hcd)->root_hub = root_hub;
+    return;
+}
+
+BOOLEAN
+ohci_remove_device2(PHCD hcd, PUSB_DEV pdev)
+{
+    if (hcd == NULL || pdev == NULL)
+        return FALSE;
+
+    return FALSE;
+    //return ehci_remove_device(ehci_from_hcd(hcd), pdev);
+}
+
+BOOLEAN
+ohci_hcd_release(PHCD hcd)
+{
+    POHCI_DEV ohci;
+    POHCI_DEVICE_EXTENSION pdev_ext;
+
+    if (hcd == NULL)
+        return FALSE;
+
+    ohci = ohci_from_hcd(hcd);
+    pdev_ext = ohci->pdev_ext;
+    return FALSE;//ehci_release(pdev_ext->pdev_obj);
+}
+
+NTSTATUS
+ohci_cancel_urb2(PHCD hcd, PUSB_DEV pdev, PUSB_ENDPOINT pendp, PURB purb)
+{
+    POHCI_DEV ohci;
+    if (hcd == NULL)
+        return STATUS_INVALID_PARAMETER;
+
+    ohci = ohci_from_hcd(hcd);
+    return STATUS_UNSUCCESSFUL;//ehci_cancel_urb(ehci, pdev, pendp, purb);
+}
+
+VOID
+ohci_generic_urb_completion(PURB purb, PVOID context)
+{
+}
+
+BOOLEAN
+ohci_rh_reset_port(PHCD hcd, UCHAR port_idx)
+{
+    //ULONG i;
+    POHCI_DEV ohci;
+    //ULONG status;
+    //UCHAR port_count;
+
+    if (hcd == NULL)
+        return FALSE;
+
+    ohci = ohci_from_hcd(hcd);
+    //port_count = (UCHAR) ((PEHCI_HCS_CONTENT) & ehci->ehci_caps.hcs_params)->port_count;
+
+    //if (port_idx < 1 || port_idx > port_count)
+    //    return FALSE;
+
+    //usb_dbg_print(DBGLVL_MAXIMUM, ("ohci_rh_reset_port(): status after written=0x%x\n", status));
+    return TRUE;
+}
+
+NTSTATUS
+ohci_hcd_dispatch(PHCD hcd, LONG disp_code, PVOID param)
+{
+    POHCI_DEV ohci;
+
+    if (hcd == NULL)
+        return STATUS_INVALID_PARAMETER;
+    ohci = ohci_from_hcd(hcd);
+#if 0
+    switch (disp_code)
+    {
+        case HCD_DISP_READ_PORT_COUNT:
+        {
+            if (param == NULL)
+                return STATUS_INVALID_PARAMETER;
+            *((PUCHAR) param) = (UCHAR) HCS_N_PORTS(ehci->ehci_caps.hcs_params);
+            return STATUS_SUCCESS;
+        }
+        case HCD_DISP_READ_RH_DEV_CHANGE:
+        {
+            if (ehci_rh_get_dev_change(hcd, param) == FALSE)
+                return STATUS_INVALID_PARAMETER;
+            return STATUS_SUCCESS;
+        }
+    }
+#endif
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 VOID
 ohci_init_hcd_interface(POHCI_DEV ohci)
 {
     ohci->hcd_interf.hcd_set_dev_mgr = ehci_set_dev_mgr;
-#if 0
     ohci->hcd_interf.hcd_get_dev_mgr = ehci_get_dev_mgr;
-    ohci->hcd_interf.hcd_get_type = ehci_get_type;
-#endif
+    ohci->hcd_interf.hcd_get_type = ohci_get_type;
     ohci->hcd_interf.hcd_set_id = ehci_set_id;
-#if 0
     ohci->hcd_interf.hcd_get_id = ehci_get_id;
     ohci->hcd_interf.hcd_alloc_addr = ehci_alloc_addr;
     ohci->hcd_interf.hcd_free_addr = ehci_free_addr;
-    ohci->hcd_interf.hcd_submit_urb = ehci_submit_urb2;
-    ohci->hcd_interf.hcd_generic_urb_completion = ehci_generic_urb_completion;
-    ohci->hcd_interf.hcd_get_root_hub = ehci_get_root_hub;
-    ohci->hcd_interf.hcd_set_root_hub = ehci_set_root_hub;
-    ohci->hcd_interf.hcd_remove_device = ehci_remove_device2;
-    ohci->hcd_interf.hcd_rh_reset_port = ehci_rh_reset_port;
-    ohci->hcd_interf.hcd_release = ehci_hcd_release;
-    ohci->hcd_interf.hcd_cancel_urb = ehci_cancel_urb2;
-    ohci->hcd_interf.hcd_start = ehci_start;
-    ohci->hcd_interf.hcd_dispatch = ehci_hcd_dispatch;
-#endif
+    ohci->hcd_interf.hcd_submit_urb = ohci_submit_urb2;
+    ohci->hcd_interf.hcd_generic_urb_completion = ohci_generic_urb_completion;
+    ohci->hcd_interf.hcd_get_root_hub = ohci_get_root_hub;
+    ohci->hcd_interf.hcd_set_root_hub = ohci_set_root_hub;
+    ohci->hcd_interf.hcd_remove_device = ohci_remove_device2;
+    ohci->hcd_interf.hcd_rh_reset_port = ohci_rh_reset_port;
+    ohci->hcd_interf.hcd_release = ohci_hcd_release;
+    ohci->hcd_interf.hcd_cancel_urb = ohci_cancel_urb2;
+    ohci->hcd_interf.hcd_start = ohci_start;
+    ohci->hcd_interf.hcd_dispatch = ohci_hcd_dispatch;
+
     ohci->hcd_interf.flags = HCD_TYPE_OHCI;     //hcd types | hcd id
 }
 

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=30596&r1=30595&r2=30596&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h (original)
+++ trunk/reactos/drivers/usb/nt4compat/usbdriver/ohci.h Tue Nov 20 18:16:16 2007
@@ -119,7 +119,7 @@
  * 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
+typedef struct _OHCI_REGS
 {
 	/* control and status registers (section 7.1) */
 	ULONG	revision;
@@ -164,6 +164,9 @@
     PHYSICAL_ADDRESS   	ohci_reg_base;						// io space
     BOOLEAN				port_mapped;
     PBYTE				port_base;							// note: added by ehci_caps.length, operational regs base addr, not the actural base
+    struct _OHCI_REGS   *regs;
+
+    USHORT              num_ports;
 
     KTIMER				reset_timer;						//used to reset the host controller
     struct _OHCI_DEVICE_EXTENSION    *pdev_ext;
@@ -193,6 +196,6 @@
     KDPC   				ohci_dpc;
 } OHCI_DEVICE_EXTENSION, *POHCI_DEVICE_EXTENSION;
 
-
+#define ohci_from_hcd( hCD ) ( struct_ptr( ( hCD ), OHCI_DEV, hcd_interf ) )
 
 #endif /* __OHCI_H__ */




More information about the Ros-diffs mailing list