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