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