1 /* 2 * Copyright 2006, Haiku Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Michael Lotz <mmlr@mlotz.ch> 7 */ 8 #ifndef EHCI_H 9 #define EHCI_H 10 11 #include "usb_private.h" 12 #include "ehci_hardware.h" 13 14 15 struct pci_info; 16 struct pci_module_info; 17 class EHCIRootHub; 18 19 20 typedef struct transfer_data { 21 Transfer * transfer; 22 ehci_qh * queue_head; 23 ehci_qtd * data_descriptor; 24 bool incoming; 25 bool canceled; 26 transfer_data * link; 27 } transfer_data; 28 29 30 class EHCI : public BusManager { 31 public: 32 EHCI(pci_info *info, Stack *stack); 33 ~EHCI(); 34 35 status_t Start(); 36 virtual status_t SubmitTransfer(Transfer *transfer); 37 virtual status_t CancelQueuedTransfers(Pipe *pipe, bool force); 38 39 virtual status_t NotifyPipeChange(Pipe *pipe, 40 usb_change change); 41 42 static status_t AddTo(Stack *stack); 43 44 // Port operations for root hub 45 uint8 PortCount() { return fPortCount; }; 46 status_t GetPortStatus(uint8 index, usb_port_status *status); 47 status_t SetPortFeature(uint8 index, uint16 feature); 48 status_t ClearPortFeature(uint8 index, uint16 feature); 49 50 status_t ResetPort(uint8 index); 51 status_t SuspendPort(uint8 index); 52 53 virtual const char * TypeName() const { return "ehci"; }; 54 55 private: 56 // Controller resets 57 status_t ControllerReset(); 58 status_t LightReset(); 59 60 // Interrupt functions 61 static int32 InterruptHandler(void *data); 62 int32 Interrupt(); 63 64 // Transfer management 65 status_t AddPendingTransfer(Transfer *transfer, 66 ehci_qh *queueHead, 67 ehci_qtd *dataDescriptor, 68 bool directionIn); 69 status_t CancelAllPendingTransfers(); 70 71 static int32 FinishThread(void *data); 72 void FinishTransfers(); 73 static int32 CleanupThread(void *data); 74 void Cleanup(); 75 76 // Queue Head functions 77 ehci_qh * CreateQueueHead(); 78 status_t InitQueueHead(ehci_qh *queueHead, 79 Pipe *pipe); 80 void FreeQueueHead(ehci_qh *queueHead); 81 82 status_t LinkQueueHead(ehci_qh *queueHead); 83 status_t LinkInterruptQueueHead(ehci_qh *queueHead, 84 Pipe *pipe); 85 status_t UnlinkQueueHead(ehci_qh *queueHead, 86 ehci_qh **freeList); 87 88 // Queue functions 89 status_t FillQueueWithRequest(Transfer *transfer, 90 ehci_qh *queueHead, 91 ehci_qtd **dataDescriptor, 92 bool *directionIn); 93 status_t FillQueueWithData(Transfer *transfer, 94 ehci_qh *queueHead, 95 ehci_qtd **dataDescriptor, 96 bool *directionIn); 97 98 // Descriptor functions 99 ehci_qtd * CreateDescriptor( 100 size_t bufferSizeToAllocate, 101 uint8 pid); 102 status_t CreateDescriptorChain(Pipe *pipe, 103 ehci_qtd **firstDescriptor, 104 ehci_qtd **lastDescriptor, 105 ehci_qtd *strayDescriptor, 106 size_t bufferSizeToAllocate, 107 uint8 pid); 108 109 void FreeDescriptor(ehci_qtd *descriptor); 110 void FreeDescriptorChain(ehci_qtd *topDescriptor); 111 112 void LinkDescriptors(ehci_qtd *first, 113 ehci_qtd *last, ehci_qtd *alt); 114 115 size_t WriteDescriptorChain( 116 ehci_qtd *topDescriptor, 117 iovec *vector, size_t vectorCount); 118 size_t ReadDescriptorChain(ehci_qtd *topDescriptor, 119 iovec *vector, size_t vectorCount, 120 bool *nextDataToggle); 121 size_t ReadActualLength(ehci_qtd *topDescriptor, 122 bool *nextDataToggle); 123 124 // Operational register functions 125 inline void WriteOpReg(uint32 reg, uint32 value); 126 inline uint32 ReadOpReg(uint32 reg); 127 128 // Capability register functions 129 inline uint8 ReadCapReg8(uint32 reg); 130 inline uint16 ReadCapReg16(uint32 reg); 131 inline uint32 ReadCapReg32(uint32 reg); 132 133 static pci_module_info * sPCIModule; 134 135 uint8 * fCapabilityRegisters; 136 uint8 * fOperationalRegisters; 137 area_id fRegisterArea; 138 pci_info * fPCIInfo; 139 Stack * fStack; 140 uint32 fEnabledInterrupts; 141 142 // Periodic transfer framelist and interrupt entries 143 area_id fPeriodicFrameListArea; 144 addr_t * fPeriodicFrameList; 145 interrupt_entry * fInterruptEntries; 146 147 // Async transfer queue management 148 ehci_qh * fAsyncQueueHead; 149 sem_id fAsyncAdvanceSem; 150 151 // Maintain a linked list of transfers 152 transfer_data * fFirstTransfer; 153 transfer_data * fLastTransfer; 154 sem_id fFinishTransfersSem; 155 thread_id fFinishThread; 156 sem_id fCleanupSem; 157 thread_id fCleanupThread; 158 bool fStopThreads; 159 ehci_qh * fFreeListHead; 160 Pipe * fProcessingPipe; 161 162 // Root Hub 163 EHCIRootHub * fRootHub; 164 uint8 fRootHubAddress; 165 166 // Port management 167 uint8 fPortCount; 168 uint16 fPortResetChange; 169 uint16 fPortSuspendChange; 170 }; 171 172 173 class EHCIRootHub : public Hub { 174 public: 175 EHCIRootHub(Object *rootObject, 176 int8 deviceAddress); 177 178 static status_t ProcessTransfer(EHCI *ehci, 179 Transfer *transfer); 180 }; 181 182 183 #endif // !EHCI_H 184