1 /* 2 * Copyright 2005-2008, 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 */ 10 #ifndef OHCI_H 11 #define OHCI_H 12 13 #include "usb_private.h" 14 #include "ohci_hardware.h" 15 #include <lock.h> 16 17 struct pci_info; 18 struct pci_module_info; 19 class OHCIRootHub; 20 21 typedef struct transfer_data { 22 Transfer * transfer; 23 ohci_endpoint_descriptor * endpoint; 24 ohci_general_td * first_descriptor; 25 ohci_general_td * data_descriptor; 26 ohci_general_td * last_descriptor; 27 bool incoming; 28 bool canceled; 29 transfer_data * link; 30 } transfer_data; 31 32 33 class OHCI : public BusManager { 34 public: 35 OHCI(pci_info *info, Stack *stack); 36 ~OHCI(); 37 38 status_t Start(); 39 virtual status_t SubmitTransfer(Transfer *transfer); 40 virtual status_t CancelQueuedTransfers(Pipe *pipe, 41 bool force); 42 43 virtual status_t NotifyPipeChange(Pipe *pipe, 44 usb_change change); 45 46 static status_t AddTo(Stack *stack); 47 48 // Port operations 49 uint8 PortCount() { return fPortCount; }; 50 status_t GetPortStatus(uint8 index, 51 usb_port_status *status); 52 status_t SetPortFeature(uint8 index, uint16 feature); 53 status_t ClearPortFeature(uint8 index, uint16 feature); 54 55 status_t ResetPort(uint8 index); 56 57 virtual const char * TypeName() const { return "ohci"; }; 58 59 private: 60 // Interrupt functions 61 static int32 _InterruptHandler(void *data); 62 int32 _Interrupt(); 63 64 // Transfer functions 65 status_t _AddPendingTransfer(Transfer *transfer, 66 ohci_endpoint_descriptor *endpoint, 67 ohci_general_td *firstDescriptor, 68 ohci_general_td *dataDescriptor, 69 ohci_general_td *lastDescriptor, 70 bool directionIn); 71 status_t _CancelQueuedIsochronousTransfers( 72 Pipe *pipe, bool force); 73 status_t _UnlinkTransfer(transfer_data *transfer); 74 75 static int32 _FinishThread(void *data); 76 void _FinishTransfers(); 77 78 status_t _SubmitRequest(Transfer *transfer); 79 status_t _SubmitTransfer(Transfer *transfer); 80 status_t _SubmitIsochronousTransfer( 81 Transfer *transfer); 82 83 void _SwitchEndpointTail( 84 ohci_endpoint_descriptor *endpoint, 85 ohci_general_td *first, 86 ohci_general_td *last); 87 void _RemoveTransferFromEndpoint( 88 transfer_data *transfer); 89 90 // Endpoint related methods 91 ohci_endpoint_descriptor * _AllocateEndpoint(); 92 void _FreeEndpoint( 93 ohci_endpoint_descriptor *endpoint); 94 status_t _InsertEndpointForPipe(Pipe *pipe); 95 status_t _RemoveEndpointForPipe(Pipe *pipe); 96 ohci_endpoint_descriptor * _FindInterruptEndpoint(uint8 interval); 97 98 // Transfer descriptor related methods 99 ohci_general_td * _CreateGeneralDescriptor( 100 size_t bufferSize); 101 void _FreeGeneralDescriptor( 102 ohci_general_td *descriptor); 103 104 status_t _CreateDescriptorChain( 105 ohci_general_td **firstDescriptor, 106 ohci_general_td **lastDescriptor, 107 uint32 direction, 108 size_t bufferSize); 109 void _FreeDescriptorChain( 110 ohci_general_td *topDescriptor); 111 112 size_t _WriteDescriptorChain( 113 ohci_general_td *topDescriptor, 114 iovec *vector, size_t vectorCount); 115 size_t _ReadDescriptorChain( 116 ohci_general_td *topDescriptor, 117 iovec *vector, size_t vectorCount); 118 size_t _ReadActualLength( 119 ohci_general_td *topDescriptor); 120 121 void _LinkDescriptors(ohci_general_td *first, 122 ohci_general_td *second); 123 124 ohci_isochronous_td * _CreateIsochronousDescriptor(); 125 void _FreeIsochronousDescriptor( 126 ohci_isochronous_td *descriptor); 127 128 // Private locking 129 bool _LockEndpoints(); 130 void _UnlockEndpoints(); 131 132 // Register functions 133 inline void _WriteReg(uint32 reg, uint32 value); 134 inline uint32 _ReadReg(uint32 reg); 135 136 // Debug functions 137 void _PrintEndpoint( 138 ohci_endpoint_descriptor *endpoint); 139 void _PrintDescriptorChain( 140 ohci_general_td *topDescriptor); 141 142 static pci_module_info * sPCIModule; 143 pci_info * fPCIInfo; 144 Stack * fStack; 145 146 uint8 * fOperationalRegisters; 147 area_id fRegisterArea; 148 149 // Host Controller Communication Area related stuff 150 area_id fHccaArea; 151 ohci_hcca * fHcca; 152 ohci_endpoint_descriptor ** fInterruptEndpoints; 153 154 // Endpoint management 155 mutex fEndpointLock; 156 ohci_endpoint_descriptor * fDummyControl; 157 ohci_endpoint_descriptor * fDummyBulk; 158 ohci_endpoint_descriptor * fDummyIsochronous; 159 160 // Maintain a linked list of transfer 161 transfer_data * fFirstTransfer; 162 transfer_data * fLastTransfer; 163 sem_id fFinishTransfersSem; 164 thread_id fFinishThread; 165 bool fStopFinishThread; 166 Pipe * fProcessingPipe; 167 168 // Root Hub 169 OHCIRootHub * fRootHub; 170 uint8 fRootHubAddress; 171 172 // Port management 173 uint8 fPortCount; 174 }; 175 176 177 class OHCIRootHub : public Hub { 178 public: 179 OHCIRootHub(Object *rootObject, 180 int8 deviceAddress); 181 182 static status_t ProcessTransfer(OHCI *ohci, 183 Transfer *transfer); 184 }; 185 186 187 #endif // OHCI_H 188