mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
- Further develop OHCI init code (based on linux-2.6.14.3).
svn path=/trunk/; revision=30595
This commit is contained in:
parent
50c8bf2b7a
commit
9a0b86e617
2 changed files with 197 additions and 3 deletions
|
@ -45,6 +45,33 @@ BOOLEAN NTAPI ehci_cal_cpu_freq(PVOID context);
|
|||
|
||||
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 @@ PDEVICE_OBJECT ohci_probe(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path,
|
|||
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 @@ ohci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU
|
|||
|
||||
//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;
|
||||
|
@ -259,8 +318,6 @@ ohci_alloc(PDRIVER_OBJECT drvr_obj, PUNICODE_STRING reg_path, ULONG bus_addr, PU
|
|||
|
||||
init_pending_endp_pool(&pdev_ext->ehci->pending_endp_pool);
|
||||
|
||||
KeInitializeTimer(&pdev_ext->ehci->reset_timer);
|
||||
|
||||
vector = HalGetInterruptVector(PCIBus,
|
||||
bus,
|
||||
pdev_ext->res_interrupt.level,
|
||||
|
|
|
@ -21,6 +21,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
|
||||
{
|
||||
HCD hcd_interf;
|
||||
|
@ -58,4 +194,5 @@ typedef struct _OHCI_DEVICE_EXTENSION
|
|||
} OHCI_DEVICE_EXTENSION, *POHCI_DEVICE_EXTENSION;
|
||||
|
||||
|
||||
|
||||
#endif /* __OHCI_H__ */
|
||||
|
|
Loading…
Reference in a new issue