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/usbdr... ============================================================================== --- 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/usbdr... ============================================================================== --- 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__ */