2 * Copyright 2006, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
11 #define USB_MODULE_NAME "ehci roothub"
13 static usb_device_descriptor sEHCIRootHubDevice
=
15 18, // Descriptor length
16 USB_DESCRIPTOR_DEVICE
, // Descriptor type
18 0x09, // Class (9 = Hub)
21 64, // Max packet size on endpoint 0
25 1, // Index of manufacturer string
26 2, // Index of product string
27 0, // Index of serial number string
28 1 // Number of configurations
32 struct ehci_root_hub_configuration_s
{
33 usb_configuration_descriptor configuration
;
34 usb_interface_descriptor interface
;
35 usb_endpoint_descriptor endpoint
;
36 usb_hub_descriptor hub
;
40 static ehci_root_hub_configuration_s sEHCIRootHubConfig
=
42 { // configuration descriptor
43 9, // Descriptor length
44 USB_DESCRIPTOR_CONFIGURATION
, // Descriptor type
45 34, // Total length of configuration (including
46 // interface, endpoint and hub descriptors)
47 1, // Number of interfaces
48 1, // Value of this configuration
49 0, // Index of configuration string
50 0x40, // Attributes (0x40 = self powered)
51 0 // Max power (0, since self powered)
54 { // interface descriptor
55 9, // Descriptor length
56 USB_DESCRIPTOR_INTERFACE
, // Descriptor type
57 0, // Interface number
58 0, // Alternate setting
59 1, // Number of endpoints
60 0x09, // Interface class (9 = Hub)
61 0, // Interface subclass
62 0, // Interface protocol
63 0 // Index of interface string
66 { // endpoint descriptor
67 7, // Descriptor length
68 USB_DESCRIPTOR_ENDPOINT
, // Descriptor type
69 USB_REQTYPE_DEVICE_IN
| 1, // Endpoint address (first in IN endpoint)
70 0x03, // Attributes (0x03 = interrupt endpoint)
76 9, // Descriptor length (including
77 // deprecated power control mask)
78 USB_DESCRIPTOR_HUB
, // Descriptor type
79 0x0f, // Number of ports
80 0x0000, // Hub characteristics
81 0, // Power on to power good (in 2ms units)
82 0, // Maximum current (in mA)
83 0x00, // All ports are removable
84 0xff // Depricated power control mask
89 struct ehci_root_hub_string_s
{
91 uint8 descriptor_type
;
92 uint16 unicode_string
[12];
96 static ehci_root_hub_string_s sEHCIRootHubStrings
[3] = {
98 4, // Descriptor length
99 USB_DESCRIPTOR_STRING
, // Descriptor type
101 0x0409 // Supported language IDs (English US)
106 22, // Descriptor length
107 USB_DESCRIPTOR_STRING
, // Descriptor type
109 'H', 'A', 'I', 'K', 'U', // Characters
110 ' ', 'I', 'n', 'c', '.'
115 26, // Descriptor length
116 USB_DESCRIPTOR_STRING
, // Descriptor type
118 'E', 'H', 'C', 'I', ' ', // Characters
119 'R', 'o', 'o', 't', 'H',
126 EHCIRootHub::EHCIRootHub(Object
*rootObject
, int8 deviceAddress
)
127 : Hub(rootObject
, 0, rootObject
->GetStack()->IndexOfBusManager(rootObject
->GetBusManager()),
128 sEHCIRootHubDevice
, deviceAddress
, USB_SPEED_HIGHSPEED
, true)
134 EHCIRootHub::ProcessTransfer(EHCI
*ehci
, Transfer
*transfer
)
136 if ((transfer
->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE
) == 0)
139 usb_request_data
*request
= transfer
->RequestData();
140 TRACE_MODULE("request: %d\n", request
->Request
);
142 status_t status
= B_TIMED_OUT
;
143 size_t actualLength
= 0;
144 switch (request
->Request
) {
145 case USB_REQUEST_GET_STATUS
: {
146 if (request
->Index
== 0) {
148 actualLength
= MIN(sizeof(usb_port_status
),
149 transfer
->DataLength());
150 // the hub reports whether the local power failed (bit 0)
151 // and if there is a over-current condition (bit 1).
152 // everything as 0 means all is ok.
153 memset(transfer
->Data(), 0, actualLength
);
158 usb_port_status portStatus
;
159 if (ehci
->GetPortStatus(request
->Index
- 1, &portStatus
) >= B_OK
) {
160 actualLength
= MIN(sizeof(usb_port_status
), transfer
->DataLength());
161 memcpy(transfer
->Data(), (void *)&portStatus
, actualLength
);
168 case USB_REQUEST_SET_ADDRESS
:
169 if (request
->Value
>= 128) {
170 status
= B_TIMED_OUT
;
174 TRACE_MODULE("set address: %d\n", request
->Value
);
178 case USB_REQUEST_GET_DESCRIPTOR
:
179 TRACE_MODULE("get descriptor: %d\n", request
->Value
>> 8);
181 switch (request
->Value
>> 8) {
182 case USB_DESCRIPTOR_DEVICE
: {
183 actualLength
= MIN(sizeof(usb_device_descriptor
),
184 transfer
->DataLength());
185 memcpy(transfer
->Data(), (void *)&sEHCIRootHubDevice
,
191 case USB_DESCRIPTOR_CONFIGURATION
: {
192 actualLength
= MIN(sizeof(ehci_root_hub_configuration_s
),
193 transfer
->DataLength());
194 sEHCIRootHubConfig
.hub
.num_ports
= ehci
->PortCount();
195 memcpy(transfer
->Data(), (void *)&sEHCIRootHubConfig
,
201 case USB_DESCRIPTOR_STRING
: {
202 uint8 index
= request
->Value
& 0x00ff;
206 actualLength
= MIN(sEHCIRootHubStrings
[index
].length
,
207 transfer
->DataLength());
208 memcpy(transfer
->Data(), (void *)&sEHCIRootHubStrings
[index
],
214 case USB_DESCRIPTOR_HUB
: {
215 actualLength
= MIN(sizeof(usb_hub_descriptor
),
216 transfer
->DataLength());
217 sEHCIRootHubConfig
.hub
.num_ports
= ehci
->PortCount();
218 memcpy(transfer
->Data(), (void *)&sEHCIRootHubConfig
.hub
,
226 case USB_REQUEST_SET_CONFIGURATION
:
230 case USB_REQUEST_CLEAR_FEATURE
: {
231 if (request
->Index
== 0) {
232 // we don't support any hub changes
233 TRACE_MODULE_ERROR("clear feature: no hub changes\n");
237 TRACE_MODULE("clear feature: %d\n", request
->Value
);
238 if (ehci
->ClearPortFeature(request
->Index
- 1, request
->Value
) >= B_OK
)
243 case USB_REQUEST_SET_FEATURE
: {
244 if (request
->Index
== 0) {
245 // we don't support any hub changes
246 TRACE_MODULE_ERROR("set feature: no hub changes\n");
250 TRACE_MODULE("set feature: %d\n", request
->Value
);
251 if (ehci
->SetPortFeature(request
->Index
- 1, request
->Value
) >= B_OK
)
257 transfer
->Finished(status
, actualLength
);