The Pedigree Project 0.1
UsbHubDevice.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef USBHUBDEVICE_H
21#define USBHUBDEVICE_H
22
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/processor/types.h"
25#include "pedigree/kernel/utilities/String.h"
26
27#include "modules/drivers/common/usb-hcd/PortChangeRequest.h"
28#include "modules/system/usb/Usb.h"
29#include "modules/system/usb/UsbConstants.h"
30#include "modules/system/usb/UsbDevice.h"
31#include "modules/system/usb/UsbHub.h"
32
33class UsbHubDevice : public UsbDevice, public UsbHub, private RequestQueue {
34 public:
36 virtual ~UsbHubDevice();
37
38 virtual void initialiseDriver();
39
40 virtual void getName(String& str) {
41 str.assign("USB Hub Device", 15);
42 }
43
44 bool hasSubtree() const override {
45 return true;
46 }
47
48 Device* getDevice() override {
49 return this;
50 }
51
52 void prepareForDriverRetirement() override;
53 void quiesceForRetirement() override;
54 void prepareForDisconnection() override;
55
56 virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid,
57 uintptr_t pBuffer, size_t nBytes);
58 virtual uintptr_t createTransaction(UsbEndpoint endpointInfo);
59 MUST_USE_RESULT virtual bool doAsync(uintptr_t pTransaction,
60 void (*pCallback)(uintptr_t, ssize_t) = 0,
61 uintptr_t pParam = 0);
62 MUST_USE_RESULT virtual bool addInterruptInHandler(UsbEndpoint endpointInfo, uintptr_t pBuffer,
63 uint16_t nBytes,
64 void (*pCallback)(uintptr_t, ssize_t),
66 uintptr_t pParam = 0);
67
68 virtual bool portReset(uint8_t nPort, bool bErrorResponse = false);
69
70 protected:
71 virtual void cancelAsyncAndDrain(uintptr_t pTransaction, void (*pCallback)(uintptr_t, ssize_t),
72 uintptr_t pParam);
74 void (*callback)(uintptr_t, ssize_t),
75 uintptr_t parameter,
76 bool producerAlreadyStopped) override;
77 uint64_t executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5,
78 uint64_t p6, uint64_t p7, uint64_t p8) override;
79 void cancelRequest(const Request& request) override;
80 bool portSpeed(uint8_t port, UsbSpeed& speed) override;
81
82 private:
83 enum HubFeatureSelectors {
84 HubLocalPower = 0,
85 HubOverCurrent = 1,
86 };
87
88 enum PortFeatureSelectors {
89 PortConnection = 0,
90 PortEnable = 1,
91 PortSuspend = 2,
92 PortOverCurrent = 3,
93 PortReset = 4,
94 PortPower = 8,
95 PortLowSpeed = 9,
96 CPortConnection = 16,
97 CPortEnable = 17,
98 CPortSuspend = 18,
99 CPortOverCurrent = 19,
100 CPortReset = 20,
101 PortTest = 21,
102 PortIndicator = 22,
103 };
104
105 enum HubRequests {
106 HubRequest = static_cast<uint8_t>(UsbRequestType::Class),
107 HubPortRequest = static_cast<uint8_t>(static_cast<uint8_t>(UsbRequestType::Class) |
108 static_cast<uint8_t>(UsbRequestRecipient::Other))
109 };
110
111 bool setPortFeature(size_t port, PortFeatureSelectors feature);
112 bool clearPortFeature(size_t port, PortFeatureSelectors feature);
113
115 bool getPortStatus(size_t port, uint32_t& status);
116 bool clearPortChanges(size_t port, uint32_t status);
117 bool debouncePort(size_t port, uint32_t& status);
118 bool connectPort(size_t port);
119 void portChanged(size_t port);
120 void stopHotplug();
121 static void statusChanged(uintptr_t parameter, ssize_t result);
122
124 inline HubDescriptor(void* pBuffer)
125 : pDescriptor(static_cast<Descriptor*>(pBuffer)),
126 nPorts(pDescriptor->nPorts),
127 hubCharacteristics(pDescriptor->hubCharacteristics),
128 powerGoodDelay(pDescriptor->powerGoodDelay) {}
129
131 delete[] reinterpret_cast<uint8_t*>(pDescriptor);
132 }
133
134 struct Descriptor {
135 uint8_t nLength;
136 uint8_t nType;
137 uint8_t nPorts;
138 uint16_t hubCharacteristics;
139 uint8_t powerGoodDelay;
140 uint8_t controllerCurrent;
141 } PACKED* pDescriptor;
142
143 uint8_t nPorts;
144 uint16_t hubCharacteristics;
145 uint8_t powerGoodDelay;
146 };
147
148 size_t m_nPorts;
149 size_t m_PowerGoodDelay;
150 uint8_t* m_StatusBuffer;
151 size_t m_StatusBytes;
152 UsbInterruptInHandle m_StatusInterrupt;
153 UsbHcd::PortChangeRequest m_StatusChange;
154};
155
156#endif
bool portSpeed(uint8_t port, UsbSpeed &speed) override
void prepareForDisconnection() override
bool getPortStatus(size_t port, uint32_t &status)
Top 16 bits of status hold the port-change flags.
Device * getDevice() override
virtual void cancelAsyncAndDrain(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t), uintptr_t pParam)
MUST_USE_RESULT bool cancelInterruptInAndDrain(const UsbInterruptInToken &token, void(*callback)(uintptr_t, ssize_t), uintptr_t parameter, bool producerAlreadyStopped) override
void quiesceForRetirement() override
virtual void getName(String &str)
void prepareForDriverRetirement() override
virtual MUST_USE_RESULT bool doAsync(uintptr_t pTransaction, void(*pCallback)(uintptr_t, ssize_t)=0, uintptr_t pParam=0)
virtual bool portReset(uint8_t nPort, bool bErrorResponse=false)
Gets a UsbDevice from a given vendor:product pair.
bool hasSubtree() const override
Do we expose our own Device tree?
virtual void addTransferToTransaction(uintptr_t pTransaction, bool bToggle, UsbPid pid, uintptr_t pBuffer, size_t nBytes)
Adds a new transfer to an existent transaction.
void cancelRequest(const Request &request) override
virtual void initialiseDriver()
Implemented by the driver class, initialises driver-specific stuff.
uint64_t executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8) override
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)
Adds an owned recurring interrupt-IN transaction.
virtual uintptr_t createTransaction(UsbEndpoint endpointInfo)
Creates a new transaction with the given endpoint data.