90 explicit operator bool()
const {
94 m_Outcome = UsbStartup::Outcome::Failed;
97 m_Outcome = UsbStartup::Outcome::DeviceReady;
105 UsbStartup::Outcome m_Outcome = UsbStartup::Outcome::Neutral;
123 explicit operator bool()
const {
124 return m_Hub !=
nullptr;
153 virtual bool controllerAssignsAddresses()
const {
156 virtual bool supportsHubDevices()
const {
159 virtual bool prepareDevice(uint8_t,
const UsbEndpoint&) {
162 virtual bool addressDevice(uint8_t,
const UsbEndpoint&) {
169 virtual Type getType();
173 uintptr_t pBuffer,
size_t nBytes) = 0;
188 void (*pCallback)(uintptr_t, ssize_t) = 0,
189 uintptr_t pParam = 0) = 0;
201 uintptr_t pParam) = 0;
206 void (*pCallback)(uintptr_t, ssize_t),
208 uintptr_t pParam = 0) = 0;
211 bool deviceConnected(uint8_t nPort, UsbSpeed speed);
214 void deviceDisconnected(uint8_t nPort);
218 ssize_t doSync(uintptr_t nTransaction, uint32_t timeout = 5000);
220#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
222 static bool runHostedSyncOwnershipRegression();
225 static bool runHostedInterruptOwnershipRegression();
227 using ConnectionChangePendingHook = void (*)(
UsbHub* hub,
size_t port,
size_t observedState);
228 using ConnectionChangeReplayWaitHook = void (*)(
UsbHub* hub,
size_t port);
229 static void setConnectionChangePendingHookForTest(ConnectionChangePendingHook hook);
230 static void setConnectionChangeReplayWaitHookForTest(ConnectionChangeReplayWaitHook hook);
233#if PEDIGREE_CONCURRENCY_SMOKE_TESTS
235 static bool runQemuInterruptOwnershipRegression();
249 virtual bool portReset(uint8_t nPort,
bool bErrorResponse =
false) = 0;
252 bool deviceConnectedAdmitted(uint8_t nPort, UsbSpeed speed);
253#if (HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS) || PEDIGREE_CONCURRENCY_SMOKE_TESTS
254 static bool runInterruptOwnershipRegression();
255 static int retireProbeSubtreeForTest(
void* parameter);
260 inline SyncParam() : semaphore(0), nResult(-1), owners(2) {}
271 static void syncCallback(uintptr_t pParam, ssize_t ret);
273 void deviceDisconnectedLocked(uint8_t nPort);
274 void retirePortContainersLocked(uint8_t nPort,
bool* retiredAddresses,
275 bool* pinnedSubtreeAddresses =
nullptr);
276 void releaseRetiredAddressesLocked(uint8_t nPort,
const bool* retiredAddresses);
277 void retainAddressLocked(
size_t address);
278 void releaseAddressLocked(
size_t address);
279 void retainAddressesLocked(
const bool* addresses);
280 void releaseAddressesLocked(
const bool* addresses);
281 static void collectUsbAddresses(
Device* device,
bool* addresses);
285 void releaseConnectionChangeSuppression(
size_t port);
292 size_t m_AddressReferences[128] = {};
300 static constexpr size_t ConnectionChangePortCount = 32;
301 static constexpr size_t ConnectionChangePending =
302 static_cast<size_t>(1) << ((
sizeof(
size_t) * 8) -
static_cast<size_t>(1));
303 static constexpr size_t ConnectionChangeCountMask = ~ConnectionChangePending;
321 bool m_RetainDisconnectedAddresses =
false;
329 virtual bool beginStartupActivity() {
332 virtual void endStartupActivity(UsbStartup::Outcome) {}
341 void (*callback)(uintptr_t, ssize_t),
342 uintptr_t parameter);
346 void (*callback)(uintptr_t, ssize_t),
348 bool producerAlreadyStopped) = 0;
356 void disconnectAllDevices();
359 void retainDisconnectedAddressesUntilControllerTeardown();
362 void attachToUpstreamHub(
UsbHub* upstream,
const RootConnection& connection);
371 ConnectionChangeSuppression& suppression);
380 virtual void replaySuppressedConnectionChange(
size_t port);
virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer, size_t nBytes)=0
Adds a new transfer to an existent transaction.
virtual MUST_USE_RESULT bool addInterruptInHandler(UsbEndpoint endpointInfo, uintptr_t pBuffer, uint16_t nBytes, void(*pCallback)(uintptr_t, ssize_t), UsbInterruptInHandle &handle, uintptr_t pParam=0)=0
Adds an owned recurring interrupt-IN transaction.