1 /* 2 * Copyright 2005-2013, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jan-Rixt Van Hoye 7 * Salvatore Benedetto <salvatore.benedetto@gmail.com> 8 * Michael Lotz <mmlr@mlotz.ch> 9 * Siarzhuk Zharski <imker@gmx.li> 10 */ 11 #ifndef OHCI_H 12 #define OHCI_H 13 14 #include "usb_private.h" 15 #include "ohci_hardware.h" 16 #include <lock.h> 17 18 struct pci_info; 19 struct pci_module_info; 20 struct pci_x86_module_info; 21 class OHCIRootHub; 22 23 typedef struct transfer_data { 24 Transfer * transfer; 25 ohci_endpoint_descriptor * endpoint; 26 ohci_general_td * first_descriptor; 27 ohci_general_td * data_descriptor; 28 ohci_general_td * last_descriptor; 29 bool incoming; 30 bool canceled; 31 transfer_data * link; 32 } transfer_data; 33 34 35 class OHCI : public BusManager { 36 public: 37 static status_t AddTo(Stack *stack); 38 39 OHCI(pci_info *info, Stack *stack); 40 ~OHCI(); 41 42 status_t Start(); 43 virtual status_t SubmitTransfer(Transfer *transfer); 44 virtual status_t CancelQueuedTransfers(Pipe *pipe, 45 bool force); 46 47 virtual status_t NotifyPipeChange(Pipe *pipe, 48 usb_change change); 49 50 // Port operations 51 uint8 PortCount() { return fPortCount; }; 52 status_t GetPortStatus(uint8 index, 53 usb_port_status *status); 54 status_t SetPortFeature(uint8 index, uint16 feature); 55 status_t ClearPortFeature(uint8 index, uint16 feature); 56 57 status_t ResetPort(uint8 index); 58 59 virtual const char * TypeName() const { return "ohci"; }; 60 61 private: 62 // Interrupt functions 63 static int32 _InterruptHandler(void *data); 64 int32 _Interrupt(); 65 66 // Transfer functions 67 status_t _AddPendingTransfer(Transfer *transfer, 68 ohci_endpoint_descriptor *endpoint, 69 ohci_general_td *firstDescriptor, 70 ohci_general_td *dataDescriptor, 71 ohci_general_td *lastDescriptor, 72 bool directionIn); 73 status_t _AddPendingIsochronousTransfer( 74 Transfer *transfer, 75 ohci_endpoint_descriptor *endpoint, 76 ohci_isochronous_td *firstDescriptor, 77 ohci_isochronous_td *lastDescriptor, 78 bool directionIn); 79 80 status_t _UnlinkTransfer(transfer_data *transfer); 81 82 static int32 _FinishThread(void *data); 83 void _FinishTransfers(); 84 bool _FinishIsochronousTransfer( 85 transfer_data *transfer, 86 transfer_data **_lastTransfer); 87 88 status_t _SubmitRequest(Transfer *transfer); 89 status_t _SubmitTransfer(Transfer *transfer); 90 status_t _SubmitIsochronousTransfer( 91 Transfer *transfer); 92 93 void _SwitchEndpointTail( 94 ohci_endpoint_descriptor *endpoint, 95 ohci_general_td *first, 96 ohci_general_td *last); 97 void _SwitchIsochronousEndpointTail( 98 ohci_endpoint_descriptor *endpoint, 99 ohci_isochronous_td *first, 100 ohci_isochronous_td *last); 101 102 void _RemoveTransferFromEndpoint( 103 transfer_data *transfer); 104 105 // Endpoint related methods 106 ohci_endpoint_descriptor * _AllocateEndpoint(); 107 void _FreeEndpoint( 108 ohci_endpoint_descriptor *endpoint); 109 status_t _InsertEndpointForPipe(Pipe *pipe); 110 status_t _RemoveEndpointForPipe(Pipe *pipe); 111 ohci_endpoint_descriptor * _FindInterruptEndpoint(uint8 interval); 112 113 // Transfer descriptor related methods 114 ohci_general_td * _CreateGeneralDescriptor( 115 size_t bufferSize); 116 void _FreeGeneralDescriptor( 117 ohci_general_td *descriptor); 118 status_t _CreateDescriptorChain( 119 ohci_general_td **firstDescriptor, 120 ohci_general_td **lastDescriptor, 121 uint32 direction, 122 size_t bufferSize); 123 void _FreeDescriptorChain( 124 ohci_general_td *topDescriptor); 125 126 ohci_isochronous_td * _CreateIsochronousDescriptor( 127 size_t bufferSize); 128 void _FreeIsochronousDescriptor( 129 ohci_isochronous_td *descriptor); 130 status_t _CreateIsochronousDescriptorChain( 131 ohci_isochronous_td **firstDescriptor, 132 ohci_isochronous_td **lastDescriptor, 133 Transfer *transfer); 134 void _FreeIsochronousDescriptorChain( 135 ohci_isochronous_td *topDescriptor); 136 137 size_t _WriteDescriptorChain( 138 ohci_general_td *topDescriptor, 139 iovec *vector, size_t vectorCount); 140 size_t _ReadDescriptorChain( 141 ohci_general_td *topDescriptor, 142 iovec *vector, size_t vectorCount); 143 144 size_t _WriteIsochronousDescriptorChain( 145 ohci_isochronous_td *topDescriptor, 146 iovec *vector, size_t vectorCount); 147 void _ReadIsochronousDescriptorChain( 148 ohci_isochronous_td *topDescriptor, 149 iovec *vector, size_t vectorCount); 150 151 size_t _ReadActualLength( 152 ohci_general_td *topDescriptor); 153 154 void _LinkDescriptors(ohci_general_td *first, 155 ohci_general_td *second); 156 void _LinkIsochronousDescriptors( 157 ohci_isochronous_td *first, 158 ohci_isochronous_td *second, 159 ohci_isochronous_td *nextDone); 160 161 bool _AllocateIsochronousBandwidth(uint16 frame, 162 uint16 size); 163 void _ReleaseIsochronousBandwidth( 164 uint16 startFrame, uint16 count); 165 166 status_t _GetStatusOfConditionCode( 167 uint8 conditionCode); 168 // Private locking 169 bool _LockEndpoints(); 170 void _UnlockEndpoints(); 171 172 // Register functions 173 inline void _WriteReg(uint32 reg, uint32 value); 174 inline uint32 _ReadReg(uint32 reg); 175 176 // Debug functions 177 void _PrintEndpoint( 178 ohci_endpoint_descriptor *endpoint); 179 void _PrintDescriptorChain( 180 ohci_general_td *topDescriptor); 181 void _PrintDescriptorChain( 182 ohci_isochronous_td *topDescriptor); 183 184 static pci_module_info * sPCIModule; 185 static pci_x86_module_info * sPCIx86Module; 186 187 pci_info * fPCIInfo; 188 Stack * fStack; 189 190 uint8 * fOperationalRegisters; 191 area_id fRegisterArea; 192 193 // Host Controller Communication Area related stuff 194 area_id fHccaArea; 195 ohci_hcca * fHcca; 196 ohci_endpoint_descriptor ** fInterruptEndpoints; 197 198 // Endpoint management 199 mutex fEndpointLock; 200 ohci_endpoint_descriptor * fDummyControl; 201 ohci_endpoint_descriptor * fDummyBulk; 202 ohci_endpoint_descriptor * fDummyIsochronous; 203 204 // Maintain a linked list of transfer 205 transfer_data * fFirstTransfer; 206 transfer_data * fLastTransfer; 207 sem_id fFinishTransfersSem; 208 thread_id fFinishThread; 209 bool fStopFinishThread; 210 Pipe * fProcessingPipe; 211 // frame bandwidth watchdogs array 212 uint16 * fFrameBandwidth; 213 214 // Root Hub 215 OHCIRootHub * fRootHub; 216 uint8 fRootHubAddress; 217 218 // Port management 219 uint8 fPortCount; 220 221 uint8 fIRQ; 222 bool fUseMSI; 223 }; 224 225 226 class OHCIRootHub : public Hub { 227 public: 228 OHCIRootHub(Object *rootObject, 229 int8 deviceAddress); 230 231 static status_t ProcessTransfer(OHCI *ohci, 232 Transfer *transfer); 233 }; 234 235 236 #endif // OHCI_H 237