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 11 #ifndef OHCI_H 12 #define OHCI_H 13 14 #include "usb_p.h" 15 #include "ohci_hardware.h" 16 #include <lock.h> 17 18 struct pci_info; 19 struct pci_module_info; 20 class OHCIRootHub; 21 22 typedef struct transfer_data_s { 23 Transfer *transfer; 24 ohci_endpoint_descriptor *endpoint; 25 ohci_general_td *first_descriptor; 26 ohci_general_td *data_descriptor; 27 ohci_general_td *last_descriptor; 28 bool incoming; 29 bool canceled; 30 transfer_data_s *link; 31 } transfer_data; 32 33 34 class OHCI : public BusManager { 35 public: 36 OHCI(pci_info *info, Stack *stack); 37 ~OHCI(); 38 39 status_t Start(); 40 virtual status_t SubmitTransfer(Transfer *transfer); 41 virtual status_t CancelQueuedTransfers(Pipe *pipe, 42 bool force); 43 44 virtual status_t NotifyPipeChange(Pipe *pipe, 45 usb_change change); 46 47 static status_t AddTo(Stack *stack); 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 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 167 // Root Hub 168 OHCIRootHub *fRootHub; 169 uint8 fRootHubAddress; 170 171 // Port management 172 uint8 fPortCount; 173 }; 174 175 176 class OHCIRootHub : public Hub { 177 public: 178 OHCIRootHub(Object *rootObject, 179 int8 deviceAddress); 180 181 static status_t ProcessTransfer(OHCI *ohci, 182 Transfer *transfer); 183 }; 184 185 186 #endif // OHCI_H 187