The Pedigree Project  0.1
Ehci.h
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 #ifndef EHCI_H
21 #define EHCI_H
22 
23 #include "modules/system/usb/Usb.h"
24 #include "modules/system/usb/UsbHub.h"
25 #include "pedigree/kernel/Spinlock.h"
26 #include "pedigree/kernel/compiler.h"
27 #include "pedigree/kernel/machine/IrqHandler.h"
28 #include "pedigree/kernel/machine/types.h"
29 #include "pedigree/kernel/process/Mutex.h"
30 #include "pedigree/kernel/processor/MemoryRegion.h"
31 #include "pedigree/kernel/processor/state_forward.h"
32 #include "pedigree/kernel/processor/types.h"
33 #include "pedigree/kernel/utilities/ExtensibleBitmap.h"
34 #include "pedigree/kernel/utilities/RequestQueue.h"
35 #include "pedigree/kernel/utilities/String.h"
36 
37 class Device;
38 class IoBase;
39 
41 class Ehci : public UsbHub,
42 #ifdef X86_COMMON
43  public IrqHandler,
44 #else
45  public InterruptHandler,
46 #endif
47  public RequestQueue
48 {
49  public:
50  Ehci(Device *pDev);
51  virtual ~Ehci();
52 
53  bool initialiseController();
54 
55  struct qTD
56  {
57  uint32_t bNextInvalid : 1;
58  uint32_t res0 : 4;
59  uint32_t pNext : 27;
60  uint32_t bAltNextInvalid : 1;
61  uint32_t res1 : 4;
62  uint32_t pAltNext : 27;
63  uint32_t nStatus : 8;
64  uint32_t nPid : 2;
65  uint32_t nErr : 2;
66  uint32_t nPage : 3;
67  uint32_t bIoc : 1;
68  uint32_t nBytes : 15;
69  uint32_t bDataToggle : 1;
70  uint32_t nOffset : 12;
71  uint32_t pPage0 : 20;
72  uint32_t res2 : 12;
73  uint32_t pPage1 : 20;
74  uint32_t res3 : 12;
75  uint32_t pPage2 : 20;
76  uint32_t res4 : 12;
77  uint32_t pPage3 : 20;
78  uint32_t res5 : 12;
79  uint32_t pPage4 : 20;
80 
81  // 64-bit qTD fields
82  uint32_t extend0;
83  uint32_t extend1;
84  uint32_t extend2;
85  uint32_t extend3;
86  uint32_t extend4;
87 
88  // Custom qTD fields
89  uint16_t nBufferSize;
90 
91  // Possible values for status
92  enum StatusCodes
93  {
94  Halted = 0x40,
95  };
96 
97  UsbError getError()
98  {
99  if (nStatus & Halted)
100  return Stall;
101  return TransactionError;
102  }
103  } PACKED ALIGN(32);
104 
105  struct QH
106  {
107  uint32_t bNextInvalid : 1;
108  uint32_t nNextType : 2;
109  uint32_t res0 : 2;
110  uint32_t pNext : 27;
111  uint32_t nAddress : 7;
112  uint32_t bInactiveNext : 1;
113  uint32_t nEndpoint : 4;
114  uint32_t nSpeed : 2;
115  uint32_t bDataToggleSrc : 1;
116  uint32_t hrcl : 1;
117  uint32_t nMaxPacketSize : 11;
118  uint32_t bControlEndpoint : 1;
119  uint32_t nNakReload : 4;
120  uint32_t ism : 8;
121  uint32_t scm : 8;
122  uint32_t nHubAddress : 7;
123  uint32_t nHubPort : 7;
124  uint32_t mult : 2;
125  uint32_t res1 : 5;
126  uint32_t pQTD : 27;
127 
128  qTD overlay;
129 
130  struct MetaData
131  {
132  void (*pCallback)(uintptr_t, ssize_t);
133  uintptr_t pParam;
134 
135  bool bPeriodic;
136  qTD *pFirstQTD;
137  qTD *pLastQTD;
138  size_t nTotalBytes;
139 
140  QH *pPrev;
141  QH *pNext;
142 
143  bool bIgnore;
144  } * pMetaData;
146  } PACKED ALIGN(32);
147 
148  virtual void getName(String &str)
149  {
150  str = "EHCI";
151  }
152 
153  virtual void addTransferToTransaction(
154  uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer,
155  size_t nBytes);
156  virtual uintptr_t createTransaction(UsbEndpoint endpointInfo);
157 
158  virtual void doAsync(
159  uintptr_t pTransaction, void (*pCallback)(uintptr_t, ssize_t) = 0,
160  uintptr_t pParam = 0);
161  virtual void addInterruptInHandler(
162  UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes,
163  void (*pCallback)(uintptr_t, ssize_t), uintptr_t pParam = 0);
164 
166 #ifdef X86_COMMON
167  virtual bool irq(irq_id_t number, InterruptState &state);
168 #else
169  virtual void interrupt(size_t number, InterruptState &state);
170 #endif
171 
172  void doDequeue();
173 
174  virtual bool portReset(uint8_t nPort, bool bErrorResponse = false);
175 
176  protected:
177  virtual uint64_t executeRequest(
178  uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0, uint64_t p4 = 0,
179  uint64_t p5 = 0, uint64_t p6 = 0, uint64_t p7 = 0, uint64_t p8 = 0);
180 
181  private:
182  enum EhciConstants
183  {
184  EHCI_CAPLENGTH = 0x00, // Capability Registers Length
185  EHCI_HCIVERSION = 0x02, // Host Controller Interface Version
186  EHCI_HCSPARAMS = 0x04, // Host Controller Structural Parameters
187  EHCI_HCCPARAMS = 0x08, // Host Controller Structural Parameters
188 
189  EHCI_CMD = 0x00, // Command register
190  EHCI_STS = 0x04, // Status register
191  EHCI_INTR = 0x08, // Intrerrupt Enable register
192  EHCI_CTRLDSEG = 0x10, // Control Data Structure Segment Register
193  EHCI_FRINDEX = 0x0c, // Periodic Frame Index register
194  EHCI_PERIODICLP = 0x14, // Periodic List Pointer register
195  EHCI_ASYNCLP = 0x18, // Async List Pointer register
196  EHCI_CFGFLAG = 0x40, // Config Flag register
197  EHCI_PORTSC = 0x44, // Port Status/Control registers
198 
199  EHCI_CMD_ASYNCLE = 0x20, // Async List Enable bit
200  EHCI_CMD_PERIODICLE = 0x10, // Periodic List Enable bit
201  EHCI_CMD_HCRES = 0x02, // Host Controller Reset bit
202  EHCI_CMD_RUN = 0x01, // Run bit
203 
204  EHCI_STS_HALTED = 0x1000, // Host Controller Halted bit
205  EHCI_STS_ASYNCADVANCE = 0x20, // Async Advance
206  EHCI_STS_PORTCH = 0x4, // Port Change Detect bit
207  EHCI_STS_ERR = 0x2, // Error bit
208  EHCI_STS_INT = 0x1, // On Completition Interrupt bit
209 
210  EHCI_PORTSC_PPOW = 0x1000, // Port Power bit
211  EHCI_PORTSC_PRES = 0x100, // Port Reset bit
212  EHCI_PORTSC_ENCH = 0x8, // Port Enable/Disable Change bit
213  EHCI_PORTSC_EN = 0x4, // Port Enabled bit
214  EHCI_PORTSC_CSCH = 0x2, // Port Connect Status Change bit
215  EHCI_PORTSC_CONN = 0x1, // Port Connected bit
216  };
217 
218  IoBase *m_pBase;
219 
220  uint8_t m_nOpRegsOffset;
221  uint8_t m_nPorts;
222 
223  Mutex m_Mutex;
224 
225  Spinlock m_QueueListChangeLock;
226 
227  QH *m_pQHList;
228  uintptr_t m_pQHListPhys;
229  ExtensibleBitmap m_QHBitmap;
230 
231  uint32_t *m_pFrameList;
232  uintptr_t m_pFrameListPhys;
233  ExtensibleBitmap m_FrameBitmap;
234 
235  qTD *m_pqTDList;
236  uintptr_t m_pqTDListPhys;
237  ExtensibleBitmap m_qTDBitmap;
238 
239  // Pointer to the current queue tail, which allows insertion of new queue
240  // heads to the asynchronous schedule.
241  QH *m_pCurrentQueueTail;
242 
243  // Pointer to the current queue head. Used to fill pNext automatically
244  // for new queue heads inserted to the asynchronous schedule.
245  QH *m_pCurrentQueueHead;
246 
247  MemoryRegion m_EhciMR;
248 
249  Ehci(const Ehci &);
250  void operator=(const Ehci &);
251 };
252 
253 #endif
virtual void doAsync(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t)=0, uintptr_t pParam=0)
Definition: Ehci.cc:880
Definition: Ehci.h:41
virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer, size_t nBytes)
Adds a new transfer to an existent transaction.
Definition: Ehci.cc:719
Definition: Mutex.h:58
Definition: String.h:49
Abstrace base class for hardware I/O capabilities.
Definition: IoBase.h:31
Definition: Device.h:43
virtual bool portReset(uint8_t nPort, bool bErrorResponse=false)
Gets a UsbDevice from a given vendor:product pair.
Definition: Ehci.cc:996
virtual void addInterruptInHandler(UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes, void(*pCallback)(uintptr_t, ssize_t), uintptr_t pParam=0)
Adds a new handler for an interrupt IN transaction.
Definition: Ehci.cc:958
Special memory entity in the kernel's virtual address space.
Definition: MemoryRegion.h:35
Definition: Ehci.h:105
Definition: Ehci.h:55
Definition: UsbHub.h:30
virtual uintptr_t createTransaction(UsbEndpoint endpointInfo)
Creates a new transaction with the given endpoint data.
Definition: Ehci.cc:815
bool initialiseController()
Definition: Ehci.cc:86
virtual void getName(String &str)
Definition: Ehci.h:148
Abstract base class for interrupt-handlers.
virtual bool irq(irq_id_t number, InterruptState &state)
IRQ handler.
Definition: Ehci.cc:478
virtual uint64_t executeRequest(uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0)
Definition: Ehci.cc:1061