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 area_id user_area; 26 bool incoming; 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 status_t SubmitPeriodicTransfer(Transfer *transfer); 39 status_t SubmitAsyncTransfer(Transfer *transfer); 40 41 virtual status_t NotifyPipeChange(Pipe *pipe, 42 usb_change change); 43 44 static status_t AddTo(Stack *stack); 45 46 // Port operations for root hub 47 uint8 PortCount() { return fPortCount; }; 48 status_t GetPortStatus(uint8 index, usb_port_status *status); 49 status_t SetPortFeature(uint8 index, uint16 feature); 50 status_t ClearPortFeature(uint8 index, uint16 feature); 51 52 status_t ResetPort(uint8 index); 53 status_t SuspendPort(uint8 index); 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 CancelPendingTransfer(Transfer *transfer); 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 void FreeQueueHead(ehci_qh *queueHead); 80 81 status_t LinkQueueHead(ehci_qh *queueHead); 82 status_t UnlinkQueueHead(ehci_qh *queueHead, 83 ehci_qh **freeList); 84 85 // Queue functions 86 status_t FillQueueWithRequest(Transfer *transfer, 87 ehci_qh *queueHead, 88 ehci_qtd **dataDescriptor, 89 bool *directionIn); 90 status_t FillQueueWithData(Transfer *transfer, 91 ehci_qh *queueHead, 92 ehci_qtd **dataDescriptor, 93 bool *directionIn); 94 95 // Descriptor functions 96 ehci_qtd *CreateDescriptor(size_t bufferSizeToAllocate, 97 uint8 pid); 98 status_t CreateDescriptorChain(Pipe *pipe, 99 ehci_qtd **firstDescriptor, 100 ehci_qtd **lastDescriptor, 101 ehci_qtd *strayDescriptor, 102 size_t bufferSizeToAllocate, 103 uint8 pid); 104 105 void FreeDescriptor(ehci_qtd *descriptor); 106 void FreeDescriptorChain(ehci_qtd *topDescriptor); 107 108 void LinkDescriptors(ehci_qtd *first, 109 ehci_qtd *last, ehci_qtd *alt); 110 111 size_t WriteDescriptorChain(ehci_qtd *topDescriptor, 112 iovec *vector, size_t vectorCount); 113 size_t ReadDescriptorChain(ehci_qtd *topDescriptor, 114 iovec *vector, size_t vectorCount, 115 bool *nextDataToggle); 116 size_t ReadActualLength(ehci_qtd *topDescriptor, 117 bool *nextDataToggle); 118 119 // Operational register functions 120 inline void WriteOpReg(uint32 reg, uint32 value); 121 inline uint32 ReadOpReg(uint32 reg); 122 123 // Capability register functions 124 inline uint8 ReadCapReg8(uint32 reg); 125 inline uint16 ReadCapReg16(uint32 reg); 126 inline uint32 ReadCapReg32(uint32 reg); 127 128 static pci_module_info *sPCIModule; 129 130 uint8 *fCapabilityRegisters; 131 uint8 *fOperationalRegisters; 132 area_id fRegisterArea; 133 pci_info *fPCIInfo; 134 Stack *fStack; 135 136 // Framelist memory 137 area_id fPeriodicFrameListArea; 138 addr_t *fPeriodicFrameList; 139 140 // Async frame list management 141 ehci_qh *fAsyncQueueHead; 142 sem_id fAsyncAdvanceSem; 143 144 // Maintain a linked list of transfers 145 transfer_data *fFirstTransfer; 146 transfer_data *fLastTransfer; 147 sem_id fFinishTransfersSem; 148 thread_id fFinishThread; 149 sem_id fCleanupSem; 150 thread_id fCleanupThread; 151 bool fStopThreads; 152 ehci_qh *fFreeListHead; 153 154 // Root Hub 155 EHCIRootHub *fRootHub; 156 uint8 fRootHubAddress; 157 158 // Port management 159 uint8 fPortCount; 160 uint16 fPortResetChange; 161 uint16 fPortSuspendChange; 162 }; 163 164 165 class EHCIRootHub : public Hub { 166 public: 167 EHCIRootHub(Object *rootObject, 168 int8 deviceAddress); 169 170 static status_t ProcessTransfer(EHCI *ehci, 171 Transfer *transfer); 172 }; 173 174 175 #endif // !EHCI_H 176