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 generic_io_vec *vector, size_t vectorCount, 139 bool physical); 140 size_t _ReadDescriptorChain( 141 ohci_general_td *topDescriptor, 142 generic_io_vec *vector, size_t vectorCount, 143 bool physical); 144 145 size_t _WriteIsochronousDescriptorChain( 146 ohci_isochronous_td *topDescriptor, 147 generic_io_vec *vector, size_t vectorCount, 148 bool physical); 149 void _ReadIsochronousDescriptorChain( 150 ohci_isochronous_td *topDescriptor, 151 generic_io_vec *vector, size_t vectorCount, 152 bool physical); 153 154 size_t _ReadActualLength( 155 ohci_general_td *topDescriptor); 156 157 void _LinkDescriptors(ohci_general_td *first, 158 ohci_general_td *second); 159 void _LinkIsochronousDescriptors( 160 ohci_isochronous_td *first, 161 ohci_isochronous_td *second, 162 ohci_isochronous_td *nextDone); 163 164 bool _AllocateIsochronousBandwidth(uint16 frame, 165 uint16 size); 166 void _ReleaseIsochronousBandwidth( 167 uint16 startFrame, uint16 count); 168 169 status_t _GetStatusOfConditionCode( 170 uint8 conditionCode); 171 // Private locking 172 bool _LockEndpoints(); 173 void _UnlockEndpoints(); 174 175 // Register functions 176 inline void _WriteReg(uint32 reg, uint32 value); 177 inline uint32 _ReadReg(uint32 reg); 178 179 // Debug functions 180 void _PrintEndpoint( 181 ohci_endpoint_descriptor *endpoint); 182 void _PrintDescriptorChain( 183 ohci_general_td *topDescriptor); 184 void _PrintDescriptorChain( 185 ohci_isochronous_td *topDescriptor); 186 187 pci_info * fPCIInfo; 188 pci_device_module_info* fPci; 189 pci_device* fDevice; 190 Stack * fStack; 191 192 uint8 * fOperationalRegisters; 193 area_id fRegisterArea; 194 195 // Host Controller Communication Area related stuff 196 area_id fHccaArea; 197 ohci_hcca * fHcca; 198 ohci_endpoint_descriptor ** fInterruptEndpoints; 199 200 // Endpoint management 201 mutex fEndpointLock; 202 ohci_endpoint_descriptor * fDummyControl; 203 ohci_endpoint_descriptor * fDummyBulk; 204 ohci_endpoint_descriptor * fDummyIsochronous; 205 206 // Maintain a linked list of transfer 207 transfer_data * fFirstTransfer; 208 transfer_data * fLastTransfer; 209 sem_id fFinishTransfersSem; 210 thread_id fFinishThread; 211 bool fStopFinishThread; 212 Pipe * fProcessingPipe; 213 // frame bandwidth watchdogs array 214 uint16 * fFrameBandwidth; 215 216 // Root Hub 217 OHCIRootHub * fRootHub; 218 uint8 fRootHubAddress; 219 220 // Port management 221 uint8 fPortCount; 222 223 uint8 fIRQ; 224 bool fUseMSI; 225 }; 226 227 228 class OHCIRootHub : public Hub { 229 public: 230 OHCIRootHub(Object *rootObject, 231 int8 deviceAddress); 232 233 static status_t ProcessTransfer(OHCI *ohci, 234 Transfer *transfer); 235 }; 236 237 238 #endif // OHCI_H 239