The Pedigree Project 0.1
modules/drivers/common/usb-hcd/main.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/Log.h"
21#include "pedigree/kernel/machine/Device.h"
22#include "pedigree/kernel/processor/Processor.h"
23#include "pedigree/kernel/utilities/new"
24
25#include "Ehci.h"
26#include "Ohci.h"
27#include "Uhci.h"
28#include "Xhci.h"
29#include "modules/Module.h"
30
31enum HcdConstants {
32 HCI_CLASS = 0x0C, // Host Controller PCI class
33 HCI_SUBCLASS = 0x03, // Host Controller PCI subclass
34 HCI_PROGIF_UHCI = 0x00, // UHCI PCI programming interface
35 HCI_PROGIF_OHCI = 0x10, // OHCI PCI programming interface
36 HCI_PROGIF_EHCI = 0x20, // EHCI PCI programming interface
37 HCI_PROGIF_XHCI = 0x30, // xHCI PCI programming interface
38};
39
40static bool bFound = false;
41
42static void probeXhci(Device* pDev) {
43 NOTICE("USB: xHCI found");
44 Xhci* pXhci = new Xhci(pDev);
45 if (!pXhci->initialiseController()) {
46 ERROR("USB: xHCI failed to initialise");
47 delete pXhci;
48 return;
49 }
50 pDev->getParent()->replaceChild(pDev, pXhci);
51 delete pDev;
52 bFound = true;
53}
54
55static void probeEhci(Device* pDev) {
56 NOTICE("USB: EHCI found");
57
58 // Create a new Ehci node
59 Ehci* pEhci = new Ehci(pDev);
60 bool success = pEhci->initialiseController();
61 if (!success) {
62 NOTICE("USB: EHCI failed to initialise");
63 delete pEhci;
64 return;
65 }
66
67 // Replace pDev with pEhci, then delete pDev
68 pDev->getParent()->replaceChild(pDev, pEhci);
69 delete pDev;
70 pEhci->startFirmwareRecovery();
71
72 bFound = true;
73}
74
75static void probeOhci(Device* pDev) {
76 NOTICE("USB: OHCI found");
77
78 // Create a new Ohci node
79 Ohci* pOhci = new Ohci(pDev);
80 if (!pOhci->initialised()) {
81 NOTICE("USB: OHCI failed to initialise");
82 delete pOhci;
83 return;
84 }
85
86 // Replace pDev with pOhci, then delete pDev
87 pDev->getParent()->replaceChild(pDev, pOhci);
88 delete pDev;
89
90 bFound = true;
91}
92
93#if X86_COMMON
94static void probeUhci(Device* pDev) {
95 NOTICE("USB: UHCI found");
96
97 // Create a new Uhci node
98 Uhci* pUhci = new Uhci(pDev);
99 if (!pUhci->initialised()) {
100 delete pUhci;
101 return;
102 }
103
104 // Replace pDev with pUhci, then delete pDev
105 pDev->getParent()->replaceChild(pDev, pUhci);
106 delete pDev;
107
108 bFound = true;
109}
110#endif
111
112static bool entry() {
113 // Interrupts may get disabled on the way here, so make sure they are
114 // enabled
116 Device::searchByClassSubclassAndProgInterface(HCI_CLASS, HCI_SUBCLASS, HCI_PROGIF_XHCI,
117 probeXhci);
118 Device::searchByClassSubclassAndProgInterface(HCI_CLASS, HCI_SUBCLASS, HCI_PROGIF_EHCI,
119 probeEhci);
120 Device::searchByClassSubclassAndProgInterface(HCI_CLASS, HCI_SUBCLASS, HCI_PROGIF_OHCI,
121 probeOhci);
122#if X86_COMMON
123 Device::searchByClassSubclassAndProgInterface(HCI_CLASS, HCI_SUBCLASS, HCI_PROGIF_UHCI,
124 probeUhci);
125#endif
126
127 return bFound;
128}
129
130static void exit() {}
131
132#if X86_COMMON
133MODULE_INFO_NON_UNLOADABLE("usb-hcd", &entry, &exit, "pci", "usb");
134#else
135MODULE_INFO_NON_UNLOADABLE("usb-hcd", &entry, &exit, "usb");
136#endif
Device * getParent() const
Definition Device.h:166
void replaceChild(Device *src, Device *dest)
Definition Device.cc:166
Definition Ehci.h:57
Definition Ohci.h:54
static void setInterrupts(bool bEnable)
Definition Uhci.h:54
Definition Xhci.h:16