2 * Copyright 2011, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
7 * Jian Chiang <j.jian.chiang@gmail.com>
13 #define USB_MODULE_NAME "xhci roothub"
15 static usb_device_descriptor sXHCIRootHubDevice
=
17 18, // Descriptor length
18 USB_DESCRIPTOR_DEVICE
, // Descriptor type
20 0x09, // Class (9 = Hub)
23 9, // Max packet size on endpoint 0
27 1, // Index of manufacturer string
28 2, // Index of product string
29 0, // Index of serial number string
30 1 // Number of configurations
34 struct usb_endpoint_ss_comp_descriptor
{
36 uint8 descriptor_type
;
43 struct xhci_root_hub_configuration_s
{
44 usb_configuration_descriptor configuration
;
45 usb_interface_descriptor interface
;
46 usb_endpoint_descriptor endpoint
;
47 usb_endpoint_ss_comp_descriptor endpc
;
48 usb_hub_descriptor hub
;
52 static xhci_root_hub_configuration_s sXHCIRootHubConfig
=
54 { // configuration descriptor
55 9, // Descriptor length
56 USB_DESCRIPTOR_CONFIGURATION
, // Descriptor type
57 sizeof(sXHCIRootHubConfig
), // Total length of configuration (including
58 // interface, endpoint and hub descriptors)
59 1, // Number of interfaces
60 1, // Value of this configuration
61 0, // Index of configuration string
62 0x40, // Attributes (0x40 = self powered)
63 0 // Max power (0, since self powered)
66 { // interface descriptor
67 9, // Descriptor length
68 USB_DESCRIPTOR_INTERFACE
, // Descriptor type
69 0, // Interface number
70 0, // Alternate setting
71 1, // Number of endpoints
72 0x09, // Interface class (9 = Hub)
73 0, // Interface subclass
74 0, // Interface protocol
75 0 // Index of interface string
78 { // endpoint descriptor
79 7, // Descriptor length
80 USB_DESCRIPTOR_ENDPOINT
, // Descriptor type
81 USB_REQTYPE_DEVICE_IN
| 1, // Endpoint address (first in IN endpoint)
82 0x03, // Attributes (0x03 = interrupt endpoint)
87 { // endpoint companion descriptor
96 9, // Descriptor length (including
97 // deprecated power control mask)
98 USB_DESCRIPTOR_HUB
, // Descriptor type
99 0x0f, // Number of ports
100 0x0000, // Hub characteristics
101 10, // Power on to power good (in 2ms units)
102 0, // Maximum current (in mA)
103 0x00, // All ports are removable
104 0xff // Deprecated power control mask
109 struct xhci_root_hub_string_s
{
111 uint8 descriptor_type
;
112 uint16 unicode_string
[12];
116 static xhci_root_hub_string_s sXHCIRootHubStrings
[3] = {
118 4, // Descriptor length
119 USB_DESCRIPTOR_STRING
, // Descriptor type
121 0x0409 // Supported language IDs (English US)
126 22, // Descriptor length
127 USB_DESCRIPTOR_STRING
, // Descriptor type
129 'H', 'A', 'I', 'K', 'U', // Characters
130 ' ', 'I', 'n', 'c', '.'
135 26, // Descriptor length
136 USB_DESCRIPTOR_STRING
, // Descriptor type
138 'X', 'H', 'C', 'I', ' ', // Characters
139 'R', 'o', 'o', 't', 'H',
146 XHCIRootHub::XHCIRootHub(Object
*rootObject
, int8 deviceAddress
)
147 : Hub(rootObject
, 0, rootObject
->GetStack()->IndexOfBusManager(rootObject
->GetBusManager()),
148 sXHCIRootHubDevice
, deviceAddress
, USB_SPEED_SUPER
, true)
154 XHCIRootHub::ProcessTransfer(XHCI
*xhci
, Transfer
*transfer
)
156 if ((transfer
->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE
) == 0)
159 usb_request_data
*request
= transfer
->RequestData();
160 TRACE_MODULE("request: %d\n", request
->Request
);
162 status_t status
= B_TIMED_OUT
;
163 size_t actualLength
= 0;
164 switch (request
->Request
) {
165 case USB_REQUEST_GET_STATUS
: {
166 if (request
->Index
== 0) {
168 actualLength
= MIN(sizeof(usb_port_status
),
169 transfer
->DataLength());
170 // the hub reports whether the local power failed (bit 0)
171 // and if there is a over-current condition (bit 1).
172 // everything as 0 means all is ok.
173 memset(transfer
->Data(), 0, actualLength
);
178 usb_port_status portStatus
;
179 if (xhci
->GetPortStatus(request
->Index
- 1, &portStatus
) >= B_OK
) {
180 actualLength
= MIN(sizeof(usb_port_status
), transfer
->DataLength());
181 memcpy(transfer
->Data(), (void *)&portStatus
, actualLength
);
188 case USB_REQUEST_SET_ADDRESS
:
189 if (request
->Value
>= 128) {
190 status
= B_TIMED_OUT
;
194 TRACE_MODULE("set address: %d\n", request
->Value
);
198 case USB_REQUEST_GET_DESCRIPTOR
:
199 TRACE_MODULE("get descriptor: %d\n", request
->Value
>> 8);
201 switch (request
->Value
>> 8) {
202 case USB_DESCRIPTOR_DEVICE
: {
203 actualLength
= MIN(sizeof(usb_device_descriptor
),
204 transfer
->DataLength());
205 memcpy(transfer
->Data(), (void *)&sXHCIRootHubDevice
,
211 case USB_DESCRIPTOR_CONFIGURATION
: {
212 actualLength
= MIN(sizeof(xhci_root_hub_configuration_s
),
213 transfer
->DataLength());
214 sXHCIRootHubConfig
.hub
.num_ports
= xhci
->PortCount();
215 memcpy(transfer
->Data(), (void *)&sXHCIRootHubConfig
,
221 case USB_DESCRIPTOR_STRING
: {
222 uint8 index
= request
->Value
& 0x00ff;
226 actualLength
= MIN(sXHCIRootHubStrings
[index
].length
,
227 transfer
->DataLength());
228 memcpy(transfer
->Data(), (void *)&sXHCIRootHubStrings
[index
],
234 case USB_DESCRIPTOR_HUB
: {
235 actualLength
= MIN(sizeof(usb_hub_descriptor
),
236 transfer
->DataLength());
237 sXHCIRootHubConfig
.hub
.num_ports
= xhci
->PortCount();
238 memcpy(transfer
->Data(), (void *)&sXHCIRootHubConfig
.hub
,
246 case USB_REQUEST_SET_CONFIGURATION
:
250 case USB_REQUEST_CLEAR_FEATURE
: {
251 if (request
->Index
== 0) {
252 // we don't support any hub changes
253 TRACE_MODULE_ERROR("clear feature: no hub changes\n");
257 TRACE_MODULE("clear feature: %d\n", request
->Value
);
258 if (xhci
->ClearPortFeature(request
->Index
- 1, request
->Value
) >= B_OK
)
263 case USB_REQUEST_SET_FEATURE
: {
264 if (request
->Index
== 0) {
265 // we don't support any hub changes
266 TRACE_MODULE_ERROR("set feature: no hub changes\n");
270 TRACE_MODULE("set feature: %d\n", request
->Value
);
271 if (xhci
->SetPortFeature(request
->Index
- 1, request
->Value
) >= B_OK
)
277 transfer
->Finished(status
, actualLength
);