The Pedigree Project  0.1
Uhci.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 #ifdef X86_COMMON
21 
22 #ifndef UHCI_H
23 #define UHCI_H
24 
25 #include "modules/system/usb/Usb.h"
26 #include "modules/system/usb/UsbHub.h"
27 #include "pedigree/kernel/Spinlock.h"
28 #include "pedigree/kernel/compiler.h"
29 #include "pedigree/kernel/machine/IrqHandler.h"
30 #include "pedigree/kernel/machine/TimerHandler.h"
31 #include "pedigree/kernel/machine/types.h"
32 #include "pedigree/kernel/process/Mutex.h"
33 #include "pedigree/kernel/process/Semaphore.h"
34 #include "pedigree/kernel/processor/MemoryRegion.h"
35 #include "pedigree/kernel/processor/state_forward.h"
36 #include "pedigree/kernel/processor/types.h"
37 #include "pedigree/kernel/utilities/ExtensibleBitmap.h"
38 #include "pedigree/kernel/utilities/List.h"
39 #include "pedigree/kernel/utilities/RequestQueue.h"
40 #include "pedigree/kernel/utilities/String.h"
41 #include "pedigree/kernel/utilities/new"
42 
43 class Device;
44 class IoBase;
45 
47 class Uhci : public UsbHub,
48  public IrqHandler,
49  public RequestQueue,
50  public TimerHandler
51 {
52  public:
53  Uhci(Device *pDev);
54  virtual ~Uhci();
55 
56  struct TD
57  {
58  uint32_t bNextInvalid : 1;
59  uint32_t bNextQH : 1;
60  uint32_t bNextDepth : 1;
61  uint32_t res0 : 1;
62  uint32_t pNext : 28;
63  uint32_t nActLen : 11;
64  uint32_t res1 : 5;
65  uint32_t nStatus : 8;
66  uint32_t bIoc : 1;
67  uint32_t bIsochronus : 1;
68  uint32_t bLoSpeed : 1;
69  uint32_t nErr : 2;
70  uint32_t bSpd : 1;
71  uint32_t res2 : 2;
72  uint32_t nPid : 8;
73  uint32_t nAddress : 7;
74  uint32_t nEndpoint : 4;
75  uint32_t bDataToggle : 1;
76  uint32_t res3 : 1;
77  uint32_t nMaxLen : 11;
78  uint32_t pBuff;
79 
80  // Custom TD fields
81  uint16_t nBufferSize;
82  bool bShortTransferTD;
83 
84  size_t id;
85 
86  // Possible values for status
87  enum StatusCodes
88  {
89  Timeout = 0x4,
90  Nak = 0x8,
91  Babble = 0x10,
92  Stall = 0x40,
93  };
94 
95  inline UsbError getError()
96  {
97  if (nStatus & Stall)
98  return ::Stall;
99  else if (nStatus & Nak)
100  return NakNyet;
101  else if (nStatus & Babble)
102  return ::Babble;
103  else if (nStatus & Timeout)
104  return ::Timeout;
105  else
106  return TransactionError;
107  }
108  } PACKED ALIGN(16);
109 
110  struct QH
111  {
112  uint32_t bNextInvalid : 1;
113  uint32_t bNextQH : 1;
114  uint32_t res0 : 2;
115  uint32_t pNext : 28;
116  uint32_t bElemInvalid : 1;
117  uint32_t bElemQH : 1;
118  uint32_t res1 : 2;
119  uint32_t pElem : 28;
120 
121  struct MetaData
122  {
123  void (*pCallback)(uintptr_t, ssize_t);
124  uintptr_t pParam;
125 
126  UsbEndpoint endpointInfo;
127 
128  bool bPeriodic;
129  TD *pFirstTD;
130  TD *pLastTD;
131  size_t nTotalBytes;
132 
133  QH *pPrev;
134  QH *pNext;
135 
136  List<TD *> tdList;
137  List<TD *> completedTdList;
138 
139  bool bIgnore;
140 
142  size_t id;
143  } * pMetaData;
144  } PACKED ALIGN(16);
145 
146  virtual void getName(String &str)
147  {
148  str = "UHCI";
149  }
150 
151  virtual void addTransferToTransaction(
152  uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer,
153  size_t nBytes);
154  virtual uintptr_t createTransaction(UsbEndpoint endpointInfo);
155 
156  virtual void doAsync(
157  uintptr_t pTransaction, void (*pCallback)(uintptr_t, ssize_t) = 0,
158  uintptr_t pParam = 0);
159  virtual void addInterruptInHandler(
160  UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes,
161  void (*pCallback)(uintptr_t, ssize_t), uintptr_t pParam = 0);
162 
164  virtual bool irq(irq_id_t number, InterruptState &state);
165 
166  void doDequeue() NORETURN;
167 
169  void timer(uint64_t delta, InterruptState &state);
170 
171  virtual bool portReset(uint8_t nPort, bool bErrorResponse = false);
172 
173  protected:
174  virtual uint64_t executeRequest(
175  uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0, uint64_t p4 = 0,
176  uint64_t p5 = 0, uint64_t p6 = 0, uint64_t p7 = 0, uint64_t p8 = 0);
177 
178  private:
180  void stop();
181 
183  void start();
184 
185  enum UhciConstants
186  {
187  UHCI_CMD = 0x00, // Command register
188  UHCI_STS = 0x02, // Status register
189  UHCI_INTR = 0x04, // Intrerrupt Enable register
190  UHCI_FRMN = 0x06, // Frame Number register
191  UHCI_FRLP = 0x08, // Frame List Pointer register
192  UHCI_PORTSC = 0x10, // Port Status/Control registers
193 
194  UHCI_CMD_GRES = 0x04, // Global Reset bit
195  UHCI_CMD_HCRES = 0x02, // Host Controller Reset bit
196  UHCI_CMD_RUN = 0x01, // Run bit
197 
198  UHCI_STS_HALT = 0x20, // Controller is halted
199  UHCI_STS_ERR = 0x02, // UHCI Error
200  UHCI_STS_INT = 0x01, // On Completition Interrupt bit
201 
202  UHCI_PORTSC_PRES = 0x200, // Port Reset bit
203  UHCI_PORTSC_LOSPEED = 0x100, // Port has Low Speed Device attached bit
204  UHCI_PORTSC_EDCH = 0x8, // Port Enable/Disable Change bit
205  UHCI_PORTSC_ENABLE = 0x4, // Port Enable bit
206  UHCI_PORTSC_CSCH = 0x2, // Port Connect Status Change bit
207  UHCI_PORTSC_CONN = 0x1, // Port Connected bit
208  };
209 
210  IoBase *m_pBase;
211 
212  uint8_t m_nPorts;
213 
214  Mutex m_Mutex;
215 
216  Spinlock m_AsyncQueueListChangeLock;
217 
218  uint32_t *m_pFrameList;
219  uintptr_t m_pFrameListPhys;
220 
221  TD *m_pTDList;
222  uintptr_t m_pTDListPhys;
223  ExtensibleBitmap m_TDBitmap;
224 
225  QH *m_pAsyncQH;
226  QH *m_pPeriodicQH;
227 
228  QH *m_pQHList;
229  uintptr_t m_pQHListPhys;
230  ExtensibleBitmap m_QHBitmap;
231 
232  MemoryRegion m_UhciMR;
233 
237 
241 
244 
247 
250 
253 
254  Uhci(const Uhci &);
255  void operator=(const Uhci &);
256 };
257 
258 #endif
259 
260 #endif
Definition: Uhci.h:110
QH * m_pCurrentAsyncQueueHead
Definition: Uhci.h:240
virtual bool portReset(uint8_t nPort, bool bErrorResponse=false)
Gets a UsbDevice from a given vendor:product pair.
Definition: Uhci.cc:724
Definition: Mutex.h:58
Definition: String.h:49
void start()
Starts the UHCI controller.
Definition: Uhci.cc:870
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: Uhci.cc:697
Abstrace base class for hardware I/O capabilities.
Definition: IoBase.h:31
virtual uintptr_t createTransaction(UsbEndpoint endpointInfo)
Creates a new transaction with the given endpoint data.
Definition: Uhci.cc:587
Definition: Device.h:43
void timer(uint64_t delta, InterruptState &state)
Timer callback to handle port status changes.
Definition: Uhci.cc:835
Semaphore m_DequeueCount
Semaphore for the dequeue list.
Definition: Uhci.h:249
virtual bool irq(irq_id_t number, InterruptState &state)
IRQ handler.
Definition: Uhci.cc:261
Special memory entity in the kernel&#39;s virtual address space.
Definition: MemoryRegion.h:35
QH * m_pCurrentAsyncQueueTail
Definition: Uhci.h:236
virtual void getName(String &str)
Definition: Uhci.h:146
Definition: UsbHub.h:30
List< QH * > m_DequeueList
List of QHs ready for dequeue.
Definition: Uhci.h:246
List< QH * > m_AsyncSchedule
List of QHs in the active asynchronous schedule.
Definition: Uhci.h:243
void stop()
Stops the UHCI controller.
Definition: Uhci.cc:863
Definition: Uhci.h:56
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: Uhci.cc:794
Definition: Uhci.h:47
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: Uhci.cc:496
uint64_t m_nPortCheckTicks
The time passed since last port check.
Definition: Uhci.h:252
virtual void doAsync(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t)=0, uintptr_t pParam=0)
Definition: Uhci.cc:620