1 /* 2 * Copyright 2004-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 * Niels S. Reedijk 8 */ 9 10 #ifndef UHCI_H 11 #define UHCI_H 12 13 #include "usb_p.h" 14 #include "uhci_hardware.h" 15 #include <lock.h> 16 17 #define UHCI_INTERRUPT_QUEUE 0 18 #define UHCI_LOW_SPEED_CONTROL_QUEUE 1 19 #define UHCI_FULL_SPEED_CONTROL_QUEUE 2 20 #define UHCI_BULK_QUEUE 3 21 #define UHCI_BANDWIDTH_RECLAMATION_QUEUE 4 22 23 struct pci_info; 24 struct pci_module_info; 25 class UHCIRootHub; 26 27 28 class Queue { 29 public: 30 Queue(Stack *stack); 31 ~Queue(); 32 33 bool Lock(); 34 void Unlock(); 35 36 status_t InitCheck(); 37 38 status_t LinkTo(Queue *other); 39 status_t TerminateByStrayDescriptor(); 40 41 status_t AppendTransfer(uhci_qh *transfer); 42 status_t RemoveTransfer(uhci_qh *transfer); 43 44 addr_t PhysicalAddress(); 45 46 void PrintToStream(); 47 48 private: 49 status_t fStatus; 50 Stack *fStack; 51 uhci_qh *fQueueHead; 52 uhci_td *fStrayDescriptor; 53 uhci_qh *fQueueTop; 54 benaphore fLock; 55 }; 56 57 58 typedef struct transfer_data_s { 59 Transfer *transfer; 60 Queue *queue; 61 uhci_qh *transfer_queue; 62 uhci_td *first_descriptor; 63 uhci_td *data_descriptor; 64 area_id user_area; 65 bool incoming; 66 transfer_data_s *link; 67 } transfer_data; 68 69 70 class UHCI : public BusManager { 71 public: 72 UHCI(pci_info *info, Stack *stack); 73 ~UHCI(); 74 75 status_t Start(); 76 virtual status_t SubmitTransfer(Transfer *transfer); 77 virtual status_t CancelQueuedTransfers(Pipe *pipe); 78 status_t SubmitRequest(Transfer *transfer); 79 status_t SubmitIsochronous(Transfer *transfer); 80 81 static status_t AddTo(Stack *stack); 82 83 // Port operations 84 status_t GetPortStatus(uint8 index, usb_port_status *status); 85 status_t SetPortFeature(uint8 index, uint16 feature); 86 status_t ClearPortFeature(uint8 index, uint16 feature); 87 88 status_t ResetPort(uint8 index); 89 90 private: 91 // Controller resets 92 void GlobalReset(); 93 status_t ControllerReset(); 94 95 // Interrupt functions 96 static int32 InterruptHandler(void *data); 97 int32 Interrupt(); 98 99 // Transfer functions 100 status_t AddPendingTransfer(Transfer *transfer, 101 Queue *queue, 102 uhci_qh *transferQueue, 103 uhci_td *firstDescriptor, 104 uhci_td *dataDescriptor, 105 bool directionIn); 106 static int32 FinishThread(void *data); 107 void FinishTransfers(); 108 109 status_t CreateFilledTransfer(Transfer *transfer, 110 uhci_td **_firstDescriptor, 111 uhci_qh **_transferQueue); 112 113 // Transfer queue functions 114 uhci_qh *CreateTransferQueue(uhci_td *descriptor); 115 void FreeTransferQueue(uhci_qh *queueHead); 116 117 // Descriptor functions 118 uhci_td *CreateDescriptor(Pipe *pipe, 119 uint8 direction, 120 size_t bufferSizeToAllocate); 121 status_t CreateDescriptorChain(Pipe *pipe, 122 uhci_td **firstDescriptor, 123 uhci_td **lastDescriptor, 124 uint8 direction, 125 size_t bufferSizeToAllocate); 126 127 void FreeDescriptor(uhci_td *descriptor); 128 void FreeDescriptorChain(uhci_td *topDescriptor); 129 130 void LinkDescriptors(uhci_td *first, 131 uhci_td *second); 132 133 size_t WriteDescriptorChain(uhci_td *topDescriptor, 134 iovec *vector, size_t vectorCount); 135 size_t ReadDescriptorChain(uhci_td *topDescriptor, 136 iovec *vector, size_t vectorCount, 137 uint8 *lastDataToggle); 138 size_t ReadActualLength(uhci_td *topDescriptor, 139 uint8 *lastDataToggle); 140 141 // Register functions 142 inline void WriteReg8(uint32 reg, uint8 value); 143 inline void WriteReg16(uint32 reg, uint16 value); 144 inline void WriteReg32(uint32 reg, uint32 value); 145 inline uint8 ReadReg8(uint32 reg); 146 inline uint16 ReadReg16(uint32 reg); 147 inline uint32 ReadReg32(uint32 reg); 148 149 static pci_module_info *sPCIModule; 150 151 uint32 fRegisterBase; 152 pci_info *fPCIInfo; 153 Stack *fStack; 154 155 // Frame list memory 156 area_id fFrameArea; 157 addr_t *fFrameList; 158 159 // fFrameBandwidth[n] holds the available bandwidth 160 // of the nth frame in microseconds 161 int32 *fFrameBandwidth; 162 163 // Queues 164 int32 fQueueCount; 165 Queue **fQueues; 166 167 // Maintain a linked list of transfers 168 transfer_data *fFirstTransfer; 169 transfer_data *fLastTransfer; 170 sem_id fFinishTransfersSem; 171 thread_id fFinishThread; 172 bool fStopFinishThread; 173 174 // Root hub 175 UHCIRootHub *fRootHub; 176 uint8 fRootHubAddress; 177 uint8 fPortResetChange; 178 }; 179 180 181 class UHCIRootHub : public Hub { 182 public: 183 UHCIRootHub(Object *rootObject, 184 int8 deviceAddress); 185 186 static status_t ProcessTransfer(UHCI *uhci, 187 Transfer *transfer); 188 }; 189 190 191 #endif 192