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_device_module_info; 20 struct pci_device; 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 OHCI(pci_info *info, pci_device_module_info* pci, 38 pci_device* device, Stack *stack, device_node* node); 39 ~OHCI(); 40 41 status_t Start(); 42 virtual status_t SubmitTransfer(Transfer *transfer); 43 virtual status_t CancelQueuedTransfers(Pipe *pipe, 44 bool force); 45 46 virtual status_t NotifyPipeChange(Pipe *pipe, 47 usb_change change); 48 49 // Port operations 50 uint8 PortCount() { return fPortCount; }; 51 status_t GetPortStatus(uint8 index, 52 usb_port_status *status); 53 status_t SetPortFeature(uint8 index, uint16 feature); 54 status_t ClearPortFeature(uint8 index, uint16 feature); 55 56 status_t ResetPort(uint8 index); 57 58 virtual const char * TypeName() const { return "ohci"; }; 59 60 private: 61 // Interrupt functions 62 static int32 _InterruptHandler(void *data); 63 int32 _Interrupt(); 64 65 // Transfer functions 66 status_t _AddPendingTransfer(Transfer *transfer, 67 ohci_endpoint_descriptor *endpoint, 68 ohci_general_td *firstDescriptor, 69 ohci_general_td *dataDescriptor, 70 ohci_general_td *lastDescriptor, 71 bool directionIn); 72 status_t _AddPendingIsochronousTransfer( 73 Transfer *transfer, 74 ohci_endpoint_descriptor *endpoint, 75 ohci_isochronous_td *firstDescriptor, 76 ohci_isochronous_td *lastDescriptor, 77 bool directionIn); 78 79 status_t _UnlinkTransfer(transfer_data *transfer); 80 81 static int32 _FinishThread(void *data); 82 void _FinishTransfers(); 83 bool _FinishIsochronousTransfer( 84 transfer_data *transfer, 85 transfer_data **_lastTransfer); 86 87 status_t _SubmitRequest(Transfer *transfer); 88 status_t _SubmitTransfer(Transfer *transfer); 89 status_t _SubmitIsochronousTransfer( 90 Transfer *transfer); 91 92 void _SwitchEndpointTail( 93 ohci_endpoint_descriptor *endpoint, 94 ohci_general_td *first, 95 ohci_general_td *last); 96 void _SwitchIsochronousEndpointTail( 97 ohci_endpoint_descriptor *endpoint, 98 ohci_isochronous_td *first, 99 ohci_isochronous_td *last); 100 101 void _RemoveTransferFromEndpoint( 102 transfer_data *transfer); 103 104 // Endpoint related methods 105 ohci_endpoint_descriptor * _AllocateEndpoint(); 106 void _FreeEndpoint( 107 ohci_endpoint_descriptor *endpoint); 108 status_t _InsertEndpointForPipe(Pipe *pipe); 109 status_t _RemoveEndpointForPipe(Pipe *pipe); 110 ohci_endpoint_descriptor * _FindInterruptEndpoint(uint8 interval); 111 112 // Transfer descriptor related methods 113 ohci_general_td * _CreateGeneralDescriptor( 114 size_t bufferSize); 115 void _FreeGeneralDescriptor( 116 ohci_general_td *descriptor); 117 status_t _CreateDescriptorChain( 118 ohci_general_td **firstDescriptor, 119 ohci_general_td **lastDescriptor, 120 uint32 direction, 121 size_t bufferSize); 122 void _FreeDescriptorChain( 123 ohci_general_td *topDescriptor); 124 125 ohci_isochronous_td * _CreateIsochronousDescriptor( 126 size_t bufferSize); 127 void _FreeIsochronousDescriptor( 128 ohci_isochronous_td *descriptor); 129 status_t _CreateIsochronousDescriptorChain( 130 ohci_isochronous_td **firstDescriptor, 131 ohci_isochronous_td **lastDescriptor, 132 Transfer *transfer); 133 void _FreeIsochronousDescriptorChain( 134 ohci_isochronous_td *topDescriptor); 135 136 size_t _WriteDescriptorChain( 137 ohci_general_td *topDescriptor, 138 iovec *vector, size_t vectorCount); 139 size_t _ReadDescriptorChain( 140 ohci_general_td *topDescriptor, 141 iovec *vector, size_t vectorCount); 142 143 size_t _WriteIsochronousDescriptorChain( 144 ohci_isochronous_td *topDescriptor, 145 iovec *vector, size_t vectorCount); 146 void _ReadIsochronousDescriptorChain( 147 ohci_isochronous_td *topDescriptor, 148 iovec *vector, size_t vectorCount); 149 150 size_t _ReadActualLength( 151 ohci_general_td *topDescriptor); 152 153 void _LinkDescriptors(ohci_general_td *first, 154 ohci_general_td *second); 155 void _LinkIsochronousDescriptors( 156 ohci_isochronous_td *first, 157 ohci_isochronous_td *second, 158 ohci_isochronous_td *nextDone); 159 160 bool _AllocateIsochronousBandwidth(uint16 frame, 161 uint16 size); 162 void _ReleaseIsochronousBandwidth( 163 uint16 startFrame, uint16 count); 164 165 status_t _GetStatusOfConditionCode( 166 uint8 conditionCode); 167 // Private locking 168 bool _LockEndpoints(); 169 void _UnlockEndpoints(); 170 171 // Register functions 172 inline void _WriteReg(uint32 reg, uint32 value); 173 inline uint32 _ReadReg(uint32 reg); 174 175 // Debug functions 176 void _PrintEndpoint( 177 ohci_endpoint_descriptor *endpoint); 178 void _PrintDescriptorChain( 179 ohci_general_td *topDescriptor); 180 void _PrintDescriptorChain( 181 ohci_isochronous_td *topDescriptor); 182 183 pci_info * fPCIInfo; 184 pci_device_module_info* fPci; 185 pci_device* fDevice; 186 Stack * fStack; 187 188 uint8 * fOperationalRegisters; 189 area_id fRegisterArea; 190 191 // Host Controller Communication Area related stuff 192 area_id fHccaArea; 193 ohci_hcca * fHcca; 194 ohci_endpoint_descriptor ** fInterruptEndpoints; 195 196 // Endpoint management 197 mutex fEndpointLock; 198 ohci_endpoint_descriptor * fDummyControl; 199 ohci_endpoint_descriptor * fDummyBulk; 200 ohci_endpoint_descriptor * fDummyIsochronous; 201 202 // Maintain a linked list of transfer 203 transfer_data * fFirstTransfer; 204 transfer_data * fLastTransfer; 205 sem_id fFinishTransfersSem; 206 thread_id fFinishThread; 207 bool fStopFinishThread; 208 Pipe * fProcessingPipe; 209 // frame bandwidth watchdogs array 210 uint16 * fFrameBandwidth; 211 212 // Root Hub 213 OHCIRootHub * fRootHub; 214 uint8 fRootHubAddress; 215 216 // Port management 217 uint8 fPortCount; 218 219 uint8 fIRQ; 220 bool fUseMSI; 221 }; 222 223 224 class OHCIRootHub : public Hub { 225 public: 226 OHCIRootHub(Object *rootObject, 227 int8 deviceAddress); 228 229 static status_t ProcessTransfer(OHCI *ohci, 230 Transfer *transfer); 231 }; 232 233 234 #endif // OHCI_H 235