2 * Copyright 2004-2006, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Michael Lotz <mmlr@mlotz.ch>
12 #define USB_MODULE_NAME "uhci roothub"
14 static usb_device_descriptor sUHCIRootHubDevice
=
16 18, // Descriptor length
17 USB_DESCRIPTOR_DEVICE
, // Descriptor type
19 0x09, // Class (9 = Hub)
22 64, // Max packet size on endpoint 0
26 1, // Index of manufacturer string
27 2, // Index of product string
28 0, // Index of serial number string
29 1 // Number of configurations
33 struct uhci_root_hub_configuration_s
{
34 usb_configuration_descriptor configuration
;
35 usb_interface_descriptor interface
;
36 usb_endpoint_descriptor endpoint
;
37 usb_hub_descriptor hub
;
41 static uhci_root_hub_configuration_s sUHCIRootHubConfig
=
43 { // configuration descriptor
44 9, // Descriptor length
45 USB_DESCRIPTOR_CONFIGURATION
, // Descriptor type
46 34, // Total length of configuration (including
47 // interface, endpoint and hub descriptors)
48 1, // Number of interfaces
49 1, // Value of this configuration
50 0, // Index of configuration string
51 0x40, // Attributes (0x40 = self powered)
52 0 // Max power (0, since self powered)
55 { // interface descriptor
56 9, // Descriptor length
57 USB_DESCRIPTOR_INTERFACE
, // Descriptor type
58 0, // Interface number
59 0, // Alternate setting
60 1, // Number of endpoints
61 0x09, // Interface class (9 = Hub)
62 0, // Interface subclass
63 0, // Interface protocol
64 0 // Index of interface string
67 { // endpoint descriptor
68 7, // Descriptor length
69 USB_DESCRIPTOR_ENDPOINT
, // Descriptor type
70 USB_REQTYPE_DEVICE_IN
| 1, // Endpoint address (first in IN endpoint)
71 0x03, // Attributes (0x03 = interrupt endpoint)
77 9, // Descriptor length (including
78 // deprecated power control mask)
79 USB_DESCRIPTOR_HUB
, // Descriptor type
81 0x0000, // Hub characteristics
82 0, // Power on to power good (in 2ms units)
83 0, // Maximum current (in mA)
84 0x00, // Both ports are removable
85 0xff // Depricated power control mask
90 struct uhci_root_hub_string_s
{
92 uint8 descriptor_type
;
93 uint16 unicode_string
[12];
97 static uhci_root_hub_string_s sUHCIRootHubStrings
[3] = {
99 4, // Descriptor length
100 USB_DESCRIPTOR_STRING
, // Descriptor type
102 0x0409 // Supported language IDs (English US)
107 22, // Descriptor length
108 USB_DESCRIPTOR_STRING
, // Descriptor type
110 'H', 'A', 'I', 'K', 'U', // Characters
111 ' ', 'I', 'n', 'c', '.'
116 26, // Descriptor length
117 USB_DESCRIPTOR_STRING
, // Descriptor type
119 'U', 'H', 'C', 'I', ' ', // Characters
120 'R', 'o', 'o', 't', 'H',
127 UHCIRootHub::UHCIRootHub(Object
*rootObject
, int8 deviceAddress
)
128 : Hub(rootObject
, 0, rootObject
->GetStack()->IndexOfBusManager(rootObject
->GetBusManager()),
129 sUHCIRootHubDevice
, deviceAddress
, USB_SPEED_FULLSPEED
, true)
135 UHCIRootHub::ProcessTransfer(UHCI
*uhci
, Transfer
*transfer
)
137 if ((transfer
->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE
) == 0)
140 usb_request_data
*request
= transfer
->RequestData();
141 TRACE_MODULE("request: %d\n", request
->Request
);
143 status_t status
= B_TIMED_OUT
;
144 size_t actualLength
= 0;
145 switch (request
->Request
) {
146 case USB_REQUEST_GET_STATUS
: {
147 if (request
->Index
== 0) {
149 actualLength
= MIN(sizeof(usb_port_status
),
150 transfer
->DataLength());
151 // the hub reports whether the local power failed (bit 0)
152 // and if there is a over-current condition (bit 1).
153 // everything as 0 means all is ok.
154 memset(transfer
->Data(), 0, actualLength
);
159 usb_port_status portStatus
;
160 if (uhci
->GetPortStatus(request
->Index
- 1, &portStatus
) >= B_OK
) {
161 actualLength
= MIN(sizeof(usb_port_status
), transfer
->DataLength());
162 memcpy(transfer
->Data(), (void *)&portStatus
, actualLength
);
169 case USB_REQUEST_SET_ADDRESS
:
170 if (request
->Value
>= 128) {
171 status
= B_TIMED_OUT
;
175 TRACE_MODULE("set address: %d\n", request
->Value
);
179 case USB_REQUEST_GET_DESCRIPTOR
:
180 TRACE_MODULE("get descriptor: %d\n", request
->Value
>> 8);
182 switch (request
->Value
>> 8) {
183 case USB_DESCRIPTOR_DEVICE
: {
184 actualLength
= MIN(sizeof(usb_device_descriptor
),
185 transfer
->DataLength());
186 memcpy(transfer
->Data(), (void *)&sUHCIRootHubDevice
,
192 case USB_DESCRIPTOR_CONFIGURATION
: {
193 actualLength
= MIN(sizeof(uhci_root_hub_configuration_s
),
194 transfer
->DataLength());
195 memcpy(transfer
->Data(), (void *)&sUHCIRootHubConfig
,
201 case USB_DESCRIPTOR_STRING
: {
202 uint8 index
= request
->Value
& 0x00ff;
206 actualLength
= MIN(sUHCIRootHubStrings
[index
].length
,
207 transfer
->DataLength());
208 memcpy(transfer
->Data(), (void *)&sUHCIRootHubStrings
[index
],
214 case USB_DESCRIPTOR_HUB
: {
215 actualLength
= MIN(sizeof(usb_hub_descriptor
),
216 transfer
->DataLength());
217 memcpy(transfer
->Data(), (void *)&sUHCIRootHubConfig
.hub
,
225 case USB_REQUEST_SET_CONFIGURATION
:
229 case USB_REQUEST_CLEAR_FEATURE
: {
230 if (request
->Index
== 0) {
231 // we don't support any hub changes
232 TRACE_MODULE_ERROR("clear feature: no hub changes\n");
236 TRACE_MODULE("clear feature: %d\n", request
->Value
);
237 if (uhci
->ClearPortFeature(request
->Index
- 1, request
->Value
) >= B_OK
)
242 case USB_REQUEST_SET_FEATURE
: {
243 if (request
->Index
== 0) {
244 // we don't support any hub changes
245 TRACE_MODULE_ERROR("set feature: no hub changes\n");
249 TRACE_MODULE("set feature: %d\n", request
->Value
);
250 if (uhci
->SetPortFeature(request
->Index
- 1, request
->Value
) >= B_OK
)
256 transfer
->Finished(status
, actualLength
);