BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / busses / usb / ohci_rh.cpp
blob912c15caef56520075a776709697b34e367b520a
1 /*
2 * Copyright 2005-2008, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Jan-Rixt Van Hoye
7 * Salvatore Benedetto <salvatore.benedetto@gmail.com>
8 * Michael Lotz <mmlr@mlotz.ch>
9 */
11 #include "ohci.h"
13 #define USB_MODULE_NAME "ohci roothub"
15 static usb_device_descriptor sOHCIRootHubDevice =
17 18, // Descriptor length
18 USB_DESCRIPTOR_DEVICE, // Descriptor type
19 0x110, // USB 1.1
20 0x09, // Class (9 = Hub)
21 0, // Subclass
22 0, // Protocol
23 64, // Max packet size on endpoint 0
24 0, // Vendor ID
25 0, // Product ID
26 0x110, // Version
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 ohci_root_hub_configuration_s {
35 usb_configuration_descriptor configuration;
36 usb_interface_descriptor interface;
37 usb_endpoint_descriptor endpoint;
38 usb_hub_descriptor hub;
39 } _PACKED;
42 static ohci_root_hub_configuration_s sOHCIRootHubConfig =
44 { // configuration descriptor
45 9, // Descriptor length
46 USB_DESCRIPTOR_CONFIGURATION, // Descriptor type
47 34, // Total length of configuration (including
48 // interface, endpoint and hub descriptors)
49 1, // Number of interfaces
50 1, // Value of this configuration
51 0, // Index of configuration string
52 0x40, // Attributes (0x40 = self powered)
53 0 // Max power (0, since self powered)
56 { // interface descriptor
57 9, // Descriptor length
58 USB_DESCRIPTOR_INTERFACE, // Descriptor type
59 0, // Interface number
60 0, // Alternate setting
61 1, // Number of endpoints
62 0x09, // Interface class (9 = Hub)
63 0, // Interface subclass
64 0, // Interface protocol
65 0 // Index of interface string
68 { // endpoint descriptor
69 7, // Descriptor length
70 USB_DESCRIPTOR_ENDPOINT, // Descriptor type
71 USB_REQTYPE_DEVICE_IN | 1, // Endpoint address (first in IN endpoint)
72 0x03, // Attributes (0x03 = interrupt endpoint)
73 8, // Max packet size
74 0xff // Interval 256
77 { // hub descriptor
78 9, // Descriptor length (including
79 // deprecated power control mask)
80 USB_DESCRIPTOR_HUB, // Descriptor type
81 2, // Number of ports
82 0x0000, // Hub characteristics
83 0, // Power on to power good (in 2ms units)
84 0, // Maximum current (in mA)
85 0x00, // Both ports are removable
86 0xff // Depricated power control mask
91 struct ohci_root_hub_string_s {
92 uint8 length;
93 uint8 descriptor_type;
94 uint16 unicode_string[12];
95 } _PACKED;
98 static ohci_root_hub_string_s sOHCIRootHubStrings[3] = {
100 4, // Descriptor length
101 USB_DESCRIPTOR_STRING, // Descriptor type
103 0x0409 // Supported language IDs (English US)
108 22, // Descriptor length
109 USB_DESCRIPTOR_STRING, // Descriptor type
111 'H', 'A', 'I', 'K', 'U', // Characters
112 ' ', 'I', 'n', 'c', '.'
117 26, // Descriptor length
118 USB_DESCRIPTOR_STRING, // Descriptor type
120 'O', 'H', 'C', 'I', ' ', // Characters
121 'R', 'o', 'o', 't', 'H',
122 'u', 'b'
128 OHCIRootHub::OHCIRootHub(Object *rootObject, int8 deviceAddress)
129 : Hub(rootObject, 0, rootObject->GetStack()->IndexOfBusManager(rootObject->GetBusManager()),
130 sOHCIRootHubDevice, deviceAddress, USB_SPEED_FULLSPEED, true)
135 status_t
136 OHCIRootHub::ProcessTransfer(OHCI *ohci, Transfer *transfer)
138 if ((transfer->TransferPipe()->Type() & USB_OBJECT_CONTROL_PIPE) == 0)
139 return B_ERROR;
141 usb_request_data *request = transfer->RequestData();
142 TRACE_MODULE("request: %d\n", request->Request);
144 status_t status = B_TIMED_OUT;
145 size_t actualLength = 0;
146 switch (request->Request) {
147 case USB_REQUEST_GET_STATUS: {
148 if (request->Index == 0) {
149 // get hub status
150 actualLength = MIN(sizeof(usb_port_status),
151 transfer->DataLength());
152 // the hub reports whether the local power failed (bit 0)
153 // and if there is a over-current condition (bit 1).
154 // everything as 0 means all is ok.
155 memset(transfer->Data(), 0, actualLength);
156 status = B_OK;
157 break;
160 usb_port_status portStatus;
161 if (ohci->GetPortStatus(request->Index - 1, &portStatus) >= B_OK) {
162 actualLength = MIN(sizeof(usb_port_status), transfer->DataLength());
163 memcpy(transfer->Data(), (void *)&portStatus, actualLength);
164 status = B_OK;
167 break;
170 case USB_REQUEST_SET_ADDRESS:
171 if (request->Value >= 128) {
172 status = B_TIMED_OUT;
173 break;
176 TRACE_MODULE("set address: %d\n", request->Value);
177 status = B_OK;
178 break;
180 case USB_REQUEST_GET_DESCRIPTOR:
181 TRACE_MODULE("get descriptor: %d\n", request->Value >> 8);
183 switch (request->Value >> 8) {
184 case USB_DESCRIPTOR_DEVICE: {
185 actualLength = MIN(sizeof(usb_device_descriptor),
186 transfer->DataLength());
187 memcpy(transfer->Data(), (void *)&sOHCIRootHubDevice,
188 actualLength);
189 status = B_OK;
190 break;
193 case USB_DESCRIPTOR_CONFIGURATION: {
194 actualLength = MIN(sizeof(ohci_root_hub_configuration_s),
195 transfer->DataLength());
196 sOHCIRootHubConfig.hub.num_ports = ohci->PortCount();
197 memcpy(transfer->Data(), (void *)&sOHCIRootHubConfig,
198 actualLength);
199 status = B_OK;
200 break;
203 case USB_DESCRIPTOR_STRING: {
204 uint8 index = request->Value & 0x00ff;
205 if (index > 2)
206 break;
208 actualLength = MIN(sOHCIRootHubStrings[index].length,
209 transfer->DataLength());
210 memcpy(transfer->Data(), (void *)&sOHCIRootHubStrings[index],
211 actualLength);
212 status = B_OK;
213 break;
216 case USB_DESCRIPTOR_HUB: {
217 actualLength = MIN(sizeof(usb_hub_descriptor),
218 transfer->DataLength());
219 sOHCIRootHubConfig.hub.num_ports = ohci->PortCount();
220 memcpy(transfer->Data(), (void *)&sOHCIRootHubConfig.hub,
221 actualLength);
222 status = B_OK;
223 break;
226 break;
228 case USB_REQUEST_SET_CONFIGURATION:
229 status = B_OK;
230 break;
232 case USB_REQUEST_CLEAR_FEATURE: {
233 if (request->Index == 0) {
234 // we don't support any hub changes
235 TRACE_MODULE_ERROR("clear feature: no hub changes\n");
236 break;
239 TRACE_MODULE("clear feature: %d\n", request->Value);
240 if (ohci->ClearPortFeature(request->Index - 1, request->Value) >= B_OK)
241 status = B_OK;
242 break;
245 case USB_REQUEST_SET_FEATURE: {
246 if (request->Index == 0) {
247 // we don't support any hub changes
248 TRACE_MODULE_ERROR("set feature: no hub changes\n");
249 break;
252 TRACE_MODULE("set feature: %d\n", request->Value);
253 if (ohci->SetPortFeature(request->Index - 1, request->Value) >= B_OK)
254 status = B_OK;
255 break;
259 transfer->Finished(status, actualLength);
260 delete transfer;
261 return B_OK;