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 private: 55 // Controller resets 56 status_t ControllerReset(); 57 status_t LightReset(); 58 59 // Interrupt functions 60 static int32 InterruptHandler(void *data); 61 int32 Interrupt(); 62 63 // Transfer management 64 status_t AddPendingTransfer(Transfer *transfer, 65 ehci_qh *queueHead, 66 ehci_qtd *dataDescriptor, 67 bool directionIn); 68 status_t CancelAllPendingTransfers(); 69 70 static int32 FinishThread(void *data); 71 void FinishTransfers(); 72 static int32 CleanupThread(void *data); 73 void Cleanup(); 74 75 // Queue Head functions 76 ehci_qh *CreateQueueHead(); 77 status_t InitQueueHead(ehci_qh *queueHead, 78 Pipe *pipe); 79 void FreeQueueHead(ehci_qh *queueHead); 80 81 status_t LinkQueueHead(ehci_qh *queueHead); 82 status_t LinkInterruptQueueHead(ehci_qh *queueHead, 83 Pipe *pipe); 84 status_t UnlinkQueueHead(ehci_qh *queueHead, 85 ehci_qh **freeList); 86 87 // Queue functions 88 status_t FillQueueWithRequest(Transfer *transfer, 89 ehci_qh *queueHead, 90 ehci_qtd **dataDescriptor, 91 bool *directionIn); 92 status_t FillQueueWithData(Transfer *transfer, 93 ehci_qh *queueHead, 94 ehci_qtd **dataDescriptor, 95 bool *directionIn); 96 97 // Descriptor functions 98 ehci_qtd *CreateDescriptor(size_t bufferSizeToAllocate, 99 uint8 pid); 100 status_t CreateDescriptorChain(Pipe *pipe, 101 ehci_qtd **firstDescriptor, 102 ehci_qtd **lastDescriptor, 103 ehci_qtd *strayDescriptor, 104 size_t bufferSizeToAllocate, 105 uint8 pid); 106 107 void FreeDescriptor(ehci_qtd *descriptor); 108 void FreeDescriptorChain(ehci_qtd *topDescriptor); 109 110 void LinkDescriptors(ehci_qtd *first, 111 ehci_qtd *last, ehci_qtd *alt); 112 113 size_t WriteDescriptorChain(ehci_qtd *topDescriptor, 114 iovec *vector, size_t vectorCount); 115 size_t ReadDescriptorChain(ehci_qtd *topDescriptor, 116 iovec *vector, size_t vectorCount, 117 bool *nextDataToggle); 118 size_t ReadActualLength(ehci_qtd *topDescriptor, 119 bool *nextDataToggle); 120 121 // Operational register functions 122 inline void WriteOpReg(uint32 reg, uint32 value); 123 inline uint32 ReadOpReg(uint32 reg); 124 125 // Capability register functions 126 inline uint8 ReadCapReg8(uint32 reg); 127 inline uint16 ReadCapReg16(uint32 reg); 128 inline uint32 ReadCapReg32(uint32 reg); 129 130 static pci_module_info *sPCIModule; 131 132 uint8 *fCapabilityRegisters; 133 uint8 *fOperationalRegisters; 134 area_id fRegisterArea; 135 pci_info *fPCIInfo; 136 Stack *fStack; 137 138 // Periodic transfer framelist and interrupt entries 139 area_id fPeriodicFrameListArea; 140 addr_t *fPeriodicFrameList; 141 interrupt_entry *fInterruptEntries; 142 143 // Async transfer queue management 144 ehci_qh *fAsyncQueueHead; 145 sem_id fAsyncAdvanceSem; 146 147 // Maintain a linked list of transfers 148 transfer_data *fFirstTransfer; 149 transfer_data *fLastTransfer; 150 sem_id fFinishTransfersSem; 151 thread_id fFinishThread; 152 sem_id fCleanupSem; 153 thread_id fCleanupThread; 154 bool fStopThreads; 155 ehci_qh *fFreeListHead; 156 157 // Root Hub 158 EHCIRootHub *fRootHub; 159 uint8 fRootHubAddress; 160 161 // Port management 162 uint8 fPortCount; 163 uint16 fPortResetChange; 164 uint16 fPortSuspendChange; 165 }; 166 167 168 class EHCIRootHub : public Hub { 169 public: 170 EHCIRootHub(Object *rootObject, 171 int8 deviceAddress); 172 173 static status_t ProcessTransfer(EHCI *ehci, 174 Transfer *transfer); 175 }; 176 177 178 #endif // !EHCI_H 179